← BásicoObjeto 3Dfogon/silla-windsor-v2
Silla Windsor
Arrastrá para girarlo// «Silla Windsor» · gpt-6-sol (medium)
// Windsor chair («Silla Windsor»). One of several variations of this object: follow the reference picture closely.
// Honey-colored oak Windsor chair.
const wood = {
light: "#edb579",
top: "#dfa365",
mid: "#c88d51",
side: "#ad713d",
dark: "#87552f",
grain: "#f2bd80"
};
function mottled(base, lighter, darker) {
const n = rand();
return n < 0.09 ? lighter : n > 0.92 ? darker : base;
}
function seatContains(x, y) {
if (y === 10) return x >= 15 && x <= 34;
if (y === 11) return x >= 12 && x <= 37;
if (y === 12) return x >= 10 && x <= 39;
if (y >= 13 && y <= 30) return x >= 9 && x <= 40;
if (y === 31) return x >= 10 && x <= 39;
if (y === 32) return x >= 11 && x <= 38;
if (y === 33) return x >= 13 && x <= 36;
if (y === 34) return x >= 17 && x <= 32;
return false;
}
// Solid, softly rounded saddle seat with a darker, thick outer edge.
for (let y = 10; y <= 34; y++) {
for (let x = 9; x <= 40; x++) {
if (!seatContains(x, y)) continue;
const edge = !seatContains(x - 1, y) || !seatContains(x + 1, y) ||
!seatContains(x, y - 1) || !seatContains(x, y + 1);
set(x, y, 18, mottled(wood.dark, wood.side, wood.dark));
set(x, y, 19, mottled(wood.side, wood.mid, wood.dark));
set(x, y, 20, mottled(wood.mid, wood.top, wood.side));
set(x, y, 21, edge
? mottled(wood.mid, wood.top, wood.side)
: mottled(wood.top, wood.light, wood.mid));
if (edge && y >= 13 && y <= 32) {
set(x, y, 22, mottled(wood.top, wood.light, wood.mid));
}
}
}
// Subtle short grain marks across the broad seat surface.
for (let i = 0; i < 115; i++) {
const x = 11 + Math.floor(rand() * 27);
const y = 12 + Math.floor(rand() * 20);
if (!seatContains(x, y) || !seatContains(x + 1, y)) continue;
if (rand() < 0.56) {
set(x, y, 21, rand() < 0.6 ? wood.light : wood.mid);
set(x + 1, y, 21, rand() < 0.6 ? wood.light : wood.mid);
} else {
set(x, y, 21, wood.grain);
}
}
// Rounded back edge of the seat, into which the spindles are fitted.
for (let x = 12; x <= 37; x++) {
const y = x < 16 || x > 33 ? 31 : 32;
set(x, y, 22, wood.side);
set(x, y, 23, x % 5 === 0 ? wood.light : wood.mid);
}
// Four slim, gently splayed legs.
function leg(topX, topY, dx, dy) {
for (let z = 0; z <= 19; z++) {
const t = (19 - z) / 19;
const x = Math.round(topX + dx * t);
const y = Math.round(topY + dy * t);
const width = z < 3 ? 3 : 2;
for (let a = 0; a < width; a++) {
for (let b = 0; b < 2; b++) {
set(x + a, y + b, z,
a === 0 && b === 0 ? wood.light :
a === width - 1 ? wood.side : wood.mid);
}
}
if (z === 3 || z === 11 || z === 12) {
set(x, y, z, wood.top);
set(x + 1, y, z, wood.dark);
}
}
}
leg(11, 12, -3, -3);
leg(37, 12, 3, -3);
leg(11, 32, -3, 3);
leg(37, 32, 3, 3);
// Low, slender stretchers: side rails and the transverse H-shaped brace.
function railX(x0, x1, y, z) {
for (let x = x0; x <= x1; x++) {
set(x, y, z, wood.side);
set(x, y, z + 1, x % 7 === 0 ? wood.light : wood.mid);
set(x, y + 1, z + 1, wood.dark);
}
}
function railY(x, y0, y1, z) {
for (let y = y0; y <= y1; y++) {
set(x, y, z, wood.side);
set(x, y, z + 1, y % 7 === 0 ? wood.light : wood.mid);
set(x + 1, y, z + 1, wood.dark);
}
}
railY(10, 11, 35, 8);
railY(39, 11, 35, 8);
railX(11, 39, 23, 9);
railX(10, 39, 10, 7);
railX(10, 39, 36, 7);
// A few turned collars just beneath the seat.
for (const [x, y] of [[11,12], [37,12], [11,32], [37,32]]) {
box(x, y, 15, x + 2, y + 1, 16, wood.side);
box(x, y, 16, x + 1, y, 16, wood.light);
}
// The thin upright spindles sit slightly behind the bow.
function bowHeight(x) {
const q = Math.max(0, 1 - Math.pow((x - 24.5) / 15, 2));
return Math.round(25 + 17 * Math.sqrt(q));
}
for (const x of [13, 16, 19, 22, 25, 28, 31, 34, 37]) {
const top = bowHeight(x) - 2;
for (let z = 23; z <= top; z++) {
set(x, 34, z, z % 8 === 0 ? wood.light : wood.mid);
set(x, 35, z, wood.side);
}
// Small turned bases and tenons.
box(x, 33, 23, x, 35, 24, wood.side);
set(x, 33, 24, wood.light);
set(x, 34, top, wood.light);
}
// Continuous, stepped steam-bent bow, including its descending sides.
const points = [[10,22], [10,27], [11,31]];
for (let x = 12; x <= 37; x++) points.push([x, bowHeight(x)]);
points.push([39,30], [39,22]);
for (let i = 0; i < points.length - 1; i++) {
const [x0, z0] = points[i];
const [x1, z1] = points[i + 1];
line(x0, 34, z0, x1, 34, z1, 0, wood.side);
line(x0, 33, z0, x1, 33, z1, 0, wood.top);
line(x0, 33, z0 + 1, x1, 33, z1 + 1, 0, wood.light);
}
// Crisp highlights along the crown and darker square ends at the seat.
for (let x = 19; x <= 30; x++) {
if (x % 3 !== 0) set(x, 33, bowHeight(x) + 1, wood.grain);
}
box(9, 32, 22, 11, 35, 25, wood.side);
box(9, 32, 24, 10, 33, 26, wood.top);
box(38, 32, 22, 40, 35, 25, wood.side);
box(38, 32, 24, 39, 33, 26, wood.top);import { draw } from "./assets/voxel";
import { sillaWindsorV2 } from "./assets/silla-windsor-v2";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, sillaWindsorV2, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add silla-windsor-v2
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["silla-windsor-v2"] })
# Queda en client/assets/silla-windsor-v2.ts
# https://fogon.page/object/silla-windsor-v2