← Asian3D assetfogon/tambor-taiko
Tambor taiko
Drag to turn it// «Tambor taiko» · gpt-6-sol (medium)
// A big Japanese taiko drum on a wooden stand: a fat barrel-shaped body of dark red wood with rows of brass studs around both skins, the cream drum skin facing front (-y), a black tomoe swirl painted on it, and two drumsticks resting on the stand.
const cx = 24, cz = 27;
// Low lacquered stand and broad feet.
const darkWood = "#43251e";
const redWood = "#792b25";
box(5, 13, 0, 15, 40, 2, darkWood);
box(33, 13, 0, 43, 40, 2, darkWood);
box(7, 12, 2, 41, 15, 5, redWood);
box(8, 38, 2, 40, 40, 5, darkWood);
box(9, 13, 5, 39, 14, 5, "#bd8540");
for (const x of [10, 38]) {
line(x, 17, 3, x, 22, 20, 2, redWood);
line(x, 36, 3, x, 29, 20, 2, darkWood);
box(x - 2, 21, 16, x + 2, 30, 20, "#67241f");
box(x - 2, 21, 20, x + 2, 30, 21, "#a74b32");
for (const y of [18, 35]) {
box(x - 2, y - 1, 3, x + 2, y + 1, 4, "#a95234");
set(x, y - 2, 7, "#d5a34e");
}
}
// Solid barrel, slightly wider at its middle.
for (let y = 11; y <= 37; y++) {
const u = (y - 11) / 26;
const radius = 15.25 + 2.25 * Math.sin(Math.PI * u);
for (let x = 6; x <= 42; x++) {
for (let z = 9; z <= 45; z++) {
const dx = x - cx, dz = z - cz;
const d = Math.hypot(dx, dz);
if (d > radius) continue;
let color = "#782a26";
if (d > radius - 2.2) {
color = dz > 7 ? "#a74332" : dz < -7 ? "#58201e" : "#8d3029";
if (rand() < 0.12) color = dz > 0 ? "#b44b36" : "#a03b2d";
// Fine seams between the curved wooden staves.
const angle = Math.atan2(dz, dx) + Math.PI;
if ((angle * 18 / (2 * Math.PI)) % 1 < 0.075)
color = "#64221f";
// Binding hoops near both drumheads.
if (y === 12 || y === 36) color = "#49201d";
if (y === 13 || y === 35) color = "#bb7938";
if (y === 14 || y === 34) color = "#713027";
}
set(x, y, z, color);
}
}
}
// A narrow dark-red end cap and the warm cream front skin.
for (let x = 7; x <= 41; x++) {
for (let z = 10; z <= 44; z++) {
const d = Math.hypot(x - cx, z - cz);
if (d <= 16.1) {
set(x, 10, z, "#672420");
if (d <= 14.35) {
let skin = "#f3ddb2";
if (z > 33) skin = "#fae9c6";
if (z < 20) skin = "#dfc494";
if (rand() < 0.11) skin = "#ead0a2";
set(x, 9, z, skin);
}
if (d >= 14.15) {
set(x, 8, z, d < 14.65 ? "#d9a357" : "#61221e");
if (d > 15.75) set(x, 8, z, "#ad6232");
}
}
// Far skin and its visible upper rim.
if (d <= 14.4) set(x, 38, z, "#ddc59c");
if (d >= 14.2 && d <= 16.1) set(x, 39, z, "#783027");
}
}
// Three bold, curling tomoe painted directly onto the front skin.
function inkDisk(px, pz, r) {
for (let x = Math.floor(px - r); x <= Math.ceil(px + r); x++) {
for (let z = Math.floor(pz - r); z <= Math.ceil(pz + r); z++) {
if (Math.hypot(x - px, z - pz) <= r &&
Math.hypot(x - cx, z - cz) < 13.3)
set(x, 8, z, "#211c1d");
}
}
}
for (let k = 0; k < 3; k++) {
const a = Math.PI / 2 + k * 2 * Math.PI / 3;
inkDisk(cx + 6.3 * Math.cos(a), cz + 6.3 * Math.sin(a), 3.0);
for (let i = 0; i <= 32; i++) {
const t = i / 32;
const angle = a + 1.75 * t;
const dist = 6.2 - 5.35 * t;
inkDisk(cx + dist * Math.cos(angle),
cz + dist * Math.sin(angle),
2.25 * (1 - t) + 0.35);
}
}
// Two rows of raised brass tacks encircle each head.
for (let i = 0; i < 40; i++) {
const a = 2 * Math.PI * i / 40;
const x1 = Math.round(cx + 15.1 * Math.cos(a));
const z1 = Math.round(cz + 15.1 * Math.sin(a));
set(x1, 7, z1, "#d39a48");
if (i % 2 === 0) set(x1, 6, z1, "#f2c46a");
const x2 = Math.round(cx + 15.9 * Math.cos(a + 0.06));
const z2 = Math.round(cz + 15.9 * Math.sin(a + 0.06));
set(x2, 10, z2, "#dca24e");
set(x2, 39, z2, "#ba7939");
}
// Small gold fittings on the stand.
for (const x of [10, 38]) {
for (const y of [22, 29]) {
set(x - 2, y, 18, "#d8a24d");
set(x + 2, y, 18, "#d8a24d");
}
}
// Two pale wooden bachi resting across the front crossbeam.
line(11, 9, 8, 36, 9, 11, 1, "#d7aa6e");
line(12, 7, 11, 37, 8, 7, 1, "#e7bd82");
for (const [x, y, z] of [[11, 9, 8], [12, 7, 11]]) {
sphere(x, y, z, 1.5, "#b87943");
}
for (const [x, y, z] of [[36, 9, 11], [37, 8, 7]]) {
sphere(x, y, z, 1.4, "#f0cd94");
}import { draw } from "./assets/voxel";
import { tamborTaiko } from "./assets/tambor-taiko";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, tamborTaiko, 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 tambor-taiko
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["tambor-taiko"] })
# It lands in client/assets/tambor-taiko.ts
# https://fogon.page/object/tambor-taiko