fogón

← Medieval3D assetfogon/mesa-de-banquete

Mesa de banquete

by fogonCC09022 blocks
Mesa de banqueteDrag to turn it
// «Mesa de banquete» · gpt-6-sol (medium)
// A long medieval banquet table along y: thick dark wooden planks on chunky legs, covered with a red runner cloth, loaded with a roast chicken on a platter, a roasted pig with an apple in its mouth, bread loaves, grapes, golden goblets, candles on a candlestick, with two long wooden benches on the sides.

// Long banquet table and side benches
const woodDark = "#3b2219", wood = "#593421", woodLight = "#76462a";
const iron = "#292c2e", gold = "#c99a3d";
const red = "#912c32", redLight = "#b63d40";

// Chunky table legs and low cross-braces
for (const x of [15, 31]) {
  for (const y of [9, 39]) {
    box(x, y, 0, x + 3, y + 3, 12, woodDark);
    box(x, y, 2, x + 3, y + 3, 3, iron);
    box(x, y, 9, x + 3, y + 3, 10, iron);
    set(x + 1, y, 3, gold);
    set(x + 1, y, 10, gold);
  }
}
box(17, 11, 4, 32, 12, 6, wood);
box(17, 39, 4, 32, 40, 6, wood);
for (const x of [16, 32]) box(x, 11, 6, x + 1, 40, 8, woodDark);

// Deep apron and thick, individually visible planks
box(13, 5, 10, 35, 43, 12, woodDark);
for (const [x0, x1, shade] of [
  [13, 16, wood], [18, 21, woodLight], [23, 26, wood],
  [28, 31, woodLight], [33, 35, wood]
]) {
  box(x0, 5, 13, x1, 43, 14, shade);
  for (let i = 0; i < 35; i++) {
    const x = x0 + Math.floor(rand() * (x1 - x0 + 1));
    const y = 6 + Math.floor(rand() * 37);
    set(x, y, 14, rand() < 0.5 ? "#805034" : "#633a25");
  }
}
for (const x of [17, 22, 27, 32]) box(x, 5, 13, x, 43, 14, woodDark);
box(13, 5, 12, 35, 5, 13, "#875333");
box(13, 43, 12, 35, 43, 13, woodDark);

// Two long, sturdy benches
for (const x of [5, 38]) {
  for (const y of [10, 37]) {
    box(x + 1, y, 0, x + 4, y + 3, 8, woodDark);
    box(x + 1, y, 2, x + 4, y + 3, 2, iron);
  }
  box(x, 7, 8, x + 6, 41, 9, woodDark);
  box(x, 7, 10, x + 2, 41, 10, woodLight);
  box(x + 4, 7, 10, x + 6, 41, 10, woodLight);
  box(x + 3, 7, 10, x + 3, 41, 10, "#3a2119");
  for (const y of [10, 20, 30, 39]) {
    set(x + 1, y, 10, "#a36b3e");
    set(x + 5, y, 10, "#a36b3e");
  }
}

// Runner, with hanging ends and gold woven borders
box(21, 6, 15, 27, 42, 15, red);
for (const x of [21, 27]) box(x, 6, 15, x, 42, 15, gold);
for (const y of [5, 43]) {
  box(21, y, 10, 27, y, 15, red);
  box(21, y, 10, 21, y, 15, gold);
  box(27, y, 10, 27, y, 15, gold);
  box(22, y, 10, 26, y, 10, gold);
  set(24, y, 12, gold);
}
for (const y of [8, 20, 28, 40]) {
  set(24, y, 15, redLight);
  set(23, y + 1, 15, gold);
  set(25, y + 1, 15, gold);
}

// Roast chicken on a broad pewter platter
ellipsoid(24, 15, 16, 5.5, 6.1, 0.7, "#7d8581");
ellipsoid(24, 15, 16, 4.7, 5.2, 0.7, "#b5b9a6");
ellipsoid(24, 15, 17, 2.8, 3.3, 1.8, "#86431e");
ellipsoid(24, 14, 18, 2.5, 2.5, 1.3, "#bc7130");
ellipsoid(22, 16, 18, 1.1, 1.8, 0.8, "#dc9142");
for (const x of [21, 27]) {
  line(x, 17, 17, x + (x < 24 ? -1 : 1), 20, 17, 1, "#a45524");
  line(x + (x < 24 ? -1 : 1), 20, 17,
       x + (x < 24 ? -1 : 1), 22, 17, 0, "#e8d8af");
  sphere(x + (x < 24 ? -1 : 1), 22, 17, 0.7, "#eee0bd");
}

