fogón

← Antiguo y prehistoriaObjeto 3Dfogon/market-stall

Puesto del mercado

de fogonCC06526 bloques
Puesto del mercadoArrastrá para girarlo
// «Puesto del mercado» · propio
// A desert market stall: a wooden table on four dark posts under a slanted red and cream striped cloth roof, a striped skirt at the front, green melons and oranges piled on the table and a small dark box.

// A desert market stall: a wooden table on four dark posts under a slanted red and cream striped cloth, a striped
// skirt at the front, melons and oranges piled on the table and a small dark box.
const wood = ["#73492a", "#85562f", "#976639", "#a97645", "#b98652"];
const post = ["#3b2718", "#4a321f", "#5a3e27"];
const red = ["#8f2f22", "#a83b2a", "#bf4a36", "#d25c46"];
const cream = ["#cbb68c", "#dcc9a0", "#ead9b6", "#f5e8cb"];
const melon = ["#2a5f27", "#35722f", "#43873a", "#5a9d4c"];
const orange = ["#c06f18", "#d98424", "#ec9a34", "#f7b352"];
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
const X0 = 6, X1 = 41, Y0 = 16, Y1 = 34;
// The cloth roof: low at the front, high at the back.
const roofZ = (y) => 33 + (y - 9) * 0.17;
const stripe = (x) => Math.floor((x - 2) / 4) % 2 === 0;

// The table: planks, with an apron under them.
for (let x = X0; x <= X1; x++)
  for (let y = Y0; y <= Y1; y++) {
    const line = (y - Y0) % 5 === 4;
    set(x, y, 14, line ? wood[0] : wood[clampi(2 + ((Math.floor((y - Y0) / 5) * 2) % 3) - (rand() < 0.14 ? 1 : 0), 0, 4)]);
    set(x, y, 13, wood[1]);
    if (x === X0 || x === X1 || y === Y0 || y === Y1) for (let z = 10; z <= 12; z++) set(x, y, z, wood[z === 12 ? 2 : 1]);
  }
// The four posts, up to the cloth.
for (const px of [X0, X1 - 1])
  for (const py of [Y0, Y1 - 1])
    for (let z = 0; z <= roofZ(py) - 1; z++) for (let i = 0; i < 2; i++) for (let j = 0; j < 2; j++) set(px + i, py + j, z, post[clampi((i === 0 && j === 0 ? 2 : 1) - (z < 3 ? 1 : 0), 0, 2)]);
// A rail between the back posts and a shelf bar under the table.
box(X0, Y1, 24, X1, Y1, 24, post[1]);
box(X0 + 1, Y0, 6, X1 - 1, Y0, 6, post[1]);
// The skirt at the front, scalloped at the bottom.
for (let x = X0; x <= X1; x++) {
  const s = stripe(x);
  const low = 3 + (Math.abs(((x - X0) % 6) - 3) < 1.5 ? 0 : 1);
  for (let z = low; z <= 13; z++) set(x, Y0 - 1, z, (s ? red : cream)[clampi(2 - (z < 6 ? 1 : 0) - ((x - 2) % 4 === 0 ? 1 : 0) - (rand() < 0.1 ? 1 : 0), 0, 3)]);
}
// The roof cloth, two layers (the under one in shade), with a hem hanging at the front.
for (let x = 3; x <= 44; x++) {
  const s = stripe(x);
  const tones = s ? red : cream;
  const fold = (x - 2) % 4 === 0 ? 1 : 0;
  for (let y = 8; y <= 39; y++) {
    const z = Math.round(roofZ(y) + 0.8 * Math.sin((x - 3) / 41 * Math.PI) * -1.2);
    set(x, y, z, tones[clampi(3 - fold - (rand() < 0.1 ? 1 : 0), 0, 3)]);
    set(x, y, z - 1, tones[clampi(1 - fold, 0, 3)]);
  }
  const zf = Math.round(roofZ(8) + 0.8 * Math.sin((x - 3) / 41 * Math.PI) * -1.2);
  const hang = Math.abs(((x - 3) % 6) - 3) < 1.5 ? 4 : 3;
  for (let k = 1; k <= hang; k++) set(x, 8, zf - k, tones[clampi(2 - fold - (k === hang ? 1 : 0), 0, 3)]);
}
// Melons, piled at the left: striped dark and light.
function ball(cx, cy, cz, r, tones, stripes) {
  for (let x = Math.floor(cx - r); x <= Math.ceil(cx + r); x++)
    for (let y = Math.floor(cy - r); y <= Math.ceil(cy + r); y++)
      for (let z = Math.floor(cz - r); z <= Math.ceil(cz + r); z++) {
        const d = Math.hypot(x - cx, y - cy, z - cz);
        if (d > r) continue;
        let tone = 1 + (z > cz ? 1 : 0) + (x < cx && y < cy ? 1 : 0) - (z < cz - r * 0.4 ? 1 : 0);
        if (stripes && Math.round(Math.atan2(y - cy, x - cx) * 2.4) % 2 === 0) tone--;
        set(x, y, z, tones[clampi(tone, 0, 3)]);
      }
}
ball(12, 21, 17.6, 3, melon, true);
ball(18.5, 20.5, 17.6, 3, melon, true);
ball(12.5, 27.5, 17.6, 3, melon, true);
ball(19, 27, 17.6, 3, melon, true);
ball(15.5, 24, 22.2, 3, melon, true);
// Oranges, in rows at the right, a few on a second layer.
for (let i = 0; i < 4; i++) for (let j = 0; j < 3; j++) ball(27 + i * 3.6, 19 + j * 3.6, 16.4, 1.7, orange, false);
ball(29, 21, 19.2, 1.7, orange, false);
ball(32.6, 21, 19.2, 1.7, orange, false);
ball(36, 21, 19.2, 1.7, orange, false);
ball(31, 24.5, 19.2, 1.7, orange, false);
// The small dark box at the back, with its lid ajar.
box(28, 29, 15, 37, 33, 18, "#3b2a1c");
box(28, 29, 18, 37, 33, 18, "#52392a");
box(28, 29, 19, 37, 30, 19, "#52392a");
box(32, 28, 16, 33, 28, 17, "#b08a3a");