← Whole house3D assetfogon/cortinas
Cortinas
Drag to turn it// «Cortinas» · gpt-6-sol (medium)
// A window with curtains: a white-framed window with four panes showing blue sky, on a short wall piece, with two long flowing curtains in coral fabric gathered to the sides with tiebacks, hanging from a wooden rod.
const cream = "#f7e9d4";
const creamLight = "#fff2df";
const creamShade = "#e9d8bf";
const white = "#fffdf5";
const trimShade = "#dce4e5";
const honey = "#bd8449";
const walnut = "#875535";
// Short, warm wall piece.
box(3, 23, 0, 44, 28, 35, cream);
for (let x = 3; x <= 44; x++)
for (let z = 3; z <= 35; z++)
if (rand() < 0.075) set(x, 22, z, rand() < 0.5 ? creamLight : creamShade);
box(3, 22, 0, 44, 28, 2, honey);
box(3, 21, 2, 44, 23, 3, creamLight);
box(3, 22, 34, 44, 28, 35, creamLight);
// Four panes: a soft blue view with a few little clouds.
box(10, 20, 9, 38, 24, 33, "#a9dcef");
for (let z = 11; z <= 31; z++) {
const blue = z > 23 ? "#95d5ee" : z > 16 ? "#a9def0" : "#bce8f2";
box(12, 19, z, 36, 20, z, blue);
}
for (const [x, z] of [[17, 27], [29, 25], [20, 15], [32, 14]]) {
box(x - 2, 18, z, x + 2, 18, z, "#f9fdfb");
box(x - 1, 18, z + 1, x + 1, 18, z + 1, white);
}
// Thick white frame, central mullions and projecting sill.
box(9, 17, 8, 11, 23, 33, trimShade);
box(37, 17, 8, 39, 23, 33, trimShade);
box(9, 17, 31, 39, 23, 33, trimShade);
box(9, 17, 8, 39, 23, 10, trimShade);
box(10, 16, 10, 11, 19, 32, white);
box(37, 16, 10, 38, 19, 32, white);
box(10, 16, 31, 38, 19, 32, white);
box(10, 16, 9, 38, 19, 10, white);
box(23, 16, 10, 25, 21, 31, white);
box(11, 16, 19, 37, 21, 21, white);
box(8, 15, 7, 40, 23, 8, white);
box(8, 15, 7, 40, 16, 7, trimShade);
// Wooden curtain rod and wall brackets.
box(10, 17, 34, 12, 23, 36, walnut);
box(36, 17, 34, 38, 23, 36, walnut);
cylinder(3, 14, 37, 2, 42, honey, "x");
line(4, 12, 38, 44, 12, 38, 0, "#d9a366");
sphere(3, 14, 37, 2, walnut);
sphere(45, 14, 37, 2, walnut);
set(2, 14, 37, "#d6a16b");
set(46, 14, 37, "#d6a16b");
// Long coral curtains: pinched at the tiebacks and flared at the floor.
for (let z = 1; z <= 35; z++) {
const pinch = Math.max(0, 1 - Math.abs(z - 17) / 17);
const leftOuter = z < 8 ? 4 : 5;
const leftInner = Math.round(16 - 5 * pinch + (z < 8 ? 1 : 0));
const rightInner = 48 - leftInner;
const rightOuter = 48 - leftOuter;
for (const [a, b, side] of [
[leftOuter, leftInner, "left"],
[rightInner, rightOuter, "right"]
]) {
for (let x = a; x <= b; x++) {
const fold = side === "left" ? x - a : b - x;
const front = 11 + (fold % 4 === 1 ? 0 : fold % 4 === 3 ? 2 : 1);
const back = 16;
let color = fold % 4 === 1 ? "#ffad98"
: fold % 4 === 3 ? "#d96e67"
: "#f18b7c";
if (z < 4) color = fold % 4 === 1 ? "#f79b87" : "#dc746b";
if (rand() < 0.035) color = "#f9a08c";
box(x, front, z, x, back, z, color);
if (front === 11 && z > 4 && z < 34)
set(x, 10, z, "#ffb29e");
}
}
}
// Plump gathered headings and small golden rod rings.
for (const x of [6, 9, 12, 15, 33, 36, 39, 42]) {
box(x, 11, 34, x + 1, 16, 35, "#f6a08d");
box(x, 11, 36, x + 1, 15, 36, "#e8bb75");
set(x, 10, 36, "#f7d697");
}
// Mustard tiebacks crossing the pinched fabric.
for (const [a, b] of [[5, 12], [36, 43]]) {
box(a, 9, 16, b, 12, 17, "#dbab58");
box(a + 1, 8, 17, b - 1, 8, 17, "#ffe1a0");
box(a, 10, 15, a + 1, 12, 18, walnut);
box(b - 1, 10, 15, b, 12, 18, walnut);
}
// Tiny folds at the curtain hems.
for (const x of [6, 10, 14, 34, 38, 42])
box(x, 10, 1, x, 12, 3, "#ffb09b");import { draw } from "./assets/voxel";
import { cortinas } from "./assets/cortinas";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, cortinas, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add cortinas
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["cortinas"] })
# It lands in client/assets/cortinas.ts
# https://fogon.page/object/cortinas