fogón

← Asian3D assetfogon/tengu

Tengu

by fogonCC08999 blocks
TenguDrag to turn it
// «Tengu» · gpt-6-sol (medium)
// A cartoon tengu mountain spirit standing facing front: a red face with a very long red nose sticking forward (-y), fierce eyebrows, a small black cap, white and tan mountain monk robes, a feather fan in one hand, and two big black feathered wings on its back.

const C = {
  wing: "#17191f", wingMid: "#242832", wingLight: "#383d45",
  robe: "#eee5cf", robeLight: "#fff5df", robeShade: "#cbbd9d",
  tan: "#b79a72", tanDark: "#907452",
  red: "#b92924", redLight: "#dc4935", redDark: "#85201e",
  gold: "#d6aa48", goldLight: "#f2d178",
  black: "#202027", ink: "#17171c"
};

// Sandals and feet.
box(18, 18, 0, 22, 26, 2, C.tanDark);
box(26, 18, 0, 30, 26, 2, C.tanDark);
box(19, 19, 2, 22, 25, 6, C.black);
box(26, 19, 2, 29, 25, 6, C.black);
box(18, 17, 1, 22, 19, 2, C.gold);
box(26, 17, 1, 30, 19, 2, C.gold);

// Two separately pivoting, feathered wings, behind the shoulders.
function wing(name, pivotX, dir, speed) {
  part(name, [pivotX, 29, 31]);

  line(pivotX, 29, 31, pivotX + dir * 9, 31, 35, 2.5, C.wing);
  ellipsoid(pivotX + dir * 5, 30, 32, 6, 2, 4, C.wingMid);

  for (let i = 0; i < 9; i++) {
    const rootX = pivotX + dir * (3 + i * 0.55);
    const rootZ = 33 - i * 0.4;
    const tipX = pivotX + dir * (15 - i * 1.4);
    const tipZ = 39 - i * 3;
    const tipY = 31 + (i % 3);

    line(rootX, 30, rootZ, tipX, tipY, tipZ, 1.5,
      i % 3 === 0 ? C.wingMid : C.wing);
    line(rootX + dir, 29, rootZ, tipX - dir, tipY - 1, tipZ + 1,
      0, C.wingLight);
    sphere(tipX, tipY, tipZ, 0.9, C.wing);
  }

  line(pivotX, 28, 31, pivotX + dir * 10, 30, 34, 1.3, C.wingLight);
  animate(name, { type: "swing", axis: "y", speed, amplitude: 0.4 });
}
wing("leftWing", 17, -1, 4);
wing("rightWing", 31, 1, -4);

part("body", [24, 24, 20]);

// Broad, solid mountain-monk robe and flared lower hem.
ellipsoid(24, 23, 18, 9, 7, 12, C.robeShade);
for (let z = 7; z <= 20; z++) {
  const half = z < 11 ? 9 : z < 16 ? 8 : 7;
  box(24 - half, 17, z, 24 + half, 29, z, C.robe);
}
ellipsoid(24, 23, 25, 9, 7, 7, C.robe);
box(15, 17, 7, 33, 28, 8, C.tan);
box(16, 16, 8, 32, 17, 9, C.gold);

// Front robe panels, hems, and warm tan sash.
box(17, 16, 10, 23, 17, 21, C.robeLight);
box(25, 16, 10, 31, 17, 21, C.robeLight);
box(23, 15, 8, 25, 16, 20, C.tan);
box(23, 14, 9, 25, 15, 18, C.goldLight);
box(17, 15, 18, 31, 17, 20, C.tanDark);
box(18, 14, 19, 30, 15, 20, C.gold);
box(19, 15, 10, 20, 16, 17, C.tan);
box(28, 15, 10, 29, 16, 17, C.tan);

// Crossed collar frames the red neck.
line(17, 16, 29, 24, 14, 21, 1.4, C.robeLight);
line(31, 16, 29, 24, 13, 21, 1.4, C.robeLight);
line(18, 15, 29, 24, 13, 22, 0, C.gold);
line(30, 15, 29, 24, 12, 22, 0, C.tan);
box(22, 19, 28, 26, 25, 32, C.redDark);

// Sleeves and hands.
line(17, 22, 27, 12, 17, 21, 3.1, C.robe);
line(16, 19, 25, 12, 16, 21, 1, C.tan);
ellipsoid(12, 16, 20, 2, 2, 2, C.red);
line(31, 22, 27, 36, 15, 20, 3, C.robe);
line(33, 18, 23, 36, 14, 20, 1, C.tan);
ellipsoid(36, 14, 19, 2, 2, 2, C.redLight);

// Feather fan in the raised hand: dark handle, pale feathers, gold rim.
line(36, 13, 18, 37, 12, 24, 0.8, C.tanDark);
for (let i = 0; i < 7; i++) {
  const x = 33 + i * 1.8;
  const z = 29 + (3 - Math.abs(i - 3)) * 0.7;
  line(37, 12, 23, x, 11, z, 0.8,
    i % 2 ? C.robe : C.robeLight);
  sphere(x, 11, z, 0.8, C.robeLight);
}
line(33, 10, 29, 38, 10, 31, 0, C.gold);
line(38, 10, 31, 44, 10, 29, 0, C.gold);
sphere(37, 11, 23, 1, C.gold);

// Red face, ears, cheek planes, and fierce expression.
ellipsoid(24, 21, 35, 6, 5, 5, C.redDark);
ellipsoid(24, 17, 35, 5, 2.5, 4.2, C.red);
ellipsoid(19, 19, 35, 2, 2, 2.7, C.redLight);
ellipsoid(29, 19, 35, 2, 2, 2.7, C.redLight);
ellipsoid(17, 21, 35, 1.5, 2, 2.5, C.redDark);
ellipsoid(31, 21, 35, 1.5, 2, 2.5, C.redDark);

ellipsoid(20, 14, 36, 1.5, 0.8, 1.2, C.robeLight);
ellipsoid(28, 14, 36, 1.5, 0.8, 1.2, C.robeLight);
set(20, 13, 36, C.ink);
set(28, 13, 36, C.ink);
line(17, 13, 39, 22, 13, 37, 0.9, C.ink);
line(26, 13, 37, 31, 13, 39, 0.9, C.ink);
line(20, 13, 32, 23, 13, 31, 0, C.redDark);
line(25, 13, 31, 28, 13, 32, 0, C.redDark);
box(23, 13, 30, 25, 13, 30, C.ink);

// The unmistakable long tengu nose projects toward the viewer.
line(24, 15, 35, 24, 6, 35, 1.4, C.red);
line(24, 13, 36, 24, 7, 36, 0, C.redLight);
sphere(24, 5, 35, 1.5, C.redLight);
set(24, 4, 35, C.red);

// Small black tokin cap with a lacquer-and-gold band.
ellipsoid(24, 21, 40, 4, 3, 1.5, C.ink);
box(21, 19, 41, 27, 24, 42, C.black);
box(22, 19, 40, 26, 19, 40, C.gold);
box(23, 20, 43, 25, 23, 43, C.black);
set(24, 19, 41, C.goldLight);

// Sparse woven flecks keep the large robe surfaces lively.
forEach((x, y, z, color) => {
  if (color === C.robe && y <= 18 && z >= 10 && z <= 27 && rand() < 0.035)
    set(x, y, z, C.robeLight);
});