SOURCE / PINNED RELEASE
Made of little things.
Supersonic RC Revive
- Release
- 1ba42f1ca1d6…
- Author-recorded commit
- baecad10b1cd…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-143146b0d6f
Archive hash verified: 90d22b206672eba4…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
// Minimal writers for the custom bundle: GLB (the subset src/game/render/glb.ts
// reads) and PNG.
import { deflateSync } from 'node:zlib';
export interface GlbPrimitiveIn {
material: number;
positions: Float32Array;
normals: Float32Array;
uvs?: Float32Array;
/** RGBA bytes: baked light (rgb). */
colors?: Uint8Array;
indices: Uint32Array;
}
export interface GlbMaterialIn {
name: string;
color: [number, number, number, number];
texture?: number;
}
export interface GlbNodeIn {
name: string;
translation?: [number, number, number];
mesh?: { name: string; primitives: GlbPrimitiveIn[]; extras?: Record<string, unknown> };
children?: GlbNodeIn[];
}
export function writeGlb(nodes: GlbNodeIn[], materials: GlbMaterialIn[], images: Uint8Array[] = []): Buffer {
const chunks: Buffer[] = [];
let offset = 0;
const views: object[] = [];
const accessors: object[] = [];
const pushView = (bytes: Uint8Array, target?: number): number => {
const pad = (4 - (offset % 4)) % 4;
if (pad) {
chunks.push(Buffer.alloc(pad));
offset += pad;
}
chunks.push(Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength));
views.push({ buffer: 0, byteOffset: offset, byteLength: bytes.byteLength, ...(target ? { target } : {}) });
offset += bytes.byteLength;
return views.length - 1;
};
const pushAccessor = (data: Float32Array | Uint32Array | Uint8Array, type: string, width: number, target: number, normalized = false): number => {
const view = pushView(new Uint8Array(data.buffer, data.byteOffset, data.byteLength), target);
const componentType = data instanceof Float32Array ? 5126 : data instanceof Uint32Array ? 5125 : 5121;
const acc: Record<string, unknown> = { bufferView: view, componentType, count: data.length / width, type };
if (normalized) acc.normalized = true;
if (type === 'VEC3' && data instanceof Float32Array) {
const min = [Infinity, Infinity, Infinity];
const max = [-Infinity, -Infinity, -Infinity];
for (let i = 0; i < data.length; i += 3) {
for (let k = 0; k < 3; k++) {
min[k] = Math.min(min[k], data[i + k]);
max[k] = Math.max(max[k], data[i + k]);
}
}
acc.min = min;
acc.max = max;
}
accessors.push(acc);
return accessors.length - 1;
};
const imageViews = images.map((png) => pushView(png));
const meshes: object[] = [];
const gltfNodes: object[] = [];
const addNode = (n: GlbNodeIn): number => {
const index = gltfNodes.length;
const out: Record<string, unknown> = { name: n.name };
gltfNodes.push(out);
if (n.translation) out.translation = n.translation;
if (n.mesh) {
const primitives = n.mesh.primitives.map((p) => {
const attributes: Record<string, number> = {
POSITION: pushAccessor(p.positions, 'VEC3', 3, 34962),
NORMAL: pushAccessor(p.normals, 'VEC3', 3, 34962),
};
if (p.uvs) attributes.TEXCOORD_0 = pushAccessor(p.uvs, 'VEC2', 2, 34962);
if (p.colors) attributes.COLOR_0 = pushAccessor(p.colors, 'VEC4', 4, 34962, true);
return { attributes, indices: pushAccessor(p.indices, 'SCALAR', 1, 34963), material: p.material };
});
meshes.push({ name: n.mesh.name, primitives, ...(n.mesh.extras ? { extras: n.mesh.extras } : {}) });
out.mesh = meshes.length - 1;
}
if (n.children?.length) out.children = n.children.map(addNode);
return index;
};
const roots = nodes.map(addNode);
const doc: Record<string, unknown> = {
asset: { version: '2.0', generator: 'ssrc tools/assets' },
scene: 0,
scenes: [{ nodes: roots }],
nodes: gltfNodes,
meshes,
materials: materials.map((m) => ({
name: m.name,
pbrMetallicRoughness: {
baseColorFactor: m.color,
metallicFactor: 0,
...(m.texture !== undefined ? { baseColorTexture: { index: m.texture } } : {}),
},
})),
accessors,
bufferViews: views,
buffers: [{ byteLength: 0 }],
};
if (images.length) {
doc.images = imageViews.map((bufferView) => ({ bufferView, mimeType: 'image/png' }));
doc.samplers = [{ wrapS: 10497, wrapT: 10497 }];
doc.textures = images.map((_, source) => ({ source, sampler: 0 }));
}
const pad = (4 - (offset % 4)) % 4;
if (pad) chunks.push(Buffer.alloc(pad));
const bin = Buffer.concat(chunks);
(doc.buffers as Array<{ byteLength: number }>)[0].byteLength = bin.length;
let json = Buffer.from(JSON.stringify(doc));
json = Buffer.concat([json, Buffer.alloc((4 - (json.length % 4)) % 4, 0x20)]);
const header = Buffer.alloc(12);
header.writeUInt32LE(0x46546c67, 0);
header.writeUInt32LE(2, 4);
header.writeUInt32LE(12 + 8 + json.length + 8 + bin.length, 8);
const chunkHeader = (length: number, type: number) => {
const b = Buffer.alloc(8);
b.writeUInt32LE(length, 0);
b.writeUInt32LE(type, 4);
return b;
};
return Buffer.concat([header, chunkHeader(json.length, 0x4e4f534a), json, chunkHeader(bin.length, 0x004e4942), bin]);
}
const CRC_TABLE = Array.from({ length: 256 }, (_, n) => {
let c = n;
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
return c >>> 0;
});
function crc32(bytes: Uint8Array): number {
let c = 0xffffffff;
for (const b of bytes) c = CRC_TABLE[(c ^ b) & 0xff] ^ (c >>> 8);
return (c ^ 0xffffffff) >>> 0;
}
/** RGBA8 pixels → PNG. */
export function writePng(width: number, height: number, rgba: Uint8Array): Buffer {
const raw = Buffer.alloc((width * 4 + 1) * height);
for (let y = 0; y < height; y++) {
raw[y * (width * 4 + 1)] = 0;
Buffer.from(rgba.buffer, rgba.byteOffset + y * width * 4, width * 4).copy(raw, y * (width * 4 + 1) + 1);
}
const chunk = (type: string, data: Buffer) => {
const head = Buffer.alloc(8);
head.writeUInt32BE(data.length, 0);
head.write(type, 4, 'ascii');
const crc = Buffer.alloc(4);
crc.writeUInt32BE(crc32(Buffer.concat([head.subarray(4), data])), 0);
return Buffer.concat([head, data, crc]);
};
const ihdr = Buffer.alloc(13);
ihdr.writeUInt32BE(width, 0);
ihdr.writeUInt32BE(height, 4);
ihdr[8] = 8;
ihdr[9] = 6;
return Buffer.concat([
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
chunk('IHDR', ihdr),
chunk('IDAT', deflateSync(raw, { level: 9 })),
chunk('IEND', Buffer.alloc(0)),
]);
}
