SOURCE / PINNED RELEASE
Made of little things.
Poly Dogfight
- Release
- b8511ee374e3…
- Author-recorded commit
- 5579434b9d8b…
- License
- LICENSE
- Author’s source reference
- nostr://npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr/wss%3A%2F%2Fgit.napplet.soy%2F/n-44f63e5422b
Archive hash verified: bcadd2430d8ea2bc…. The source-to-build association is the author’s claim; it has not been independently rebuilt.
import { BufferAttribute, Color, Euler, Matrix4, Quaternion, Vector3, type BufferGeometry } from 'three';
import { mergeGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils.js';
/** Translate/rotate/scale helper for composing low-poly parts. */
export function T(x = 0, y = 0, z = 0, rx = 0, ry = 0, rz = 0, sx = 1, sy = sx, sz = sx): Matrix4 {
return new Matrix4().compose(
new Vector3(x, y, z),
new Quaternion().setFromEuler(new Euler(rx, ry, rz)),
new Vector3(sx, sy, sz),
);
}
/** A flat-coloured, non-indexed part ready for merging (position + color only). */
export function part(geometry: BufferGeometry, color: number, matrix?: Matrix4, jitter = 0): BufferGeometry {
const g = geometry.index ? geometry.toNonIndexed() : geometry;
g.deleteAttribute('uv');
g.deleteAttribute('normal');
if (matrix) g.applyMatrix4(matrix);
const pos = g.getAttribute('position') as BufferAttribute;
if (jitter > 0) {
// Deterministic per-vertex wobble keyed by position, so shared corners stay shared.
for (let i = 0; i < pos.count; i++) {
const x = pos.getX(i);
const y = pos.getY(i);
const z = pos.getZ(i);
const n = Math.sin(x * 12.9898 + y * 78.233 + z * 37.719) * 43758.5453;
const m = Math.sin(x * 93.989 + y * 67.345 + z * 11.135) * 24634.6345;
pos.setXYZ(i, x + (n - Math.floor(n) - 0.5) * jitter, y, z + (m - Math.floor(m) - 0.5) * jitter);
}
}
const c = new Color(color);
const colors = new Float32Array(pos.count * 3);
for (let i = 0; i < pos.count; i++) {
colors[i * 3] = c.r;
colors[i * 3 + 1] = c.g;
colors[i * 3 + 2] = c.b;
}
g.setAttribute('color', new BufferAttribute(colors, 3));
return g;
}
export function merge(parts: BufferGeometry[]): BufferGeometry {
const merged = mergeGeometries(parts, false);
if (!merged) throw new Error('Could not merge geometry parts');
merged.computeBoundingSphere();
return merged;
}
