fix: restore visibility for large-coordinate DXF files after world_offset regression

Three root causes caused all geometry and UCS arrows to disappear:

1. TruckObject::Lines and TruckObject::Text variants returned world-space
   f32 coordinates without applying world_offset, so fit_all() computed
   bounds spanning from local space to UTM world space (~4 M m), placing
   the camera impossibly far from all visible geometry.

2. Ray/XLine entities with unnormalized direction vectors (common in some
   DXF exporters) produced astronomically large far-point coordinates
   (up to 1e28) that overwhelmed the camera fit even after the offset fix.
   Fixed by normalizing the direction vector before multiplying by
   DISPLAY_EXTENT.

3. Origin-stuck corrupted entities (coordinates ≈ 0 in world space become
   ≈ -world_offset in local space) pulled the fit_all() bounds far from
   the actual drawing. Fixed by computing local_extent_max from EXTMIN/EXTMAX
   (10× safety margin) and skipping points outside that range in fit_all().

Additional hardening: wire_gpu.rs now skips ±inf segments (not just NaN),
and snap_pts/key_vertices in all TruckObject variants are offset-corrected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-04-27 18:04:35 +03:00
commit e191315713
4 changed files with 115 additions and 43 deletions

View file

@ -150,9 +150,9 @@ impl WireGpu {
for i in 1..n {
let p = wire.points[i - 1];
let q = wire.points[i];
// If either point is a NaN sentinel, keep the same distance
// (the segment will be skipped anyway).
if p[0].is_nan() || q[0].is_nan() {
// If either point is non-finite (NaN sentinel or ±inf from overflow),
// keep the same distance — the segment will be skipped anyway.
if !p[0].is_finite() || !q[0].is_finite() {
dists[i] = dists[i - 1];
} else {
let dx = q[0] - p[0];
@ -166,15 +166,15 @@ impl WireGpu {
let a = wire.points[i];
let b = wire.points[i + 1];
// Skip any segment that involves a NaN sentinel point.
// NaN sentinels are inserted between disconnected glyph strokes
// by tessellate.rs so that multiple strokes can share one WireModel.
if a[0].is_nan()
|| a[1].is_nan()
|| a[2].is_nan()
|| b[0].is_nan()
|| b[1].is_nan()
|| b[2].is_nan()
// Skip segments where either endpoint is non-finite (NaN sentinels
// from disconnected glyph strokes, or ±inf from Ray/XLine far-point
// overflow when the direction vector is very large).
if !a[0].is_finite()
|| !a[1].is_finite()
|| !a[2].is_finite()
|| !b[0].is_finite()
|| !b[1].is_finite()
|| !b[2].is_finite()
{
continue;
}