File size: 5,838 Bytes
75a77d0
 
 
 
 
 
 
a987df5
 
 
 
 
 
4536b63
 
 
 
 
 
ab47e29
 
 
 
 
 
72b1843
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Native geometry contract

This is an independently authored native policy, not verified editor parity. The supplied `GeometrySolver.ixpl` uses `U×V` for signed plane distance; it does not prove which side the editor regards as interior. We adopt outward normals and interior `n·x <= d + epsilon`. Computation uses f64; persisted results must remain finite f32. Unit normals are formed from normalized U/V to avoid scale-dependent basis degeneracy.

Default distance tolerance is 1e-6 world units; angular/determinant tolerance is 1e-10. Both must be finite and positive, with angular tolerance below one. These are explicit native choices, not a claim to reproduce the source helper’s raw determinant threshold. Parallel/nearly parallel triples return no intersection. AABBs retain finite min/max values and include an explicit empty result. MAP/native axes follow the converter mapping `(x,y,z) -> (x,z,-y)` and its inverse. Invalid vectors/policies/ranges return errors.

Tests cover signed basis orientation, asymmetric three-plane intersections, parallel triples, scaled bases, boxes, empty bounds, axis round trips and invalid values. See the [ten-task ledger](PROGRESS_2026-10-26.md) for staged extensions and remaining parity limits.

## Convex brush contours

`brush::contours` enumerates checked plane triples, keeps interior intersections, welds points within distance epsilon and orders each face around its outward normal. Starts are rotated to lexicographically smallest coordinates. Every original plane must contribute a face: duplicate/redundant/degenerate faces are errors, preserving plane identity rather than silently dropping them. Feasible recession directions, missing/invalid edges and nonpositive volume reject unbounded or collapsed objects. Every edge must occur twice. This is a strict native convex profile, not the host's collapse/discard behavior.

Defaults cap 64 planes, 100,000 generated face vertices, 10 million work units and 128 MiB requested scratch/output storage. Work includes recession checks, triple candidates, containment and welding; face sorting is additionally bounded by vertex caps. Allocations are fallible; errors return no partial mesh. Analytic cube, translated box, winding/topology/determinism, contradictory/open/redundant and resource-limit tests pass. Near-degenerate geometry can be rejected conservatively; exact legacy tolerances remain unverified.

## Patch9 tessellation

`patch::sample` evaluates a quadratic 3×3 tile and analytic derivatives; `tessellate` spans odd anchor grids with overlapping tiles every two anchors, U varying fastest. The evaluator uses the tensor product of three-control-point quadratic curves ([W3C quadratic curve definition](https://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands)); this tensor-product choice is native policy, not recovered host implementation. Basis is `[(1-t)^2,2t(1-t),t²]`; derivatives are `[-2(1-t),2-4t,2t]`.

Anchor dimensions must be odd and at least three, and quads per tile at least two, matching source API declarations. Normals use `dv×du` to agree with exported OBJ quad winding. At an interior tile boundary, the right/upper tile supplies the derivative; positional seams are shared but normals are not averaged. Degenerate tangents/normals fail rather than inventing a direction. Sample count/products, work (nine control evaluations per sample) and requested point/normal allocations are bounded. Flat XZ patches, endpoints, exact quadratic midpoints, multi-tile seams and invalid/budget cases pass. Folded/self-intersecting surfaces and legacy seam-normal parity remain open.

## Computed world pipeline

`world::compute` returns a new world, preserving source tables, slots, bases and anchors. It fallibly copies editable data, rebuilds every brush/patch, checks f64→f32 range, and sets computed=true only after all objects succeed. Prior derived arrays are intentionally replaced. Properties are copied unchanged, not normalized; codec-specific validation still happens at save. No source mutation or partial world escapes on a late error.

Work and generated-position budgets apply across the whole world. Requested copy/geometry/output allocations are charged cumulatively (including scratch already freed, conservatively); model element/string limits also apply. CLI `convert/preflight --compute` opts into this native policy before target analysis/encoding. Defaults cap 64 planes per brush, 100,000 generated positions, 10 million work units, and the lower of codec/geometry storage limits. Empty worlds compute successfully; malformed/redundant/open brushes and degenerate patches fail instead of being dropped. Mixed cube/patch, property preservation, DAT round trip, late failure, global-budget and CLI cube-to-OBJ tests pass.

## Nearest-hit queries

`ray::nearest` scans explicit computed brush polygons (convex fans) and patch quads split along the first-to-third diagonal. Queries are double-sided. Ray directions are normalized, so hit parameters are world distances. Negative distances within distance epsilon clamp to zero; larger negative hits and hits beyond finite max distance are excluded. Parallel/degenerate triangles produce no hit; non-finite geometry and malformed arrays fail.

Ties within distance epsilon use stable target order: brush before patch, then ascending object/plane or quad/triangle indices. Returned normals follow polygon/quad winding and do not flip toward the ray. Work/vertex caps apply to the whole linear query, including parents and patch point scans. No acceleration, visibility, selection, near-clip or callback semantics are implied; unused properties/stored normals are not revalidated. Tests cover nearest/inside/miss/max-distance, duplicate-object ties, front/back patch hits, direction normalization and invalid/budget cases.