Keep all solid geometry GPU-resident during navigation. Use vertex-rate instancing, compact untextured vertices, vertex-cache ordering, and cached silhouette sources without culling geometry.
Share source buffers across block placements and render nested content with GPU instance transforms.\n\nChunk silhouettes and compact mesh material data so large drawings stay under device buffer limits and remain responsive.
Route model, paper, viewport and nested block content through one traversal while preserving leaf renderers. Carry decoded material state into mesh shading and harden solid geometry conversion.
Keep storage fast paths on capable adapters and use packed or texture fallbacks only when device limits require them.\n\nCompact mesh-edge varyings to avoid WebGL shader rejection.
Solid wireframes rendered every triangle edge of the tessellation, so a
curved solid read as a dense mesh instead of its real outline. Now each ACIS
solid's B-rep face-boundary edges are collected from the SAT `edge` records
(straight edges as segments, ellipse/circle edges sampled along their bounded
arc), body-transformed and split into the double-single pair, and stored on
the MeshLodSet. The block-instance and top-level offset paths transform these
edges alongside the mesh vertices.
The batch builder routes a solid with feature edges into a dedicated LineList
vertex buffer and skips its triangle wireframe; a mesh with no B-rep edges
keeps its triangulation edges. Edge colour follows the display mode: the flat
`fs_edge` shader draws the entity colour in the lines-only modes (wireframe,
hidden-line) and a `fs_edge_black` twin forces black for the edge overlay in
filled render modes.
Verified: the Clinic storefront arch bars now yield ~14-16 clean edge
segments (vs the full triangulation) bounded to the solid's true extent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The GPU draws exclusively via the rotation-only `view_rot` + eye double-
single; the full view-projection survived only to project AABBs in the
CPU frustum-cull / scissor / LOD passes. Migrate those to the same
relative-to-eye math (project `point - eye` through `view_rot`) — pixel-
equivalent but precise at UTM scale — then drop the dead uniform:
- pipeline cull/scissor/LOD helpers take (view_rot, eye) instead of the
full view_proj; render.rs reconstructs eye from the uniform's
eye_high/eye_low and passes the cropped view_rot.
- Remove the `view_proj` field from the shared Uniforms struct and all six
shader structs that only declared it for layout (none read it), and
delete Camera::view_proj(). The struct shrinks by one mat4 on both
sides, keeping the Rust / WGSL layouts in lock-step.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
No GPU pipeline reads camera_pos any more — lighting and all transforms
moved to the relative-to-eye path (view_rot + eye_high/eye_low). Remove
the field from the shared Uniforms and every shader struct, plus the now
unused Camera::position_vec4. view_proj stays: the CPU frustum-cull /
scissor / LOD passes still project offset-relative AABBs with it (it is
no longer part of any GPU draw).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3D solid / surface meshes were the last single-f32 path. truck's mesh
tessellation now returns a paired verts_low residual (TruckTessResult::Mesh,
polygon_to_result), MeshModel/MeshLodSet carry it, the model-space offset
and block-instance transforms reconstruct the f64 position and re-split it
after subtracting world_offset, MeshVertex gains position_low (location 3),
and mesh.wgsl reconstructs the eye-relative position. Native SAT / ACIS /
OBJ mesh paths default to a zero residual (no regression — they were never
sub-f32 precise).
With this every world-space pipeline (wire, hatch, image, face3d, mesh)
is full double-single relative-to-eye; large-coordinate jitter is gone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Switch the remaining world-space shaders (mesh, image, face3d, hatch,
hatch_batched) to the same relative-to-eye transform the wire pipeline
uses: subtract the eye (high+low f32) per vertex and multiply by the
rotation-only view-projection. Each shader's Uniforms struct is widened
to the full shared layout so the appended RTE fields land at the correct
offsets. Math is unchanged (proj·R·(pos−eye)); large coordinates no
longer jitter on camera movement.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebuild every ACIS face as a truck topological Face and mesh it with truck,
routing loaded 3DSOLID/BODY/REGION/SURFACE through the same kernel the Model
tab uses. plane→try_attach_plane, cone/cylinder/sphere/torus→revolution faces
(truck's Surface has no cone/sphere/torus), spline→BSplineSurface grid sample.
Per-vertex normals are computed analytically outward per surface type and
triangle winding is oriented to match, since truck's own orientation isn't
consistent across independently built faces. `tessellate_solid3d|body|region|
surface` try this first and fall back to the bespoke sampler.
Light the mesh shader with three spread directional lights plus ambient
(abs(dot) per light, two-sided) so faces — including the inner walls of an
open lofted surface — never read as a flat dark mass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>