← Asian3D assetfogon/katana-en-soporte
Katana en soporte
Drag to turn it// «Katana en soporte» · gpt-6-sol (medium)
// A display stand with two katanas: a black lacquered wooden stand with two horizontal racks, a long katana on top and a shorter one below, both with black scabbards, gold guards and handles wrapped in a red diamond pattern.
// Black lacquered two-tier katana stand
const black = "#171719";
const lacquer = "#272326";
const edge = "#403136";
const red = "#9e292b";
const brightRed = "#ce4940";
const gold = "#c99a43";
const lightGold = "#efd17a";
function foot(x0, x1) {
box(x0, 19, 0, x1, 34, 2, black);
box(x0 + 1, 19, 2, x1 - 1, 33, 3, lacquer);
box(x0, 19, 1, x1, 19, 1, gold);
box(x0 + 1, 20, 3, x1 - 1, 32, 3, edge);
}
foot(6, 17);
foot(32, 43);
// Low plinth connecting the feet
box(9, 24, 1, 40, 32, 3, black);
box(10, 24, 3, 39, 31, 3, lacquer);
box(10, 23, 2, 39, 23, 2, red);
box(11, 23, 1, 38, 23, 1, gold);
// Uprights and their gold-capped tops
for (const x of [12, 36]) {
box(x - 2, 25, 4, x + 2, 30, 31, black);
box(x - 1, 25, 5, x + 1, 25, 30, lacquer);
box(x - 2, 25, 5, x - 2, 25, 29, edge);
box(x - 2, 24, 4, x + 2, 30, 5, gold);
box(x - 2, 24, 30, x + 2, 30, 31, gold);
box(x - 1, 24, 32, x + 1, 29, 32, lightGold);
}
// Two horizontal lacquered rails, with red inlay and gilt edges
for (const z of [15, 26]) {
box(12, 26, z, 36, 30, z + 3, black);
box(13, 25, z + 1, 35, 25, z + 2, red);
box(14, 25, z + 3, 34, 28, z + 3, edge);
box(14, 25, z, 34, 25, z, gold);
// Small diamond crest at the center of each rail
set(24, 24, z + 1, lightGold);
set(23, 24, z + 2, gold);
set(25, 24, z + 2, gold);
set(24, 24, z + 3, lightGold);
}
// Cradles project toward the viewer from the uprights.
for (const z of [17, 28]) {
for (const x of [12, 36]) {
box(x - 2, 18, z, x + 2, 26, z + 1, black);
box(x - 2, 18, z + 1, x + 2, 20, z + 1, gold);
box(x - 2, 18, z + 2, x + 2, 18, z + 3, lacquer);
box(x - 1, 19, z + 2, x + 1, 23, z + 2, red);
}
}
// Each sword lies horizontally, with its decorated grip on the left.
function katana(handleStart, guardX, tipX, cz) {
const gripEnd = guardX - 1;
const sheathStart = guardX + 2;
// Rounded black grip, wider than the scabbard
box(handleStart + 1, 17, cz - 2, gripEnd, 21, cz + 2, black);
box(handleStart + 1, 16, cz - 1, gripEnd, 16, cz + 1, lacquer);
box(handleStart + 1, 18, cz + 2, gripEnd, 20, cz + 2, edge);
// Gold pommel
box(handleStart, 17, cz - 2, handleStart + 1, 21, cz + 2, gold);
box(handleStart, 18, cz - 1, handleStart, 20, cz + 1, lightGold);
// Red diagonal wrapping frames pale diamond-shaped openings.
for (let x = handleStart + 3; x < gripEnd; x += 3) {
set(x, 15, cz, "#eed3aa");
set(x - 1, 15, cz - 1, brightRed);
set(x - 1, 15, cz + 1, brightRed);
set(x + 1, 15, cz - 1, brightRed);
set(x + 1, 15, cz + 1, brightRed);
set(x, 15, cz - 2, red);
set(x, 15, cz + 2, red);
}
for (let x = handleStart + 2; x <= gripEnd; x += 3) {
set(x, 17, cz + 2, brightRed);
set(x + 1, 18, cz + 2, red);
}
// Thick gilt tsuba, seen edge-on but extending beyond the grip
box(guardX, 15, cz - 3, guardX + 1, 23, cz + 3, gold);
box(guardX, 16, cz - 2, guardX, 22, cz + 2, lightGold);
box(guardX, 17, cz - 1, guardX, 21, cz + 1, "#71432c");
box(guardX + 1, 17, cz - 1, guardX + 1, 21, cz + 1, "#76502d");
box(guardX + 2, 17, cz - 2, guardX + 2, 21, cz + 2, lightGold);
// Solid, subtly rounded black lacquer scabbard
box(sheathStart + 1, 17, cz - 1, tipX - 2, 21, cz + 1, black);
box(sheathStart + 1, 18, cz - 2, tipX - 3, 20, cz + 2, lacquer);
box(sheathStart + 1, 16, cz, tipX - 3, 16, cz, "#282a2b");
box(sheathStart + 2, 17, cz + 2, tipX - 4, 18, cz + 2, "#424346");
box(sheathStart + 3, 16, cz + 1, tipX - 5, 16, cz + 1, "#535052");
// Binding near the mouth and restrained gold fittings
for (const x of [sheathStart + 4, sheathStart + 6]) {
box(x, 16, cz - 1, x, 21, cz + 1, red);
set(x, 16, cz + 1, gold);
}
box(tipX - 3, 17, cz - 1, tipX - 1, 21, cz + 1, lacquer);
box(tipX - 1, 18, cz - 1, tipX, 20, cz + 1, gold);
set(tipX, 19, cz, lightGold);
}
katana(4, 15, 44, 31);
katana(8, 18, 41, 20);import { draw } from "./assets/voxel";
import { katanaEnSoporte } from "./assets/katana-en-soporte";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, katanaEnSoporte, 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 katana-en-soporte
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["katana-en-soporte"] })
# It lands in client/assets/katana-en-soporte.ts
# https://fogon.page/object/katana-en-soporte