Mesh display-space projection: nD cull, index rebuild, and winding parity.
Turns a whole LoadedMeshData plus a view state into the three things
the geometry builder needs: a display-space position buffer, the index
buffer of currently-visible triangles, and the material side the epoch must
use.
Whole-triangle cull, not clipping
A triangle is drawn iff all three of its vertices pass the nD slab test
(docs/specs/MESH_NODE_SPEC.md §5.1). Lines clip a segment against the slab
and interpolate every attribute at the clip parameter; the triangle
equivalent is nD polygon clipping with fan re-triangulation and per-new-vertex
attribute interpolation, every frame the slice moves. v1 does not do that.
The price is stated plainly rather than hidden: a surface cut by a slice shows
a ragged, triangle-quantized boundary, not a clean planar cut. On a
well-tessellated mesh sliced with a tolerance comparable to the edge length
that reads as a slightly jagged edge; on a coarse mesh with a thin tolerance
it can drop whole regions.
No vertex compaction
Only the index buffer is rebuilt on a slice change. The vertex attribute
buffers are uploaded once, in full, and left alone — drawElements never
fetches an unreferenced vertex, so culled vertices cost nothing to draw, and
the mesh is resident in full anyway. The only cost is VRAM for currently
invisible vertices, bounded by the mesh size, which is already the resident
working set. This is what lets the loader keep native-dtype colours: a
generic &[f32]-only mask compaction (as the former compact_by_mask was)
could not.
A displayDims change is the one case that also rewrites position, because
position is displayDims-derived. That is re-extraction of the projection,
not compaction.
Mesh display-space projection: nD cull, index rebuild, and winding parity.
Turns a whole LoadedMeshData plus a view state into the three things the geometry builder needs: a display-space
positionbuffer, the index buffer of currently-visible triangles, and the materialsidethe epoch must use.Whole-triangle cull, not clipping
A triangle is drawn iff all three of its vertices pass the nD slab test (
docs/specs/MESH_NODE_SPEC.md§5.1). Lines clip a segment against the slab and interpolate every attribute at the clip parameter; the triangle equivalent is nD polygon clipping with fan re-triangulation and per-new-vertex attribute interpolation, every frame the slice moves. v1 does not do that.The price is stated plainly rather than hidden: a surface cut by a slice shows a ragged, triangle-quantized boundary, not a clean planar cut. On a well-tessellated mesh sliced with a tolerance comparable to the edge length that reads as a slightly jagged edge; on a coarse mesh with a thin tolerance it can drop whole regions.
No vertex compaction
Only the index buffer is rebuilt on a slice change. The vertex attribute buffers are uploaded once, in full, and left alone —
drawElementsnever fetches an unreferenced vertex, so culled vertices cost nothing to draw, and the mesh is resident in full anyway. The only cost is VRAM for currently invisible vertices, bounded by the mesh size, which is already the resident working set. This is what lets the loader keep native-dtype colours: a generic&[f32]-only mask compaction (as the formercompact_by_maskwas) could not.A
displayDimschange is the one case that also rewritesposition, becausepositionisdisplayDims-derived. That is re-extraction of the projection, not compaction.