fogón

← Monstruos y enemigosObjeto 3Dfogon/troll

Troll

de fogonCC019442 bloques
TrollArrastrá para girarlo
// «Troll» · gpt-6-sol (medium)
// A big lumpy cartoon cave troll facing -y: grey-blue stony skin with mossy green patches, a small head on huge shoulders, a big round nose, tiny eyes and an underbite with two teeth, very long arms that reach the ground with huge fists, short thick legs and a fur loincloth.

const dark = "#354b5d";
const mid = "#547185";
const light = "#7897a7";
const highlight = "#a1b9bd";
const moss = "#587c48";
const mossLight = "#91ad61";
const furDark = "#493d3b";
const fur = "#785c4b";
const furLight = "#a3825f";

function skinBlob(x, y, z, rx, ry, rz) {
  ellipsoid(x, y, z, rx, ry, rz, dark);
  ellipsoid(x, y, z + 1, rx - 0.7, ry - 0.7, rz - 1, mid);
  ellipsoid(x - 0.5, y - 0.5, z + 2, rx - 1.8, ry - 1.8, rz - 2.5, light);
}

function mossClump(x, y, z) {
  ellipsoid(x, y, z, 2.4, 1.2, 1.3, moss);
  sphere(x - 1, y - 0.5, z + 1, 0.8, mossLight);
  sphere(x + 1, y, z + 0.5, 0.7, mossLight);
}

// Short, heavy legs.
for (const leg of [
  { name: "leftLeg", x: 17, speed: 2 },
  { name: "rightLeg", x: 31, speed: -2 }
]) {
  part(leg.name, [leg.x, 24, 14]);
  skinBlob(leg.x, 25, 9, 5.7, 5.6, 8);
  ellipsoid(leg.x, 20, 3, 6.2, 8, 3.2, dark);
  ellipsoid(leg.x, 19, 4, 5.7, 7.2, 2.5, mid);
  ellipsoid(leg.x, 17, 3, 4.6, 4.3, 1.7, light);

  for (let dx = -3; dx <= 3; dx += 3) {
    ellipsoid(leg.x + dx, 13, 2, 1.2, 2, 0.8, highlight);
  }

  animate(leg.name, {
    type: "swing",
    axis: "x",
    speed: leg.speed,
    amplitude: 0.3
  });
}

part("body");

// Huge shoulders and a forward-projecting belly.
skinBlob(24, 25, 22, 14, 10, 13);
skinBlob(24, 24, 30, 17, 10, 7);
skinBlob(24, 19, 19, 11.5, 9, 9);
ellipsoid(24, 17, 16, 9, 4, 3, mid);

// Uneven rocky lumps around the silhouette.
const bumps = [
  [10, 23, 31, 2.5], [38, 25, 30, 2.8],
  [11, 29, 23, 2], [36, 31, 24, 2.3],
  [15, 31, 30, 2], [32, 31, 29, 2]
];
for (const b of bumps) {
  sphere(b[0], b[1], b[2], b[3], mid);
  sphere(b[0] - 0.5, b[1] - 0.5, b[2] + 0.8, b[3] * 0.55, light);
}

// Small stone flecks across the belly.
for (let i = 0; i < 55; i++) {
  const x = 14 + rand() * 20;
  const z = 15 + rand() * 15;
  const q = ((x - 24) / 12) ** 2 + ((z - 22) / 12) ** 2;
  if (q < 0.83) {
    const y = 24 - 10 * Math.sqrt(1 - q);
    set(x, y - 0.5, z, rand() < 0.6 ? light : dark);
  }
}

const shoulderMoss = [
  [13, 17, 34], [16, 19, 36], [35, 18, 35],
  [38, 22, 33], [12, 29, 33], [34, 31, 33]
];
for (const p of shoulderMoss) {
  mossClump(p[0], p[1], p[2]);
}

// Ragged fur belt and loincloth.
ellipsoid(24, 18, 14, 11, 5, 2.6, furDark);
box(15, 13, 14, 33, 14, 16, fur);
for (let x = 15; x <= 33; x += 3) {
  box(x, 12, 16, x + 1, 12, 16, furLight);
}

ellipsoid(24, 13, 11, 8, 2.5, 5.3, furDark);
ellipsoid(24, 12, 11, 7, 1.5, 4.6, fur);
for (let x = 18; x <= 30; x += 3) {
  const tipX = x + (x < 24 ? -1 : 1);
  const tipZ = 6 + Math.floor(rand() * 3);
  line(x, 11, 11, tipX, 11, tipZ, 0.8, furLight);
}
for (const x of [17, 31]) {
  line(x, 15, 13, x, 17, 6, 1.1, furDark);
  sphere(x, 17, 6, 1.1, furLight);
}

// Small head, ears, brow, and glowing eyes.
skinBlob(24, 19, 37, 6.7, 6, 5.6);
for (const x of [17, 31]) {
  ellipsoid(x, 20, 36, 3, 2.4, 2.5, dark);
  sphere(x + (x < 24 ? -1 : 1), 19, 37, 1.4, mid);
}
ellipsoid(24, 15, 40, 4.5, 2.8, 1.5, light);

for (const x of [21, 27]) {
  ellipsoid(x, 13, 38, 1.8, 0.8, 1.6, "#263941");
  sphere(x, 12, 38, 0.9, "#edee66");
  set(x, 11, 38, "#fff9ad");
  box(x - 2, 12, 40, x + 1, 13, 40, dark);
}

// Round nose and protruding underbite with two blunt teeth.
ellipsoid(24, 10, 35, 3.4, 3.6, 2.8, mid);
ellipsoid(23, 8, 36, 2, 1.7, 1.4, light);
set(22, 7, 34, "#263941");
set(26, 7, 34, "#263941");

ellipsoid(24, 12, 31, 5.2, 3.1, 2.1, dark);
ellipsoid(24, 10, 30, 5, 2.2, 1.5, mid);
box(21, 8, 32, 27, 9, 32, "#283842");
for (const x of [21, 27]) {
  box(x, 7, 32, x + 1, 8, 33, "#f3e8bc");
  set(x, 7, 34, "#f3e8bc");
}
mossClump(29, 17, 41);

// Long arms with enormous ground-reaching fists.
for (const arm of [
  { name: "leftArm", side: -1, speed: 2 },
  { name: "rightArm", side: 1, speed: -2 }
]) {
  const shoulder = 24 + arm.side * 14;
  const hand = 24 + arm.side * 17;

  part(arm.name, [shoulder, 23, 31]);
  skinBlob(shoulder, 23, 29, 5.5, 5.2, 6);
  skinBlob(hand, 22, 23, 4.5, 4.6, 8);
  sphere(hand, 21, 18, 4.4, mid);
  skinBlob(hand, 19, 13, 4.3, 4.2, 8);

  ellipsoid(hand, 17, 5, 5, 5.3, 5, dark);
  ellipsoid(hand, 16, 6, 4.6, 4.8, 4, mid);
  ellipsoid(hand, 14, 7, 3.8, 2.6, 2.3, light);
  ellipsoid(hand - arm.side * 4, 17, 6, 2.2, 2.4, 2.8, mid);

  for (let i = -2; i <= 2; i += 2) {
    sphere(hand + i, 13, 4, 1.25, mid);
    set(hand + i, 12, 4, highlight);
  }

  mossClump(shoulder + arm.side, 19, 33);
  mossClump(hand, 18, 16);

  animate(arm.name, {
    type: "swing",
    axis: "x",
    speed: arm.speed,
    amplitude: 0.3
  });
}

part("body");