fogón

← Medieval3D assetfogon/molino-de-agua

Molino de agua

by fogonCC022179 blocks
Molino de aguaDrag to turn it
// «Molino de agua» · gpt-6-sol (medium)
// A small watermill seen from the front with its WATER WHEEL in clear view on the FRONT-RIGHT side (facing the viewer at -y or at +x, never hidden behind the house): a big round wooden water wheel almost as tall as the house, made of two rings of dark brown wood connected by many flat paddles around the rim and spokes to a central hub on a horizontal axle going into the wall, its lower part dipping into a strip of blue stream water running past the house. The house: stone ground floor, cream plaster upper floor with dark timber beams, red tiled roof, small wooden door and windows. Make the wheel the most noticeable thing.

const stone = ["#938d80", "#a8a294", "#827d72", "#b8b1a2"];
const plaster = ["#e9d9b5", "#f1e2c1", "#ddcba6"];
const timber = "#493022";
const timberLight = "#68422b";
const iron = "#292b2a";
const red = ["#a84635", "#ba5740", "#923b33", "#c36849"];
const water = ["#326f94", "#397fa4", "#286384", "#468dad"];

const sx0 = 5, sx1 = 25, sy0 = 14, sy1 = 35;

// A long, shallow millrace beside the house.
box(27, 2, 0, 46, 43, 1, "#355d70");
for (let x = 28; x <= 45; x++)
  for (let y = 3; y <= 42; y++) {
    set(x, y, 1, water[Math.floor(rand() * water.length)]);
    if (rand() < 0.13) set(x, y, 2, rand() < 0.5 ? "#6cb4c4" : "#91c6c8");
  }
for (let y = 2; y <= 43; y++) {
  for (let z = 0; z <= 2; z++) {
    set(26, y, z, stone[(y + z) % 3]);
    set(47, y, z, stone[(y + z + 1) % 3]);
  }
}
for (let y = 4; y < 43; y += 5) {
  line(29, y, 2, 32, y + 1, 2, 0, "#82c3cd");
  line(42, y + 2, 2, 44, y + 2, 2, 0, "#72b3c4");
}

// Solid stone ground floor, with individually shaded surface stones.
box(sx0, sy0, 0, sx1, sy1, 14, "#928c80");
for (let z = 0; z <= 14; z++)
  for (let x = sx0; x <= sx1; x++)
    for (let y = sy0; y <= sy1; y++)
      if (x === sx0 || x === sx1 || y === sy0 || y === sy1) {
        let c = stone[Math.floor(rand() * stone.length)];
        if (rand() < 0.035 && z < 6) c = "#68775a";
        set(x, y, z, c);
      }
for (let z = 2; z <= 13; z += 4)
  for (let x = 6; x <= 24; x++)
    if (x % 5 !== 0) set(x, 13, z, "#777267");
for (let z = 3; z <= 12; z += 5)
  for (let y = 16; y <= 34; y++)
    if (y % 5 !== 0) set(26, y, z, "#797367");
box(4, 13, 0, 26, 36, 1, "#79766b");
box(4, 13, 14, 26, 36, 15, "#514032");

// Cream upper storey.
box(sx0, sy0, 16, sx1, sy1, 29, plaster[0]);
for (let x = sx0; x <= sx1; x++)
  for (let y = sy0; y <= sy1; y++)
    for (let z = 16; z <= 29; z++)
      if ((x === sx0 || x === sx1 || y === sy0 || y === sy1) && rand() < 0.26)
        set(x, y, z, plaster[Math.floor(rand() * plaster.length)]);

// Plastered front gable beneath the pitched roof.
for (let x = 5; x <= 25; x++)
  for (let z = 30; z < 40 - Math.abs(x - 15); z++)
    set(x, 14, z, plaster[Math.floor(rand() * plaster.length)]);

// Heavy exposed timber framing.
for (const y of [13, 36]) {
  for (const x of [5, 15, 25]) box(x, y, 15, x, y, 29, timber);
  box(5, y, 15, 25, y, 16, timber);
  box(5, y, 28, 25, y, 29, timber);
  line(5, y, 16, 11, y, 27, 0, timberLight);
  line(25, y, 16, 19, y, 27, 0, timberLight);
}
for (const x of [4, 26]) {
  for (const y of [14, 24, 35]) box(x, y, 15, x, y, 29, timber);
  box(x, 14, 15, x, 35, 16, timber);
  box(x, 14, 28, x, 35, 29, timber);
}
for (let x = 7; x <= 23; x += 8)
  line(x, 13, 30, x + 6, 13, Math.min(37, 36 + (x === 7 ? 1 : -1)), 0, timber);
box(14, 13, 30, 16, 13, 37, timber);

// Chunky red-clay roof, its overlapping tile courses visible at the front.
for (let x = 3; x <= 27; x++) {
  let top = 40 - Math.abs(x - 15);
  for (let y = 12; y <= 37; y++) {
    let c = red[(Math.floor(y / 3) + Math.floor(x / 3)) % red.length];
    if (rand() < 0.11) c = red[Math.floor(rand() * red.length)];
    set(x, y, top - 1, "#71382e");
    set(x, y, top, c);
    if (y % 4 === 0) set(x, y, top + 1, "#ce7351");
  }
}
for (let y = 11; y <= 38; y++) box(14, y, 40, 16, y, 40, "#793d30");
for (let x = 3; x <= 27; x++) {
  let z = 40 - Math.abs(x - 15);
  set(x, 11, z, "#593428");
  if (x % 3 === 0) set(x, 11, z + 1, "#d27a53");
}

