fogón

← FantasíaObjeto 3Dfogon/cristal-magico

Cristal mágico

de fogonCC011081 bloques
Cristal mágicoArrastrá para girarlo
// «Cristal mágico» · gpt-6-sol (medium)
// A cluster of magic crystals growing from a rough grey mossy rock: one tall central hexagonal crystal with a pointed tip, slightly tilted, and four or five smaller pointed crystals around it at different angles. The crystals are translucent-looking violet and cyan, lighter at the tips. The central crystal glows and floats a little above the rock.

// A rough, mossy stone nest for the floating crystal.
ellipsoid(24, 24, 3, 18, 15, 8, "#696b70");
ellipsoid(15, 25, 3, 9, 11, 6, "#696b70");
ellipsoid(34, 25, 3, 9, 10, 6, "#696b70");
ellipsoid(23, 17, 5, 12, 8, 7, "#696b70");

const stone = [];
forEach((x, y, z) => stone.push([x, y, z]));
for (const [x, y, z] of stone) {
  const top = !get(x, y, z + 1);
  const shades = z < 3
    ? ["#50545a", "#595d61", "#626569"]
    : ["#62666b", "#707378", "#7b7d7c", "#858681"];
  set(x, y, z, shades[Math.floor(rand() * shades.length)]);

  if (top && z >= 4 && rand() < 0.29) {
    set(x, y, z, ["#435b4e", "#56745b", "#688568", "#78946e"][Math.floor(rand() * 4)]);
    if (rand() < 0.24 && !get(x, y, z + 1)) {
      set(x, y, z + 1, "#72986b");
    }
  }
}

// Bright runes and scattered sparks across the stone.
for (let i = 0; i < 38; i++) {
  const x = 9 + Math.floor(rand() * 30);
  const y = 11 + Math.floor(rand() * 27);
  for (let z = 13; z >= 0; z--) {
    if (get(x, y, z)) {
      if (rand() < 0.65) set(x, y, z + 1, rand() < 0.5 ? "#5acfc9" : "#ae74e1");
      break;
    }
  }
}

function mushroom(x, y, cap) {
  let z = 12;
  while (z > 0 && !get(x, y, z)) z--;
  z++;
  box(x, y, z, x, y, z + 2, "#d9d3b7");
  ellipsoid(x, y, z + 3, 2, 2, 1, cap);
  set(x, y - 1, z + 4, "#f5dfd5");
}
mushroom(12, 15, "#c877aa");
mushroom(35, 15, "#dd9cba");
mushroom(12, 32, "#87b39b");

// A small pool of magic light sits below the hovering central crystal.
for (let z = 11; z <= 13; z++) {
  for (let x = 18; x <= 30; x++) for (let y = 18; y <= 30; y++) {
    const d = Math.hypot(x - 24, y - 24);
    if (Math.abs(d - (z === 13 ? 4.4 : 5.5)) < 0.55) {
      set(x, y, z, z === 13 ? "#8ef5e9" : "#a95de0");
    }
  }
}
set(24, 24, 13, "#ddfbfa");
set(23, 24, 13, "#80e8e7");
set(25, 24, 13, "#80e8e7");

// Solid six-sided prisms, with distinct shaded faces and faceted pointed tips.
function crystal(x0, y0, z0, dx, dy, height, radius, colors) {
  for (let k = 0; k < height; k++) {
    const t = k / (height - 1);
    const cx = x0 + dx * t;
    const cy = y0 + dy * t;
    const r = t < 0.67
      ? radius * (k === 0 ? 0.84 : 1)
      : Math.max(0.38, radius * (1 - (t - 0.67) / 0.33));
    for (let x = Math.floor(cx - r - 1); x <= Math.ceil(cx + r + 1); x++) {
      for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++) {
        const a = Math.abs(x - cx), b = Math.abs(y - cy);
        if (b > 0.866 * r || 0.866 * a + 0.5 * b > 0.866 * r) continue;

        let color = y < cy - 0.5 ? colors[1] : colors[0];
        if (x < cx - 0.5 && y <= cy) color = colors[2];
        if (x > cx + 0.5 && y > cy) color = colors[3];
        if (t > 0.68) color = colors[4];
        if (t > 0.88) color = colors[5];
        if (t < 0.68 && rand() < 0.045) color = colors[4];
        set(x, y, z0 + k, color);
      }
    }
  }
}

const violet = ["#773daa", "#a968d2", "#ca8be5", "#583b92", "#da9bf0", "#f1d7ff"];
const cyan = ["#279baf", "#6bdcdd", "#9ae9e8", "#35749e", "#aaf6ed", "#e4fffa"];
const pink = ["#a746a8", "#df83c7", "#eea8df", "#753c98", "#f6b9eb", "#ffe4fa"];

// Five smaller crystals fan out at different angles.
const satellites = [
  ["left",       15, 21, 9, -7, -3, 19, 3.1, violet],
  ["right",      33, 22, 9,  7, -3, 21, 3.2, cyan],
  ["front",      24, 15, 9, -2, -5, 17, 2.8, pink],
  ["back",       26, 31, 9,  3,  5, 22, 3.0, cyan],
  ["back_left",  16, 30, 8, -4,  4, 17, 2.6, violet]
];
for (const [name, x, y, z, dx, dy, h, r, palette] of satellites) {
  part(name, [x, y, z]);
  crystal(x, y, z, dx, dy, h, r, palette);
  animate(name, {
    type: "colors",
    palette: [palette[0], palette[1], palette[4], palette[5]],
    pattern: "wave",
    speed: 0.65,
    glow: 0.45
  });
}

part("central", [24, 24, 16]);
crystal(24, 24, 16, 3, -2, 29, 5.3, violet);
animate("central", { type: "bob", axis: "z", speed: 1.6, amplitude: 1.5 });
animate("central", {
  type: "colors",
  palette: ["#a156df", "#ef6ac9", "#60e9ed", "#d4a0fa"],
  pattern: "pulse",
  speed: 1.4,
  glow: 0.8
});