← Whole house3D assetfogon/planta-de-interior
Planta de interior
Drag to turn it// «Planta de interior» · gpt-6-sol (medium)
// A big indoor plant: a monstera with large split green leaves on long stems, in a round white ceramic pot on a small wooden stand.
// Small wooden plant stand
const honey = "#bb8048", walnut = "#825333", woodLight = "#d7a166";
for (const x of [16, 30]) {
for (const y of [16, 30]) {
box(x, y, 0, x + 2, y + 2, 10, walnut);
box(x, y, 1, x + 2, y + 2, 3, honey);
box(x, y, 9, x + 2, y + 2, 10, woodLight);
}
}
box(18, 17, 7, 30, 18, 9, honey);
box(18, 30, 7, 30, 31, 9, walnut);
box(17, 18, 7, 18, 30, 9, honey);
box(30, 18, 7, 31, 30, 9, walnut);
// Rounded, gently tapered ceramic pot
for (let z = 7; z <= 19; z++) {
const r = 6.4 + (z - 7) * 0.14;
for (let x = 14; x <= 34; x++) {
for (let y = 14; y <= 34; y++) {
const d = Math.hypot(x - 24, y - 24);
if (d > r) continue;
const shade = y < 21 ? "#ffffff" : y > 28 ? "#dbe2df" : "#f1f3ec";
set(x, y, z, z < 9 ? "#d9dfda" : shade);
}
}
}
cylinder(24, 24, 19, 6.8, 1, "#654634");
for (let x = 15; x <= 33; x++) {
for (let y = 15; y <= 33; y++) {
const d = Math.hypot(x - 24, y - 24);
if (d >= 6.7 && d <= 8.3) {
set(x, y, 19, "#ffffff");
set(x, y, 20, y < 24 ? "#ffffff" : "#edf0ec");
}
}
}
// Stems curve outward from the soil to each leaf.
const leaves = [
{base:[22,27,27], tip:[7,27,37], side:[-0.55,0,-0.83], width:8, seed:0},
{base:[26,27,27], tip:[41,27,39], side:[-0.62,0,0.78], width:8, seed:1},
{base:[24,26,28], tip:[24,28,44], side:[1,0,0], width:7.5, seed:2},
{base:[21,20,25], tip:[5,12,29], side:[-0.25,0,-0.97], width:7, seed:3},
{base:[27,20,25], tip:[42,12,30], side:[-0.32,0,0.95], width:7, seed:4},
{base:[24,19,27], tip:[23,10,40], side:[1,0,0.08], width:8, seed:5}
];
for (const leaf of leaves) {
const [bx, by, bz] = leaf.base;
const [tx, ty, tz] = leaf.tip;
line(24, 24, 19, 24, 24, 23, 1, "#527b3b");
line(24, 24, 22, bx, by, bz, 1, "#648b43");
line(bx, by, bz, tx, ty, tz, 0, "#638d42");
}
// Broad heartlike blades with open splits and little inner fenestrations.
for (const leaf of leaves) {
const [bx, by, bz] = leaf.base;
const [tx, ty, tz] = leaf.tip;
const [sx, sy, sz] = leaf.side;
for (let i = 0; i <= 55; i++) {
const u = i / 55;
const broadness = Math.pow(Math.sin(Math.PI * u), 0.72);
const width = leaf.width * broadness * (1.08 - 0.18 * u);
for (let j = -17; j <= 17; j++) {
const s = j / 17;
const a = Math.abs(s);
// Three slits enter from each outside edge.
let split = false;
if (a > 0.45) {
for (const center of [0.32, 0.51, 0.70]) {
if (Math.abs(u - center) < 0.012 + 0.115 * (a - 0.45)) split = true;
}
}
// Small oval holes remain completely inside the blade.
const hole =
[0.39, 0.59].some(center =>
Math.pow((u - center) / 0.045, 2) +
Math.pow((a - 0.43) / 0.13, 2) < 1
);
if (split || hole) continue;
const x = bx + (tx - bx) * u + sx * width * s;
const y = by + (ty - by) * u + sy * width * s;
const z = bz + (tz - bz) * u + sz * width * s;
const bright = z > 32 || (leaf.seed % 3 === 0 && u > 0.45);
const color = rand() < 0.055 ? "#81ae54"
: bright ? "#609b49" : "#478a42";
set(x, y + 1, z, "#36763b");
set(x, y, z, color);
}
}
// Raised central vein and short, pale branching veins.
for (let i = 1; i < 24; i++) {
const u = i / 25;
const x = bx + (tx - bx) * u;
const y = by + (ty - by) * u - 1;
const z = bz + (tz - bz) * u;
set(x, y, z, "#a0c76a");
}
for (const u of [0.29, 0.47, 0.65]) {
const w = leaf.width * Math.pow(Math.sin(Math.PI * u), 0.72);
for (const sign of [-1, 1]) {
line(
bx + (tx - bx) * u,
by + (ty - by) * u - 1,
bz + (tz - bz) * u,
bx + (tx - bx) * (u + 0.08) + sx * w * sign * 0.62,
by + (ty - by) * (u + 0.08) + sy * w * sign * 0.62 - 1,
bz + (tz - bz) * (u + 0.08) + sz * w * sign * 0.62,
0,
"#82b65b"
);
}
}
}import { draw } from "./assets/voxel";
import { plantaDeInterior } from "./assets/planta-de-interior";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, plantaDeInterior, 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 planta-de-interior
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["planta-de-interior"] })
# It lands in client/assets/planta-de-interior.ts
# https://fogon.page/object/planta-de-interior