fogón

← Medieval3D assetfogon/princesa

Princesa

by fogonCC016912 blocks
PrincesaDrag to turn it
// «Princesa» · gpt-6-sol (medium)
// A chunky cartoon medieval princess: a wide bell-shaped pink dress with white lace trim, a big round head with long golden braided hair, black dot eyes, pink cheeks and a small silver tiara.

// Chunky storybook princess, facing -y.
const pink = ["#b94f79", "#d96893", "#eb83aa", "#f39bbb"];
const cream = "#fff2e8";
const laceShadow = "#e5d4d0";
const gold = ["#ad751e", "#d8992b", "#f2bc48", "#ffdb75"];
const skin = "#f5c6a7";

function skirtRadius(z) {
  const t = Math.min(z, 22) / 22;
  return [18 - 10 * Math.pow(t, 1.35), 14 - 7 * Math.pow(t, 1.35)];
}
function frontY(x, z) {
  const [rx, ry] = skirtRadius(z);
  const dx = (x - 24) / rx;
  return Math.round(24 - ry * Math.sqrt(Math.max(0, 1 - dx * dx)));
}

// Solid, wide bell skirt.
for (let z = 0; z <= 22; z++) {
  const [rx, ry] = skirtRadius(z);
  for (let x = Math.ceil(24 - rx); x <= Math.floor(24 + rx); x++) {
    for (let y = Math.ceil(24 - ry); y <= Math.floor(24 + ry); y++) {
      const d = ((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2;
      if (d > 1) continue;
      let c = z < 2 ? cream : pink[z < 5 ? 0 : z < 13 ? 1 : 2];
      if (z >= 5 && d < 0.84 && y < 24) c = pink[3];
      if (z >= 5 && rand() < 0.045) c = pink[1];
      set(x, y, z, c);
    }
  }
}

// Scalloped lace along the front hem and a darker ribbon above it.
for (let x = 8; x <= 40; x++) {
  for (let z = 2; z <= 5; z++) {
    const [rx] = skirtRadius(z);
    if (Math.abs(x - 24) > rx - 1) continue;
    const y = frontY(x, z) - 1;
    if (z === 2 || (z === 3 && x % 4 !== 0) || (z === 4 && x % 4 === 2))
      set(x, y, z, cream);
    if (z === 5) set(x, y, z, "#a83e68");
  }
}
// Pleated front panels and tiny embroidered flowers.
for (const x of [15, 19, 29, 33]) {
  for (let z = 7; z <= 17; z++) {
    const [rx] = skirtRadius(z);
    if (Math.abs(x - 24) < rx - 1)
      set(x, frontY(x, z) - 1, z, z % 5 === 0 ? "#ffe0b4" : "#f5a8bf");
  }
}
for (const x of [13, 24, 35]) {
  const z = x === 24 ? 10 : 8;
  const y = frontY(x, z) - 2;
  set(x, y, z, "#ffe3aa");
  set(x - 1, y, z, cream);
  set(x + 1, y, z, cream);
  set(x, y, z + 1, cream);
  set(x, y, z - 1, cream);
}

// Fitted bodice and ivory collar.
ellipsoid(24, 24, 25, 8, 6, 6, "#d4658e");
box(20, 17, 23, 28, 18, 27, "#e77da2");
box(21, 16, 23, 27, 16, 24, "#a8476b");
for (let x = 19; x <= 29; x++) {
  const z = 30 - Math.abs(x - 24) / 2;
  set(x, 18, z, cream);
}
box(22, 16, 26, 26, 16, 27, "#315184");
box(23, 15, 27, 25, 15, 28, "#f4c859");
set(24, 14, 27, "#ab354b");

// Golden hair behind the head, with long chunky braided pigtails.
ellipsoid(24, 25, 36, 9, 8, 9, gold[1]);
box(17, 27, 27, 31, 31, 38, gold[0]);
for (const side of [-1, 1]) {
  const x = 24 + side * 10;
  for (let z = 23; z <= 38; z += 3) {
    const drift = z < 29 ? side : 0;
    ellipsoid(x + drift, 19 + (z % 2), z, 2.5, 2.5, 2.4,
              gold[(Math.floor(z / 3) % 2) ? 2 : 1]);
    set(x + drift - 1, 16, z + 1, gold[3]);
  }
  ellipsoid(x + side, 19, 22, 2, 2, 2, gold[2]);
  box(x + side - 1, 17, 19, x + side + 1, 20, 20, "#b7476e");
}

// Big round face.
ellipsoid(24, 23, 35, 8, 7, 8, skin);
ellipsoid(24, 22, 38, 7, 6, 4, "#ffd6b5");

// Hair framing the face and a swept, blocky fringe.
for (let z = 34; z <= 41; z++) {
  set(16, 18, z, gold[2]);
  set(32, 18, z, gold[1]);
}
box(19, 16, 41, 29, 19, 43, gold[1]);
box(18, 16, 39, 22, 17, 41, gold[2]);
box(23, 16, 40, 30, 17, 42, gold[2]);
box(21, 15, 39, 23, 16, 40, gold[3]);

// Simple face: black dot eyes, rosy cheeks, tiny smile.
for (const x of [21, 27]) {
  box(x, 15, 35, x + 1, 15, 36, "#25202b");
  set(x, 14, 36, "#25202b");
  set(x + 1, 14, 36, "#25202b");
  set(x, 14, 37, "#fff9ed");
}
for (const x of [18, 29]) {
  box(x, 16, 32, x + 1, 16, 33, "#ec91a0");
}
set(24, 14, 33, "#d99c89");
box(23, 15, 31, 25, 15, 31, "#ba6170");
set(24, 14, 30, "#f9a7a7");

// Small silver tiara with three points and a blue jewel.
box(20, 16, 43, 28, 18, 44, "#a6b1bc");
box(21, 15, 44, 27, 16, 44, "#edf4f4");
box(21, 16, 45, 22, 17, 45, "#d3dfe2");
box(26, 16, 45, 27, 17, 45, "#d3dfe2");
box(23, 16, 45, 25, 17, 46, "#e4edef");
set(24, 15, 44, "#39699c");

// Independent, gently swinging arms.
for (const side of [-1, 1]) {
  const x = 24 + side * 9;
  const name = side < 0 ? "leftArm" : "rightArm";
  part(name, [x, 22, 28]);
  ellipsoid(x, 22, 26, 3.5, 3.5, 4, "#e77da2");
  ellipsoid(x + side * 1.5, 21, 24, 2.4, 2.5, 3, "#f19abd");
  box(x + side * 2 - 1, 18, 21, x + side * 2 + 1, 22, 22, cream);
  ellipsoid(x + side * 2, 20, 19, 2, 2, 2.5, skin);
  animate(name, {
    type: "swing", axis: "x", speed: side < 0 ? 2 : -2, amplitude: 0.25
  });
}
part("body", [24, 24, 0]);