← Asian3D assetfogon/tetera-de-hierro
Tetera de hierro
Drag to turn it// «Tetera de hierro» · gpt-6-sol (medium)
// A Japanese cast iron teapot (tetsubin): a round squat body of dark charcoal iron covered in small raised dots, a curved spout facing front, a lid with a little knob, and an arched iron handle on top.
// Cast-iron tetsubin: the spout points toward -y.
const iron = "#292b2b";
const shadow = "#1b1e1e";
const raised = "#424342";
const bronze = "#806241";
const gold = "#c49a59";
// Three squat feet.
for (const [x, y] of [[14, 17], [34, 17], [24, 36]]) {
ellipsoid(x, y, 3, 3.5, 3.5, 3, shadow);
ellipsoid(x, y, 4, 3.2, 3.2, 2, "#383633");
}
// Rounded, solid iron body.
ellipsoid(24, 26, 15, 17, 15, 12, iron);
forEach((x, y, z, color) => {
if (color !== iron) return;
const exposed = !get(x, y - 1, z) || !get(x, y, z + 1);
if (!exposed) return;
if (z > 20) set(x, y, z, rand() < 0.13 ? "#444442" : "#353837");
else if (y < 21 && rand() < 0.10) set(x, y, z, "#343635");
else if (rand() < 0.025) set(x, y, z, "#373936");
});
// Even rows of raised cast-iron hobnails, staggered around the body.
for (let z = 7; z <= 24; z += 3) {
const level = (z - 15) / 12;
const width = Math.sqrt(Math.max(0, 1 - level * level));
const count = Math.round(37 * width);
for (let i = 0; i < count; i++) {
const a = 2 * Math.PI * (i + (z % 2 ? 0.5 : 0)) / count;
const x = Math.round(24 + 17.5 * width * Math.cos(a));
const y = Math.round(26 + 15.5 * width * Math.sin(a));
sphere(x, y, z, 0.8, y < 25 ? "#50504a" : raised);
if (y < 20 && rand() < 0.35) set(x, y - 1, z, "#626055");
}
}
// Sturdy handle lugs and a tall, unbroken arched iron handle.
for (const x of [10, 38]) {
ellipsoid(x, 27, 25, 3, 3, 3, shadow);
set(x, 24, 25, bronze);
}
let previous = null;
for (let i = 0; i <= 36; i++) {
const t = Math.PI - i * Math.PI / 36;
const x = 24 + 14 * Math.cos(t);
const z = 27 + 17 * Math.sin(t);
if (previous) line(previous[0], 28, previous[1], x, 28, z, 1.8, shadow);
previous = [x, z];
}
// A restrained warm highlight follows the front edge of the upper arch.
previous = null;
for (let i = 7; i <= 29; i++) {
const t = Math.PI - i * Math.PI / 36;
const x = 24 + 14 * Math.cos(t);
const z = 27 + 17 * Math.sin(t);
if (previous) line(previous[0], 26.7, previous[1], x, 26.7, z, 0, "#615645");
previous = [x, z];
}
// Curving, upward-pointing pouring spout.
line(24, 12, 15, 24, 7, 18, 3.7, iron);
line(24, 7, 18, 24, 4, 22, 2.8, "#333534");
ellipsoid(24, 3, 23, 3.5, 3, 1.4, bronze);
ellipsoid(24, 3, 23, 2.5, 2, 1.4, "#343634");
ellipsoid(24, 3, 24, 1.6, 1.3, 0.7, shadow);
// Fitted lid, rim, and small finial.
cylinder(24, 26, 26, 10, 2, shadow);
cylinder(24, 26, 27, 9, 1, bronze);
ellipsoid(24, 26, 28, 8.5, 7.5, 2, "#343635");
cylinder(24, 26, 29, 3, 1, shadow);
sphere(24, 26, 31, 2.3, bronze);
sphere(24, 26, 32, 1.4, gold);import { draw } from "./assets/voxel";
import { teteraDeHierro } from "./assets/tetera-de-hierro";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, teteraDeHierro, 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 tetera-de-hierro
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["tetera-de-hierro"] })
# It lands in client/assets/tetera-de-hierro.ts
# https://fogon.page/object/tetera-de-hierro