// Front doorway, stone arch, iron-strapped oak door.
box(12, 12, 0, 19, 14, 11, "#625d55");
box(13, 11, 0, 18, 11, 10, "#70452b");
for (let x = 13; x <= 18; x++)
  if (x % 2 === 0) box(x, 10, 0, x, 10, 10, "#815333");
box(12, 10, 0, 12, 12, 11, "#b1a99a");
box(19, 10, 0, 19, 12, 11, "#b1a99a");
box(12, 10, 11, 19, 12, 12, "#aaa293");
for (let z of [3, 8]) {
  box(13, 9, z, 18, 9, z, iron);
  set(13, 8, z, "#aaa18b");
  set(18, 8, z, "#aaa18b");
}
set(17, 8, 5, "#d5aa56");

// Deep-set, leaded windows.
function frontWindow(x, z, w, h) {
  box(x - 1, 12, z - 1, x + w, 13, z + h, timber);
  box(x, 11, z, x + w - 1, 11, z + h - 1, "#27343d");
  box(x, 10, z, x + w - 1, 10, z + h - 1, "#779ba0");
  for (let xx = x; xx < x + w; xx++)
    for (let zz = z; zz < z + h; zz++)
      if ((xx + zz) % 4 === 0) set(xx, 9, zz, "#a9b7a4");
  box(x + Math.floor(w / 2), 9, z, x + Math.floor(w / 2), 9, z + h - 1, iron);
  box(x, 9, z + Math.floor(h / 2), x + w - 1, 9, z + Math.floor(h / 2), iron);
  box(x - 1, 10, z - 1, x + w, 12, z - 1, "#b2aa99");
}
frontWindow(7, 6, 3, 5);
frontWindow(21, 6, 3, 5);
frontWindow(8, 20, 4, 5);
frontWindow(19, 20, 4, 5);

// Small heraldic sign above the doorway.
box(13, 10, 31, 17, 10, 34, "#b8924b");
box(14, 9, 31, 16, 9, 33, "#922f39");
box(15, 8, 31, 15, 8, 33, "#d9ad55");
box(14, 8, 32, 16, 8, 32, "#d9ad55");

// The horizontal axle enters the right-hand wall.
cylinder(24, 20, 17, 2, 19, timber, "x");
cylinder(26, 20, 17, 3, 2, iron, "x");
for (let x of [27, 29, 39, 41])
  cylinder(x, 20, 17, 2.4, 1, "#292a29", "x");

// Everything from here is one rotating water wheel.
part("water wheel", [35, 20, 17]);

const cy = 20, cz = 17, radius = 16;
const N = 12;

// Broad wooden spokes on both faces, with a sturdy central hub.
for (let face of [31, 40]) {
  for (let i = 0; i < N; i++) {
    let a = i * Math.PI * 2 / N;
    line(face, cy + Math.sin(a) * 2, cz + Math.cos(a) * 2,
         face, cy + Math.sin(a) * 15, cz + Math.cos(a) * 15,
         1, i % 2 ? "#694127" : "#794b2d");
    line(face + 1, cy + Math.sin(a) * 4, cz + Math.cos(a) * 4,
         face + 1, cy + Math.sin(a) * 13, cz + Math.cos(a) * 13,
         0, "#ab7746");
  }
}
cylinder(30, cy, cz, 3, 13, "#6c4027", "x");
for (let x of [30, 41]) {
  cylinder(x, cy, cz, 3, 1, "#9b683c", "x");
  cylinder(x + 1, cy, cz, 1, 1, iron, "x");
}

// Twelve long, flat buckets bridge the two rims.
for (let i = 0; i < N; i++) {
  let a = i * Math.PI * 2 / N;
  for (let t = -3; t <= 3; t++) {
    let yy = cy + Math.sin(a) * radius + Math.cos(a) * t;
    let zz = cz + Math.cos(a) * radius - Math.sin(a) * t;
    line(32, yy, zz, 40, yy, zz, 0, t % 3 === 0 ? "#ae7948" : "#785031");
  }
  for (let t of [-2, 2]) {
    let yy = cy + Math.sin(a) * radius + Math.cos(a) * t;
    let zz = cz + Math.cos(a) * radius - Math.sin(a) * t;
    set(35, yy, zz, "#bc8753");
  }
}

// Two thick continuous circular rims, with brighter outer edges.
for (let x of [30, 31, 40, 41]) {
  for (let j = 0; j < 720; j++) {
    let a = j * Math.PI / 360;
    for (let r = 14; r <= 16; r++) {
      let yy = cy + Math.sin(a) * r;
      let zz = cz + Math.cos(a) * r;
      set(x, yy, zz, r === 16 ? "#4a2d20" :
          r === 14 ? "#a37143" : "#684026");
    }
  }
}
// Iron straps and bright rivets punctuate the visible outer face.
for (let i = 0; i < N; i++) {
  let a = i * Math.PI * 2 / N;
  let yy = cy + Math.sin(a) * 15;
  let zz = cz + Math.cos(a) * 15;
  line(42, yy - Math.sin(a), zz - Math.cos(a),
       42, yy + Math.sin(a), zz + Math.cos(a), 0, iron);
  set(43, yy, zz, "#b4a488");
}

animate("water wheel", { type: "spin", axis: "x", speed: 1.5 });
part("body", [0, 0, 0]);