fogón

← CiudadObjeto 3Dfogon/container-stack

Pila de contenedores

de fogonCC08502 bloques
Pila de contenedoresArrastrá para girarlo
// «Pila de contenedores» · propio
// Two shipping containers stacked one on top of the other, the lower one green and the upper one orange, slightly offset, corrugated sides and door ends.

// Two shipping containers, one on top of the other and a little out of line. Doors at the front (-y).
const SHARED = { casting: "#3d3f44", steel: "#c4c0b8", steelDark: "#85827c" };
const GREEN = {
  ...SHARED, base: "#3f8f5a", light: "#4ba168", dark: "#327449", groove: "#245838", top: "#5cb378", frame: "#2d6a43", frameTop: "#367d4f",
  rust: "#6f5a2e", rust2: "#8f6a34", seam: "#173a25",
};
const ORANGE = {
  ...SHARED, base: "#e07a2a", light: "#ee8b3a", dark: "#bb6220", groove: "#96501a", top: "#f39b4c", frame: "#b55d1f", frameTop: "#cc6b25",
  rust: "#9a4f1e", rust2: "#7f4420", seam: "#6b3712",
};

// A container L long, W wide (odd, so the doors meet in the middle) and H high, with a frame F thick. `put(u, v, w, color)`
// places a block u along its length (0 at the doors), v across and w up. The walls are corrugated: every third column
// is set back one block.
function container(put, L, W, H, F, C, bars) {
  const mid = (W - 1) / 2;
  const side = (u, w) => {
    if (u % 3 === 0) return null;
    if (w < 3 + (u % 5 === 0 ? 1 : 0) && rand() < 0.5) return C.dark; // grime near the ground
    if (rand() < 0.035) return rand() < 0.5 ? C.rust : C.rust2;
    return u % 3 === 1 ? C.light : C.base;
  };
  const door = (v, w) => {
    if (v === mid) return C.seam;
    if ((v === F || v === W - 1 - F) && (w === F + 1 || w === Math.floor(H / 2) || w === H - 2 - F)) return C.casting; // hinges
    if (w === F || w === H - 1 - F) return C.dark;
    return rand() < 0.03 ? C.rust : C.base;
  };
  for (let u = 0; u < L; u++)
    for (let v = 0; v < W; v++)
      for (let w = 0; w < H; w++) {
        const du = Math.min(u, L - 1 - u), dv = Math.min(v, W - 1 - v), dw = Math.min(w, H - 1 - w);
        const depth = Math.min(du, dv, dw);
        if (depth > 1) continue; // hollow
        const frame = (du < F && dv < F) || (dw < F && dv < F) || (dw < F && du < F);
        let c;
        if (du <= F && dv <= F && dw <= F) c = C.casting; // the corner blocks cranes grab
        else if (frame) c = w >= H - F ? C.frameTop : C.frame;
        else if (depth === 1) c = C.groove; // seen only through the grooves
        else if (dw === 0) c = w === 0 ? C.frame : u % 3 === 0 ? null : rand() < 0.06 ? C.light : C.top;
        else if (du === 0 && u === 0) c = door(v, w);
        else if (du === 0) c = (v - F) % 3 === 0 ? null : (v - F) % 3 === 1 ? C.light : C.base;
        else c = side(u, w);
        if (c) put(u, v, w, c);
      }
  // Lock bars on the doors, with their brackets and handles.
  const grip = Math.floor(H * 0.4);
  for (const v of bars) {
    for (let w = F; w <= H - 1 - F; w++) put(-1, v, w, w === F || w === H - 1 - F || w === Math.floor(H * 0.7) ? C.steelDark : C.steel);
  }
  put(-1, bars[0] + 1, grip, C.steelDark);
  put(-1, bars[3] - 1, grip, C.steelDark);
  // Rust running down from the roof rail.
  for (let n = 0; n < 8; n++) {
    const u = F + 1 + Math.floor(rand() * (L - 2 * F - 2));
    if (u % 3 === 0) continue;
    const v = rand() < 0.5 ? 0 : W - 1;
    for (let k = 0; k < 2 + Math.floor(rand() * 3); k++) put(u, v, H - 1 - F - k, k ? C.rust : C.rust2);
  }
}

const L = 38, W = 15, H = 16;
const at = (x0, y0, z0) => (u, v, w, c) => set(x0 + v, y0 + u, z0 + w, c);
container(at(15, 3, 0), L, W, H, 2, GREEN, [3, 5, 9, 11]);
container(at(18, 6, H), L, W, H, 2, ORANGE, [3, 5, 9, 11]);