// Whole roasted pig, facing the viewer, with an apple in its mouth
ellipsoid(24, 33, 16, 6.5, 8.1, 0.7, "#808783");
ellipsoid(24, 33, 16, 5.7, 7.2, 0.7, "#b4b8a5");
ellipsoid(24, 33, 18, 4.2, 4.7, 2.2, "#8d411e");
ellipsoid(24, 32, 19, 3.7, 3.6, 1.4, "#b6652d");
ellipsoid(24, 28, 18, 3.1, 2.7, 2, "#aa5425");
ellipsoid(24, 26, 17, 1.8, 1, 1, "#be713b");
for (const x of [22, 26]) {
  set(x, 26, 18, "#281b16");          // eyes
  ellipsoid(x, 29, 21, 0.9, 1.2, 0.8, "#75321b"); // ears
  for (const y of [30, 36])
    ellipsoid(x + (x < 24 ? -2 : 2), y, 17, 1, 1.5, 1, "#98451f");
}
for (const x of [23, 25]) set(x, 25, 17, "#71351e"); // nostrils
sphere(24, 24, 16, 1.3, "#c62e28");
set(24, 23, 16, "#e64b35");
set(24, 24, 18, "#567536");
line(28, 36, 18, 30, 38, 19, 0, "#78321a"); // curled tail

// Crusty loaves, scored across their tops
for (const [x, y] of [[32, 11], [17, 38], [32, 40]]) {
  ellipsoid(x, y, 16, 2.3, 3, 0.6, "#837d69");
  ellipsoid(x, y, 17, 1.9, 2.6, 1.3, "#a9632d");
  ellipsoid(x, y, 18, 1.6, 2.2, 0.7, "#d99449");
  for (const dy of [-1, 1]) line(x - 1, y + dy, 19, x + 1, y + dy, 19, 0, "#f1cc83");
}

// Purple and green bunches of grapes
for (const [cx, cy, color] of [[32, 19, "#583967"], [17, 17, "#718442"]]) {
  ellipsoid(cx, cy, 16, 2.6, 2.5, 0.5, "#928e75");
  for (let i = 0; i < 13; i++) {
    const x = cx + Math.round((rand() - 0.5) * 4);
    const y = cy + Math.round((rand() - 0.5) * 4);
    sphere(x, y, 17 + Math.floor(rand() * 2), 0.7, color);
  }
  line(cx, cy + 1, 18, cx + 1, cy + 3, 18, 0, "#587043");
}

// Golden goblets around the place settings
for (const [x, y] of [[17, 12], [32, 15], [17, 29], [32, 29], [31, 36]]) {
  cylinder(x, y, 15, 1.4, 1, "#a7782d");
  cylinder(x, y, 16, 0.5, 2, gold);
  cylinder(x, y, 18, 1.5, 2, "#e3b954");
  set(x, y, 20, "#69312c"); // dark wine inside
  for (const [dx, dy] of [[-1, 0], [1, 0], [0, -1], [0, 1]])
    set(x + dx, y + dy, 20, "#f1cf70");
}

// Twin branched iron candlesticks
const flames = [];
for (const cx of [17, 31]) {
  const cy = 23;
  cylinder(cx, cy, 15, 2, 1, iron);
  cylinder(cx, cy, 16, 1.4, 1, gold);
  cylinder(cx, cy, 17, 0.6, 5, iron);
  for (const dx of [-2, 0, 2]) {
    if (dx) line(cx, cy, 20, cx + dx, cy, 22, 0, iron);
    cylinder(cx + dx, cy, 22, 1, 1, gold);
    box(cx + dx, cy, 23, cx + dx, cy, 25, "#f3dfae");
    set(cx + dx, cy, 26, "#29211c");
    flames.push(cx + dx);
  }
}

// All flames belong to one flickering color part.
part("candle_flames", [24, 23, 26]);
for (const x of flames) {
  set(x, 23, 27, "#ff9b29");
  set(x, 23, 28, "#ffe268");
  set(x, 23, 29, "#fff2aa");
}
animate("candle_flames", {
  type: "colors",
  palette: ["#ff8d24", "#ffc52e", "#fff0a0"],
  pattern: "flicker",
  glow: 0.8
});