fogón

← Ancient and prehistory3D assetfogon/desert-tower

Torre del zoco

by fogonCC08005 blocks
Torre del zocoDrag to turn it
// «Torre del zoco» · propio
// A square rose-coloured plaster tower with a darker stone foot, narrow dark window slits near the top on every side, a pale stone cornice and a small white dome on top.

// A square rose-coloured plaster tower: a darker stone foot, narrow dark window slits near the top on every side, a
// pale stone cornice and a small white dome.
const rose = ["#a86a4e", "#b97a5c", "#c98a6a", "#d39878", "#dea889"];
const foot = ["#7a5c3c", "#8a6a46", "#987650", "#a6845c"];
const trim = ["#d4bd8c", "#e0cb9c", "#ebd8ad", "#f4e6c4"];
const white = ["#cfc4aa", "#ddd3bb", "#e8dfca", "#f1ead9", "#f9f4e8"];
const wood = ["#4a321f", "#5a3e27", "#6d4c30"];
const dark = "#1a120c";
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const A = 14, B = 33, TOP = 33;
const hash = (a, b, c = 0) => {
  const s = Math.sin(a * 12.9898 + b * 78.233 + c * 37.719) * 43758.5453;
  return s - Math.floor(s);
};
function plasterAt(x, y, z) {
  let tone = 2 + (hash(Math.floor((x + y) / 5), Math.floor(z / 5)) > 0.6 ? 1 : 0) - (hash(Math.floor((x + y) / 4), Math.floor(z / 4), 2) > 0.8 ? 1 : 0);
  if (z > 24) tone++;
  if (z < 10) tone--;
  if (x === A) tone++;
  if (rand() < 0.07) tone--;
  return rose[clampi(tone, 0, 4)];
}
// The shaft (hollow).
for (let x = A; x <= B; x++)
  for (let y = A; y <= B; y++)
    for (let z = 0; z <= TOP; z++) {
      const wall = x <= A + 1 || x >= B - 1 || y <= A + 1 || y >= B - 1;
      if (wall || z === TOP) set(x, y, z, plasterAt(x, y, z));
    }
// The foot: stone blocks, a block wider, sloping in at its top.
for (let x = A - 2; x <= B + 2; x++)
  for (let y = A - 2; y <= B + 2; y++) {
    if (x > A && x < B && y > A && y < B) continue;
    const out = Math.max(A - x, x - B, A - y, y - B);
    for (let z = 0; z <= 6; z++) {
      if (out === 2 && z > 3) continue;
      if (out >= 1 && z > 5) continue;
      const u = x < A || x > B ? y : x;
      const line = z === 3 || (u + (z > 3 ? 3 : 0)) % 7 === 0;
      set(x, y, z, line ? "#644a2e" : foot[clampi(1 + Math.floor(hash(Math.floor((u + (z > 3 ? 3 : 0)) / 7), z > 3 ? 1 : 0) * 3) - (rand() < 0.1 ? 1 : 0), 0, 3)]);
    }
  }
// Window slits near the top, two a side, each with a little arch and a sill.
for (const u of [18, 19, 28, 29]) {
  for (let z = 22; z <= 29; z++) {
    set(u, A, z, dark);
    set(u, B, z, dark);
    set(A, u, z, dark);
    set(B, u, z, dark);
  }
}
for (const u0 of [17, 27]) {
  box(u0, A - 1, 21, u0 + 3, A - 1, 21, trim[2]);
  box(A - 1, u0, 21, A - 1, u0 + 3, 21, trim[3]);
  box(u0, B + 1, 21, u0 + 3, B + 1, 21, trim[1]);
  box(B + 1, u0, 21, B + 1, u0 + 3, 21, trim[1]);
  box(u0, A - 1, 30, u0 + 3, A - 1, 30, trim[1]);
  box(A - 1, u0, 30, A - 1, u0 + 3, 30, trim[2]);
}
// A string course half way up.
for (let x = A - 1; x <= B + 1; x++)
  for (let y = A - 1; y <= B + 1; y++) if (x < A || x > B || y < A || y > B) set(x, y, 16, trim[clampi(1 + (x < A ? 1 : 0), 0, 3)]);
// The cornice: three steps of pale stone, each wider.
for (let k = 0; k < 3; k++)
  for (let x = A - 1 - k; x <= B + 1 + k; x++)
    for (let y = A - 1 - k; y <= B + 1 + k; y++) {
      const edge = x <= A || x >= B || y <= A || y >= B;
      if (edge || k === 2) set(x, y, TOP + 1 + k, (x + y) % 6 === 0 && k < 2 ? "#bfa878" : trim[clampi(k + 1 - (rand() < 0.12 ? 1 : 0), 0, 3)]);
    }
// The dome and its finial.
const C = 23.5, R = 8.2, RZ = 8;
for (let x = 14; x <= 33; x++)
  for (let y = 14; y <= 33; y++)
    for (let z = TOP + 4; z <= TOP + 12; z++) {
      const nx = (x - C) / R, ny = (y - C) / R, nz = (z - TOP - 4) / RZ;
      const d = Math.hypot(nx, ny, nz);
      if (d > 1 || d < 0.74) continue;
      let tone = 2 + (nz > 0.5 ? 1 : 0) + (-nx - ny > 0.5 ? 1 : 0) - (nx + ny > 0.7 ? 1 : 0) - (nz < 0.12 ? 1 : 0);
      set(x, y, z, white[clampi(tone, 0, 4)]);
    }
box(23, 23, TOP + 12, 24, 24, TOP + 13, "#33312f");
// A small arched door at the foot, of dark wood.
for (let x = 20; x <= 27; x++)
  for (let z = 0; z <= 12; z++) {
    const e = z <= 8 ? Math.abs(x - 23.5) - 3 : Math.hypot(x - 23.5, z - 8) - 3;
    if (e <= 0) {
      set(x, A - 2, z, null);
      set(x, A - 1, z, x === 23 || x === 24 ? wood[0] : wood[clampi(1 + (x < 23 ? 1 : 0) - (z % 4 === 0 ? 1 : 0), 0, 2)]);
    } else if (e <= 1.6) for (const y of [A - 2, A - 1]) set(x, y, z, trim[clampi(1 + (y === A - 2 ? 1 : 0), 0, 3)]);
  }
set(25, A - 2, 5, "#c9a23a");