fogón

← Medieval3D assetfogon/ariete

Ariete

by fogonCC011225 blocks
ArieteDrag to turn it
// «Ariete» · gpt-6-sol (medium)
// A medieval battering ram: a big wooden frame on four solid wooden wheels, with a sloped plank roof covered in hides, and under it a huge log ram hanging from two chains, its front end capped with a black iron head shaped like a ram's head pointing forward (-y).

const wood = "#513320";
const woodDark = "#382318";
const woodLight = "#785036";
const iron = "#25282a";
const ironLight = "#4c5355";
const gold = "#c59a4c";

// Four solid wheels with iron tires and wooden hubs.
for (const wy of [14, 35]) {
  for (const side of ["left", "right"]) {
    const x0 = side === "left" ? 5 : 39;
    const face = side === "left" ? 5 : 42;

    cylinder(x0, wy, 6, 6, 4, woodDark, "x");
    cylinder(x0, wy, 6, 4, 4, wood, "x");

    for (let a = 0; a < 360; a += 3) {
      const t = a * Math.PI / 180;
      const yy = Math.round(wy + 5.5 * Math.cos(t));
      const zz = Math.round(6 + 5.5 * Math.sin(t));
      for (let x = x0; x <= x0 + 3; x++) {
        set(x, yy, zz, a % 24 < 8 ? ironLight : iron);
      }
    }

    for (let a = 0; a < 360; a += 45) {
      const t = a * Math.PI / 180;
      line(face, wy, 6,
           face, wy + 4 * Math.cos(t), 6 + 4 * Math.sin(t),
           0, woodLight);
    }

    cylinder(face, wy, 6, 2, 1, ironLight, "x");
    set(face, wy, 6, gold);
  }
}

// Heavy chassis and wheel axles.
for (const yy of [14, 35]) {
  box(9, yy - 1, 5, 38, yy + 1, 7, woodDark);
  box(10, yy, 7, 37, yy, 8, woodLight);
}
for (const xx of [12, 36]) {
  box(xx - 2, 10, 8, xx + 2, 39, 10, woodDark);
  box(xx - 1, 11, 10, xx + 1, 38, 11, woodLight);
}

// Posts, side rails, and diagonal braces.
for (const xx of [12, 36]) {
  for (const yy of [12, 37]) {
    box(xx - 2, yy - 2, 8, xx + 2, yy + 2, 30, woodDark);
    box(xx - 1, yy - 2, 11, xx, yy - 2, 29, woodLight);
    for (const z of [10, 25]) {
      box(xx - 2, yy - 2, z, xx + 2, yy + 2, z + 1, iron);
    }
    set(xx, yy - 2, 26, gold);
  }

  box(xx - 1, 12, 24, xx + 1, 37, 26, wood);
  box(xx - 1, 12, 24, xx - 1, 37, 24, woodLight);
  line(xx, 15, 10, xx, 23, 23, 1, wood);
  line(xx, 34, 10, xx, 27, 23, 1, wood);
}
for (const yy of [11, 38]) {
  box(12, yy, 27, 36, yy + 1, 29, woodDark);
  line(12, yy, 30, 24, yy, 38, 1, wood);
  line(24, yy, 38, 36, yy, 30, 1, wood);
}

// Ridge and rafters.
box(23, 9, 36, 25, 40, 38, woodDark);
for (const yy of [11, 20, 29, 38]) {
  line(10, yy, 30, 24, yy, 38, 1, wood);
  line(24, yy, 38, 38, yy, 30, 1, wood);
}

// Sloping roof of stitched, irregular hides.
const hides = ["#756750", "#8a775b", "#a08b69", "#695c4b"];
for (let x = 9; x <= 39; x++) {
  const z = 39 - Math.floor(Math.abs(x - 24) * 0.53);
  for (let y = 9; y <= 40; y++) {
    const patch = (
      Math.floor((y - 9) / 7) * 3 +
      Math.floor(Math.abs(x - 24) / 7)
    ) % hides.length;
    const color = rand() < 0.09
      ? hides[(patch + 1) % hides.length]
      : hides[patch];

    set(x, y, z - 1, woodDark);
    set(x, y, z, color);
    if (y % 7 === 1) set(x, y, z, "#4c4035");
  }
}
box(23, 8, 39, 25, 41, 39, woodDark);

for (const x of [9, 39]) {
  for (let y = 10; y <= 40; y += 3) {
    set(x, y, 31, gold);
  }
}
for (let x = 10; x <= 38; x += 3) {
  const z = 39 - Math.floor(Math.abs(x - 24) * 0.53);
  set(x, 9, z, "#c6ac80");
  set(x, 10, z, iron);
}

// Small heraldic banners on the open sides.
for (const x of [10, 38]) {
  const banner = x === 10 ? "#852f36" : "#304d83";
  box(x, 20, 20, x, 27, 26, banner);
  for (let y = 20; y <= 27; y++) {
    set(x, y, 26, gold);
    if (y % 2 === 0) set(x, y, 20, gold);
  }
  box(x, 23, 22, x, 24, 24, gold);
  set(x, 23, 23, banner);
}

// Chains and log move together beneath the roof.
part("ram", [24, 24, 30]);
animate("ram", {
  type: "swing",
  axis: "x",
  speed: 2,
  amplitude: 0.35
});

for (const yy of [15, 34]) {
  for (const xx of [20, 28]) {
    set(xx, yy, 30, ironLight);
    for (let z = 21; z <= 29; z++) {
      set(xx, yy, z, z % 2 ? ironLight : iron);
      if (z % 3 === 0) {
        set(xx + (xx < 24 ? 1 : -1), yy, z, iron);
      }
    }
    set(xx, yy, 20, gold);
  }
}

// Solid wooden ram with grain and iron bindings.
cylinder(24, 9, 17, 4, 31, woodDark, "y");
cylinder(24, 10, 17, 3, 29, wood, "y");
for (let y = 13; y <= 37; y++) {
  for (const x of [22, 25, 27]) {
    if (rand() < 0.72) set(x, y, 20, woodLight);
  }
}
for (const y of [13, 19, 32, 37]) {
  cylinder(24, y, 17, 5, 2, iron, "y");
  for (const x of [20, 24, 28]) {
    set(x, y, 21, ironLight);
  }
  set(24, y, 22, gold);
}
cylinder(24, 39, 17, 3, 1, "#9b7147", "y");
set(24, 39, 17, woodDark);
for (const [x, z] of [[22, 16], [26, 16], [24, 19]]) {
  set(x, 39, z, woodDark);
}

// Forward-facing forged ram's head: muzzle, brow, ears, and curled horns.
cylinder(24, 8, 17, 5, 5, iron, "y");
box(20, 5, 17, 28, 10, 22, iron);
box(21, 4, 15, 27, 8, 19, iron);
box(22, 3, 15, 26, 6, 18, ironLight);
box(20, 5, 21, 28, 7, 23, "#363c3e");
box(18, 8, 20, 20, 11, 22, iron);
box(28, 8, 20, 30, 11, 22, iron);

for (const s of [-1, 1]) {
  line(24 + s * 4, 9, 22, 24 + s * 8, 10, 25, 2, iron);
  line(24 + s * 8, 10, 25, 24 + s * 10, 7, 24, 1, ironLight);
  line(24 + s * 10, 7, 24, 24 + s * 8, 5, 21, 1, iron);
  set(24 + s * 7, 8, 26, ironLight);
}

for (const x of [21, 27]) {
  set(x, 4, 20, gold);
  set(x, 3, 16, iron);
}
set(24, 3, 18, gold);
set(24, 5, 22, ironLight);