← Basics3D assetfogon/sargento
Sargento
Drag to turn it// «Sargento» · gpt-6-sol (medium)
// C clamp («Sargento»).
// Red cast-metal C-clamp, shifted down so its handle rests at z = 0.
// These helpers use the original design coordinates.
const S = (x, y, z, color) => set(x, y, z - 3, color);
const G = (x, y, z) => get(x, y, z - 3);
const B = (x0, y0, z0, x1, y1, z1, color) =>
box(x0, y0, z0 - 3, x1, y1, z1 - 3, color);
const L = (x0, y0, z0, x1, y1, z1, r, color) =>
line(x0, y0, z0 - 3, x1, y1, z1 - 3, r, color);
const C = (cx, cy, cz, r, h, color) =>
cylinder(cx, cy, cz - 3, r, h, color);
const rows = [
[8, 16, 24], [9, 13, 31], [10, 11, 38],
[11, 10, 40], [12, 9, 40], [13, 8, 40],
[14, 7, 40], [15, 7, 40], [16, 6, 39],
[17, 6, 17], [18, 5, 15], [19, 5, 14],
[20, 5, 13], [21, 5, 13], [22, 5, 13],
[23, 5, 13], [24, 5, 13], [25, 5, 14],
[26, 6, 14], [27, 6, 15], [28, 7, 16],
[29, 8, 17], [30, 9, 18], [31, 10, 19],
[32, 11, 42], [33, 12, 42], [34, 13, 42],
[35, 14, 42], [36, 16, 42], [37, 18, 42],
[38, 21, 42], [39, 24, 41], [40, 28, 40]
];
for (const [z, left, right] of rows) {
for (let x = left; x <= right; x++) {
for (let y = 17; y <= 29; y++) {
const edge = x <= left + 1 || x >= right - 1;
let color = y === 17 ? "#a5362e" : "#ca4436";
if (y === 29) color = "#96332c";
if (edge) color = y === 17 ? "#862c29" : "#ab392e";
if (y > 18 && y < 28 && rand() < 0.045) color = "#d84b3a";
S(x, y, z, color);
}
}
}
// Highlight upper surfaces and darken exposed lower edges.
forEach((x, y, actualZ, color) => {
const z = actualZ + 3;
if (color && y >= 17 && y <= 29) {
if (!G(x, y, z + 1)) S(x, y, z, y < 20 ? "#ec604a" : "#dd5140");
else if (!G(x, y, z - 1) && y === 17) S(x, y, z, "#802b29");
}
});
// Stepped ribs around the curved casting.
const ribs = [
[[27, 39], [22, 38], [18, 36], [15, 34], [12, 31],
[10, 29], [8, 26], [7, 23], [7, 19], [8, 16],
[10, 13], [13, 11], [17, 9]],
[[25, 37], [20, 36], [16, 33], [13, 30], [11, 27],
[9, 24], [9, 20], [10, 17], [12, 14], [15, 12], [19, 10]],
[[22, 35], [18, 33], [15, 30], [13, 27], [12, 24],
[12, 20], [13, 17], [15, 14], [19, 12]]
];
for (const path of ribs) {
for (let i = 1; i < path.length; i++) {
const [a, b] = [path[i - 1], path[i]];
L(a[0], 16, a[1], b[0], 16, b[1], 0, "#87302a");
L(a[0], 15, a[1] + 1, b[0], 15, b[1] + 1, 0, "#df5140");
}
}
// Front faces of the jaws.
B(20, 16, 12, 39, 16, 15, "#c64435");
L(20, 15, 15, 39, 15, 15, 0, "#f2634a");
L(22, 15, 12, 38, 15, 12, 0, "#8d302b");
B(20, 16, 33, 41, 16, 36, "#bb3d31");
L(21, 15, 36, 41, 15, 36, 0, "#ef6049");
L(19, 15, 33, 41, 15, 33, 0, "#862d29");
// Ridges across the upper jaw.
B(28, 19, 40, 39, 27, 41, "#e85743");
for (const y of [19, 23, 27]) {
L(27, y, 41, 39, y, 41, 0, "#fa7458");
L(26, y + 1, 40, 40, y + 1, 40, 0, "#a8372e");
}
L(29, 18, 39, 40, 18, 39, 0, "#f36a50");
L(23, 17, 37, 41, 17, 37, 0, "#8c302b");
// Steel lip beneath the fixed upper jaw.
B(38, 20, 31, 43, 29, 31, "#606b70");
L(39, 19, 31, 43, 19, 31, 0, "#abb5b6");
B(41, 21, 32, 42, 28, 32, "#bdc5c3");
// Cast boss on the curved frame.
B(11, 14, 17, 15, 16, 23, "#a6382e");
B(12, 13, 18, 15, 14, 22, "#d34b39");
B(13, 12, 19, 14, 12, 21, "#80312c");
S(14, 11, 20, "#e66a50");
// Threaded screw and swiveling pressure pad.
C(33, 23, 5, 2, 22, "#727e81");
for (let z = 18; z <= 25; z += 2) {
C(33, 23, z, 2.5, 1, "#aeb8b8");
}
C(33, 23, 18, 3, 3, "#535e63");
C(33, 23, 21, 2, 5, "#8d999b");
C(33, 23, 25, 3, 2, "#5a6669");
B(29, 20, 27, 37, 26, 28, "#aab4b5");
B(30, 19, 29, 36, 27, 29, "#d7ddda");
B(30, 19, 27, 36, 19, 28, "#758185");
L(30, 20, 29, 36, 20, 29, 0, "#f0f1ea");
for (const x of [29, 37]) {
B(x, 21, 27, x, 25, 28, "#788489");
}
// Screw collar and cross-bar handle; the left knob reaches z = 0.
C(33, 23, 5, 3, 5, "#707b7e");
C(33, 23, 4, 2, 3, "#a8b1b1");
B(24, 22, 4, 42, 24, 6, "#929d9e");
L(25, 22, 6, 41, 22, 6, 0, "#d5dbd8");
B(23, 21, 3, 26, 25, 7, "#687579");
B(24, 21, 7, 25, 25, 7, "#c8d0cd");
B(41, 21, 4, 43, 25, 7, "#687579");
B(42, 21, 7, 43, 25, 7, "#c8d0cd");import { draw } from "./assets/voxel";
import { sargento } from "./assets/sargento";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, sargento, 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 sargento
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["sargento"] })
# It lands in client/assets/sargento.ts
# https://fogon.page/object/sargento