perf(scene): zoom-adaptive curve tolerance for top-level wires (Phase 3.2)

Edge tessellation used a fixed 0.005 world-unit chord-height tolerance
regardless of zoom — a 1000 m radius arc viewed at 50 mm/px still emitted
hundreds of segments that all collapsed onto the same screen pixel.

`truck_tess` now reads tolerance from a process-wide AtomicU64 override.
`Scene::wires_for_block` sets the override to ~0.5 px chord height
(world_per_pixel × 0.5) before the par_iter, then a Drop guard clears it
back to the default. Floor stays at the original CURVE_TOL so extreme
zoom-in keeps full quality. Block-cache rebuilds and off-render paths
(snap, hit-test) always see the default — the override is bracketed to
the render call only.

Roadmap entry for Phase 3.2 removed; Implementation Order / Key Files
tables updated.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
HakanandClaude Opus 4.7 committed 2026-05-15 14:07:28 +03:00
1 parent 0584e3c862
commit 26271b8c63
3 files changed
+50 -29

No files matched your search

+15
View File
@@ -1051,6 +1051,21 @@ impl Scene {
let blk_ref: &block_cache::BlockCache = &blk_cache;
let view_aabb = self.view_world_aabb();
let wpp = self.world_per_pixel();
// Zoom-adaptive curve sampling for top-level Edge tessellation. Target
// ~0.5 px chord height — far-out arcs that used to emit hundreds of
// segments now collapse to a handful. The guard clears the override
// when this scope exits so off-render tessellation (snap previews,
// hit-test, block_cache rebuild) sees the default.
struct CurveTolGuard;
impl Drop for CurveTolGuard {
fn drop(&mut self) {
crate::scene::truck_tess::set_curve_tol_override(None);
}
}
let _tol_guard = wpp.map(|w| {
crate::scene::truck_tess::set_curve_tol_override(Some((w * 0.5) as f64));
CurveTolGuard
});
let mut wires: Vec<WireModel> = visible
.into_par_iter()
.flat_map(|e| {
+35 -2
View File
@@ -20,6 +20,38 @@ const CURVE_TOL: f64 = 0.005;
// Triangle mesh tolerance (world units).
pub const MESH_TOL: f64 = 0.01;
// ── Zoom-adaptive curve tolerance override ────────────────────────────────
//
// The Scene sets this once per render frame to a value derived from
// `world_per_pixel` (target ≈ 0.5 px chord height). All Edge tessellations
// inside the frame — including those running on rayon worker threads — read
// from the same atomic, so callers don't need to thread a tolerance
// parameter through every entity-converter signature. Zero means "use
// `CURVE_TOL`"; that is the default, and what BlockCache::build expects.
use std::sync::atomic::{AtomicU64, Ordering};
static CURVE_TOL_BITS: AtomicU64 = AtomicU64::new(0);
/// Set the per-frame curve tolerance. `None` (or any non-finite/<=0 value)
/// reverts to the default `CURVE_TOL`.
pub fn set_curve_tol_override(tol: Option<f64>) {
let bits = match tol {
Some(t) if t > 0.0 && t.is_finite() => t.to_bits(),
_ => 0,
};
CURVE_TOL_BITS.store(bits, Ordering::Relaxed);
}
/// Resolve the active curve tolerance. Clamped to the floor `CURVE_TOL` so
/// extreme zoom-in never under-samples below the existing baseline quality.
fn current_curve_tol() -> f64 {
let bits = CURVE_TOL_BITS.load(Ordering::Relaxed);
if bits == 0 {
CURVE_TOL
} else {
f64::from_bits(bits).max(CURVE_TOL)
}
}
// ── Public result type ────────────────────────────────────────────────────
/// Output of any truck topology tessellation.
@@ -65,8 +97,9 @@ pub fn tessellate_edge(e: &Edge, offset: [f64; 3]) -> TruckTessResult {
let curve = e.oriented_curve();
let (t0, t1) = curve.range_tuple();
// parameter_division samples adaptively: fewer points on straight segments,
// more on tight curves, all within CURVE_TOL chord-height error.
let (_, pts) = curve.parameter_division((t0, t1), CURVE_TOL);
// more on tight curves, all within the active chord-height tolerance.
// The Scene scales this with zoom so far-out arcs aren't oversampled.
let (_, pts) = curve.parameter_division((t0, t1), current_curve_tol());
let lines = pts
.iter()
.map(|p| to_local(p.x, p.y, p.z, offset))