3DFACE entities previously created one WireGpu buffer per entity,
resulting in N separate draw calls per frame. For files with large
triangle meshes this was the dominant GPU CPU overhead.
New pipeline:
- face3d.wgsl: simple flat-color vertex + fragment shader (MVP only,
no quad expansion, no pattern distance computation)
- Face3DGpu: batches ALL Face3D entities into a single TriangleList
buffer (6 vertices per face, per-vertex color) — 1 draw call
- WireGpu::from_batch: merges N Face3D edge wire models into one
quad-expanded buffer for edge rendering — 1 draw call
- split_face3d_wires: separates face3d from other wires at Primitive
build time via document handle lookup (O(N), once per epoch)
Hit-testing via WireModel (CPU) is unaffected — face3d wires remain
in entity_wires_arc() and hit_test_wires() as before.
Before: N 3DFACE → N draw calls, N × 96 B/vertex WireVertex
After: N 3DFACE → 2 draw calls (fill + edges), 28 B/vertex fill
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Subtracts the DXF header extents centroid (world_offset) from all coordinates
in f64 BEFORE casting to f32. This eliminates the ~0.5 m ULP error that occurs
at 4,000,000 m UTM coordinates and caused geometry to disappear on zoom-out.
- Scene: adds world_offset field + compute_and_set_world_offset() method
- tessellate.rs: threads world_offset through all f64→f32 conversions
(legacy_geometry, dimension_geometry, solid_wire_fallback, multileader)
- truck_tess.rs: to_local() helper already in place from prior session
- mod.rs: tessellate_entity() and entity_aabb() apply world_offset
- update.rs: compute_and_set_world_offset() called after doc load
- cmd_result.rs / solid3d_cmds.rs: pass correct offset to truck tessellators
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selected wires are now visible through occluding objects. A second
wire_xray pipeline (depth_compare=Greater, depth_write_enabled=false)
renders 25%-alpha ghost copies of selected wires only where they are
behind the depth buffer, leaving fully-visible portions at full glow
brightness unchanged.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>