fogón

← Ancient and prehistory3D assetfogon/grain-sacks

Bolsas de arpillera

by fogonCC012823 blocks
Bolsas de arpilleraDrag to turn it
// «Bolsas de arpillera» · propio
// A pile of four fat burlap sacks, three on the ground and one on top, tied necks, tan with darker weave, one open showing golden grain.

// A pile of four fat burlap sacks: two lying side by side, one across on top, and one standing open, full of grain.
const burlap = ["#8a6c3f", "#9c7d4c", "#b0915c", "#c2a36c", "#d0b47e", "#dcc392"];
const seam = "#6f5530";
const rope = "#4a3520";
const grain = ["#c8921a", "#d9a520", "#e8b93a", "#f2cb5a"];
const clampi = (v, lo, hi) => Math.max(lo, Math.min(hi, v));
// A sack: a plump rounded box of cloth with a loose weave, lighter on top.
function sack(cx, cy, cz, rx, ry, rz, opts = {}) {
  for (let x = Math.floor(cx - rx); x <= Math.ceil(cx + rx); x++)
    for (let y = Math.floor(cy - ry); y <= Math.ceil(cy + ry); y++)
      for (let z = Math.max(0, Math.floor(cz - rz)); z <= Math.ceil(cz + rz); z++) {
        const nx = (x - cx) / rx, ny = (y - cy) / ry, nz = (z - cz) / rz;
        const d = Math.pow(Math.abs(nx), 2.6) + Math.pow(Math.abs(ny), 2.6) + Math.pow(Math.abs(nz), 2.6);
        if (d > 1) continue;
        if (opts.cut != null && z > opts.cut) continue;
        let tone = 3 + (nz > 0.5 ? 1 : nz < -0.35 ? -1 : 0);
        tone += -nx - ny > 0.8 ? 1 : -nx - ny < -0.8 ? -1 : 0;
        if ((x + 2 * y + 3 * z) % 5 === 0) tone--;
        if (rand() < 0.06) tone--;
        let c = burlap[clampi(tone, 0, 5)];
        // The seam along its length.
        const along = opts.seam === "x" ? Math.abs(y - cy) < 0.6 : opts.seam === "y" ? Math.abs(x - cx) < 0.6 : false;
        if (along && nz > 0.2) c = seam;
        set(x, y, z, c);
      }
}
// A tied neck at the end of a lying sack: a short bunch, a dark rope around it and a tuft of cloth past the knot.
function neck(x, y, z, dx, dy) {
  for (let k = 0; k <= 4; k++) {
    const r = k < 2 ? 2.6 - k * 0.5 : k === 2 ? 1.7 : 2.2 + (k - 3) * 0.7;
    for (let u = -4; u <= 4; u++)
      for (let v = -4; v <= 4; v++) {
        if (Math.hypot(u, v) > r) continue;
        const c = k === 2 ? rope : burlap[clampi((k >= 3 ? 4 : 3) + (v > 0 ? 1 : 0) - ((u + v + 8) % 2 && k >= 3 ? 1 : 0), 0, 5)];
        set(x + dx * k + (dx ? 0 : u), y + dy * k + (dy ? 0 : u), Math.max(0, z + v), c);
      }
  }
}
// Two lying on the ground, side by side, their necks to the left.
sack(31, 14, 6, 11.5, 8.2, 6.4, { seam: "x" });
neck(19, 14, 6, -1, 0);
sack(31, 31, 6, 11.5, 8.2, 6.4, { seam: "x" });
// One across on top of them, sagging into the gap, its neck to the front.
sack(31, 22.5, 15.5, 7.8, 12, 5.6, { seam: "y" });
neck(31, 10, 15.5, 0, -1);
// One standing open beside them, its mouth rolled down, full of golden grain.
const OX = 9.5, OY = 31;
sack(OX, OY, 11, 8, 8, 11.4, { cut: 19 });
for (let x = 0; x <= 19; x++)
  for (let y = 21; y <= 41; y++) {
    const d = Math.hypot(x - OX, y - OY);
    if (d < 6.2) set(x, y, 19, grain[clampi(1 + Math.floor(rand() * 3), 0, 3)]);
    if (d < 4) set(x, y, 20, grain[clampi(2 + Math.floor(rand() * 2), 0, 3)]);
    if (d < 1.8) set(x, y, 21, grain[3]);
    if (d >= 6.2 && d < 8.4) for (const z of [19, 20]) set(x, y, z, burlap[z === 20 ? 5 : 3]);
  }
// A rope round its middle, and grain spilled on the ground in front of it.
for (let x = 0; x <= 19; x++)
  for (let y = 21; y <= 41; y++) if (get(x, y, 14) && (!get(x - 1, y, 14) || !get(x, y - 1, 14) || !get(x + 1, y, 14) || !get(x, y + 1, 14))) set(x, y, 14, rope);
for (let i = 0; i < 34; i++) {
  const a = rand() * Math.PI * 2, r = rand() * 5;
  set(11 + Math.cos(a) * r, 17 + Math.sin(a) * r * 0.7, 0, grain[1 + Math.floor(rand() * 3)]);
}