Placing each vertex of an element
32-bit in partMoves an element's vertices and normals from its own axes into the scene with its placement matrix.
p′ = M × p; n′ = (rotation part of M) × n ÷ |…|
The vertices arrive from the engine as a 32-bit array. Each one is multiplied by the column-major 4 × 4 placement in 64-bit and pushed to a plain array, which finishBatch then stores as 32-bit again. The normal is divided by its length, with a zero length replaced by 1.
function appendGeometry(b, verts, idx, m, id) {
// verts: x,y,z,nx,ny,nz per vertex; m: column-major 4×4 placement. `id` is the element's key.
const base = b.vcount;
const r = b.runs, last = r.ids.length - 1;
if (last >= 0 && r.ids[last] === id) { r.tn[last] += idx.length / 3; r.vn[last] += verts.length / 6; }
else { r.ids.push(id); r.t0.push(b.idx.length / 3); r.tn.push(idx.length / 3); r.v0.push(base); r.vn.push(verts.length / 6); }
for (let i = 0; i < verts.length; i += 6) {
const x = verts[i], y = verts[i + 1], z = verts[i + 2];
b.pos.push(
m[0] * x + m[4] * y + m[8] * z + m[12],
m[1] * x + m[5] * y + m[9] * z + m[13],
m[2] * x + m[6] * y + m[10] * z + m[14],
);
const nx = verts[i + 3], ny = verts[i + 4], nz = verts[i + 5];
let tx = m[0] * nx + m[4] * ny + m[8] * nz;
let ty = m[1] * nx + m[5] * ny + m[9] * nz;
let tz = m[2] * nx + m[6] * ny + m[10] * nz;
const l = Math.hypot(tx, ty, tz) || 1;
b.nrm.push(tx / l, ty / l, tz / l);
}
for (let i = 0; i < idx.length; i++) b.idx.push(base + idx[i]);
for (let i = 0; i < idx.length; i += 3) b.ids.push(id);
b.vcount += verts.length / 6;
}