Rule A (area-sorted triangle removal) left holes and open boundaries
on closed meshes (visible artifacts when zoomed far out). The decimator
is now a proper quadric edge collapse:
- Collapse: welded u32 topology, per-vertex quadrics (accumulated
incident face planes), edge cost = quadric error at the optimal
point (clamped to the segment) + edge length, BinaryHeap with a
custom Ord (f32 is not Ord; inverted compare, NaN-safe).
- Standard GH semantics WITHOUT the new face: both incident pair faces
degenerate and are removed; neighbouring faces remap and sweep over
the region. Preserves the Euler characteristic and closedness (no
holes, no books, no duplicate faces); interior collapse = -2 faces,
boundary = -1. Guards: non-manifold edge (>2 faces) or a fold
(duplicate sorted triple) rejects the collapse.
- welded(): fuzzy welding (1e-6 relative tolerance, grid + 27-
neighbour broad phase, exact verify) - trig-generated seams differ
by ~1e-16, exact-bit welding missed them.
- Root causes fixed along the way: dead face slots are never reused
(stale edge/vface entries), vfaces updated on remap, degenerate
faces dropped, best-effort target (granularity -2/-1 can land 1-2
off; soft cap, deterministic).
- Docs: DRAFT D10, ROADMAP 4.3, ARCHI_CPU_GPU, gpu-driven, lib
README, mesh/scene/demo comments - 'greedy decimation / Rule A'
replaced by 'quadric edge collapse'.
- lod.rs test: deprecated glam perspective alias -> explicit
glam::camera::rh::proj::opengl::perspective.
cargo test --workspace: 100 passed (94 lib + 3 wgsl + 3 integration),
0 failed; demo runs clean with LOD on.