Commit graph

31 commits

Author SHA1 Message Date
Admin
eb0b7de06e box3d: broad-phase hybrid — drop the parallel batch, keep the serial BVTT
The parallel batch machinery from be21d627a only ever existed to chase a
default-on multi-threaded win that never came (washer w8 still +54% with
the hybrid on). At w1 — the only configuration this opt-in flag is for —
parallel_for runs inline, so the serial path gives the identical result
for ~340 fewer lines. Wire up the previously-dead
dynamic_tree_self_pairs/cross_pairs into a serial collect_batch_candidates
(three BVTT self/cross traversals -> canonical (a,b,child) sort -> serial
filter into move_results[0]) and delete BatchWork, BatchCtx, batch_drain_*,
BatchFilterCtx, batch_filter_*, bvtt_step, dynamic_tree_bvtt_drain/expand,
and the batch_frontier/worker_* scratch fields.

Determinism preserved exactly: OFF 0x61E35C31/step314 bit-identical, ON
0xBE99C5F7/step313 identical across workers 1/2/4. The debug SET-equality
oracle and the determinism_broad_phase_hybrid_across_worker_counts test
are unchanged and still pass; zero warnings.

PGO: pgo.sh never trained -bp=1, so an off-path-only profile laid the
hybrid branch out cold and collapsed the win to ~-5%. Add one -b=8 -bp=1
training run (neutral for the default path — counts merge, the OFF branch
stays hot) and retrain.

Corrected README numbers to measured values (hybrid-trained profile,
paired -bp toggle, washer w1): pair-finding stage 7.6k -> 3.6k ms/1000
(-52%); total ~-17% (~19.0k vs ~22.6k), which beats C (20661) and narrows
Rapier's lead from ~23% to ~12% — not the "17.7k / within 5% / -19%"
be21d627a claimed. Still default-off (w8 regresses ~+54%), opt-in
single-threaded accelerator for churn-heavy scenes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:08:45 +02:00
Admin
550d89b446 box3d: README — document opt-in broad-phase hybrid, annotate washer
Broad-phase-hybrid subsection (why washer loses, the batch design, the
determinism proof, the single-thread win / multi-thread floor tradeoff,
and the default-off rationale). Washer row in the single-thread rapier
table annotated with the opt-in number (~17.7s, beats C, ~5% behind
rapier → box3d ahead-or-even on all nine single-threaded).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 02:51:21 +02:00
Admin
c2f54e7095 box3d: README — three-way single-thread matrix (Rust | C | Rapier), same-window run
Adds the C Box3D column to the nine-scene rapier table, all from one
same-window interleaved single-thread run (2026-07-06). Percentages vs
the box3d Rust column. box3d Rust beats Rapier on 8/9 (junkyard flipped
to a +5% win post-tier-2; only washer lost, Rapier's incremental-BVH
broad phase). vs C: within ~7% geomean, ahead on both pyramid scenes,
worst is junkyard +18%. Replaces the derived † junkyard cell with a
direct measurement. Headline updated 7/9→8/9.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 01:08:28 +02:00
Admin
4e498ca934 box3d: README — junkyard cells updated for tier-2 (derived from paired -8%), geomeans recomputed
Derived cells marked with a dagger and the derivation stated: cold-window
baseline x the same-binary paired improvement (thermal-drift-immune);
direct cold-window rerun will replace them. vs C: junkyard +17%->+7% w1,
+22%->+12% w8, geomeans +6%/+8%. vs rapier: junkyard -8% -> ~parity,
geomean +34%, washer now rapier's only win.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 23:49:14 +02:00
Admin
95eb8086fc box3d: tier-2 feature recycling (port extension) — default on, junkyard -8%
New middle tier between full manifold recycling and the full SAT, behind
WorldDef.enable_feature_recycling (default true; OFF path bit-identical,
hash 0x61E35C31 verified):

- Case A, separated-witness early-out: a previously-non-touching contact
  revalidates only the cached winning axis; still separating beyond the
  speculative distance means done in one test. Sound structurally: any
  cached axis is a valid separation witness (understates only, which
  falls through to the full SAT). Carried junkyard: 24k skips/step,
  full SATs 25.4k -> 4.5k per step.
- Case B, touching feature rebuild: re-clips the cached winning feature
  under explicit staleness bounds (SATCache::sat_pose at last full SAT,
  translation < 4x recycle distance, rotation < ~4.6 deg, forced refresh
  every 8 steps); degenerate rebuilds and touching<->separated
  transitions fall through same-step.

Probe-driven (junkyard: 89k full SATs/step on 105k pairs, 13k touching;
rapier maintains 3.4x fewer pairs): paired same-binary -fr=0/1 A/Bs show
junkyard -8% in every pairing (collide phase -15%), washer neutral to
-5%, pyramid/rain guards neutral, OFF costs nothing. Same-session
cross-engine junkyard: rapier's -8% lead closes to ~-3%.

pgo.sh now trains BOTH modes (single-mode training starved the remaining
full-SAT path); checked-in profile retrained dual-mode. SATCache pose
serialized in snapshots. feature_recycled_contact_count in Counters.
README: port-extension subsection, soundness argument, updated notes.
Also: rapier bench --probe mode from the workload-probe session.

179/185/179/179 tests green with the tier ON, zero warnings,
determinism suite passes across runs/workers/task systems.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 23:40:08 +02:00
Admin
901eafb07b rapier bench: extend to all nine box3d scenes, single-threaded matrix
- libs/rapier/crates/bench now mirrors every box3d benchmark scene
  (trees100/50/25, junkyard, rain, washer added to large_pyramid/
  many_pyramids/joint_grid), same -b indices as the box3d benchmark.
  Geometry, densities, filters, spawn cadence and joint counts match;
  body/collider/joint counts verified equal on all nine scenes.
- Fix an index-out-of-bounds panic in the vendored rapier simd-stable
  constraint grouping (interaction_groups.rs): bodies in a different
  island than the interaction (kinematic drivers, dynamics mid
  island-merge) indexed the wrong island's conflict masks. Out-of-island
  bodies are now exempt from conflict tracking, matching the solver's
  existing boundary treatment (bounds-checked gathers, dropped scatters).
  Original three scenes reproduce their previous timings after the fix.
- README: full nine-scene single-threaded matrix vs rapier (box3d wins
  7/9, +33% geomean; rapier wins the hull-churn scenes junkyard/washer)
  with comparability caveats for the extended scenes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 22:35:55 +02:00
Admin
d95c096bcd box3d: README — drop large_world from the matrix (measures scheduler overhead, not physics)
Geomeans over the nine real scenes: +7% w=1 / +9% w=8. The scene stays
in the benchmark binaries (upstream suite parity); its fixed-overhead
story is kept in the known-remainder notes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:53:10 +02:00
Admin
e990959b55 box3d: README — trees rows re-paired (trees50 +22% was a noise cell), drop the w8-vs-serial-C vanity stat
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:49:04 +02:00
Admin
b976c2e40c box3d: README — matrix refreshed to current tree (same-session run, all rounds applied)
junkyard now shows its real post-fix +17%; footnote lattice replaced by
one measurement-conditions note. Geomeans +7% w=1 / +13% w=8.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:29:19 +02:00
Admin
49e3bfc5ad box3d: README — junkyard floor mapped by recycle-disabled isolation
Pure full-update pipeline is +38% vs C (both engines, recycling forced
off), diluted to +17% by the at-parity recycle path. Gap is diffuse
(1.3-1.5x per pipeline function); all concentrated hypotheses measured
~zero, including a staging rewrite that halved build_face_a_contact's
instruction count with zero wall-clock effect (the bloat was cold code).
Note: sample attribution unreliable on PGO binaries (hot/cold splits).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:26:04 +02:00
Admin
c7daefe6a3 box3d: README — junkyard footnote updated with post-fix verification (+17%)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 21:02:46 +02:00
Admin
d8e1bade98 box3d: junkyard pass — restore manifold-pipeline function boundaries (-3.6%), unchecked-hulls demoted to neutral
Disassembly attribution on current binaries: junkyard's +23% sits
entirely in the NON-SAT narrow phase (2.06x C) — the edge SAT is now
FASTER than C. Cause: LLVM+PGO mega-inlining (third occurrence) —
update_contact compiled to 5.5x C's instruction count, collide_hulls had
no symbol at all. inline(never) on collide_hulls /
compute_convex_manifold / query_face_directions restores C's layout:
junkyard -3.6% paired (retrained profile), washer neutral, others
untouched.

hull_at coverage extended to build_face_a_contact / build_polygon /
clip_segment_to_hull_face / find_incident_face for contract completeness
— measured NEUTRAL beyond the boundary fix, and the feature's earlier
-3.6% is now captured by the safe attribute instead. README documents
the demotion honestly (the safe fix superseded the unsafe one).

Gates: 179/179/185/179 tests (default/unchecked-hulls/dp/nosimd), hash
0x61E35C31 everywhere, zero warnings. PGO profile retrained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:40:33 +02:00
Admin
12cd7865e2 box3d: README — unchecked-hulls deltas noted in the matrix, idea review moved to bottom section
Matrix cells stay default-build (cold-window run); the hull scenes'
opt-in feature gains are annotated as paired deltas rather than absolute
cross-session numbers (thermal windows differ ~10%, mixing them would
misstate both). Algebraic-float-ops evaluation moved to a dedicated
'Evaluated ideas' section at the bottom.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 20:06:00 +02:00
Admin
f75dd2bba6 box3d: unchecked-hulls opt-in feature + algebraic-float-ops evaluation
unchecked-hulls (off by default): elides bounds checks on hull-topology
indexing in the three SAT hot loops via a cfg'd accessor. Safety contract
= hull connectivity invariants validated at construction (hull.rs
is_valid_hull_impl + create_hull asserts), immutable behind Arc; debug
builds always assert, so every test run exercises the contract. Measured
(paired, retrained PGO): junkyard -3.6%, washer -2%, nothing elsewhere —
documented honestly that the checks were NOT most of the hull residue.
Tests 179 green with and without the feature; hash 0x61E35C31 both.

README: evaluation of the newly-stabilized algebraic float ops idea —
incompatible with the determinism contract as a default (compiler-
version/ISA-dependent results break cross-arch equality and cross-build
replay), modest expected upside since hot paths are already hand-
contracted; possible future opt-in, not planned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 19:55:41 +02:00
Admin
11b955694d box3d: parallelize finalize-bodies + bullet passes — 8-worker geomean +28% -> +11% vs C
A sweep of every C b3ParallelFor/enqueue dispatch against the port found
the finalize-bodies pass (per-body transforms, AABB updates, sleep
accounting, continuous/TOI) and the bullet pass were left serial when
threading was ported — C runs both under b3ParallelFor. rain's w=8 gap
was almost entirely this serial fraction (Amdahl decomposition showed
its parallel portion already at C parity).

FinalizeCtx mirrors the collide pass's pattern: taken arrays + SyncSlice
disjoint per-body access, per-worker task contexts, deterministic merges
(bitset OR, split-candidate max like C), bullet list via atomic cursor
(C's b3AtomicFetchAddInt mirror). No new unsafe primitives. Pre-solve/
custom-filter callbacks force single-worker like collide.

w=8: rain +42% -> +8%, joint_grid +36% -> +11%, large_pyramid and
many_pyramids and trees25 at parity; geomean +11%. Serial geomean +5%
(Rust wins joint_grid/large_pyramid/many_pyramids outright). PGO profile
retrained; README tables + narrative updated. Remaining known
serial-vs-C difference: the split-island enqueue overlap (documented).

Hash 0x61E35C31 bit-identical (runs, workers 1/2/4, external tasks);
179/185/179 tests, zero warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 19:24:46 +02:00
Admin
fed43d7ec3 box3d: PGO trains on all 10 scenes; small-stage fast path tested and dropped
Training set was missing washer and trees50/25 (washer -1.5% with
coverage, large_pyramid unchanged — no dilution). Profile refreshed.

Small-stage main-only fast path (generalizing C's single-block
shortcut): swept cutoffs 32/64/256 at w=8 — only large_world benefited
(-8% of ~11ms); rain regressed at every cutoff (its small-count stages
are mesh-contact stages with heavy per-item cost — serializing them
starves real parallelism) and joint_grid has few fat stages (grid
coloring = 2-4 colors), so its w=8 gap is NOT thin-stage sync. Reverted
per the measurable-win rule; negative result documented in the README.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 18:39:18 +02:00
Admin
02d72d4e10 box3d: narrow joint write-backs — joint_grid at C parity, serial geomean +7%
Disassembly census showed the joint solvers at exact FMA parity with C
but +110 loads/+54 stores per joint: the full 56-byte BodyState get/set
round trip keeps untouched fields live across the ~1000-instruction
solve bodies. StateAccess::set_velocities (same unsafe contract as set,
velocities only, like C's in-place stores) + get_ref field extraction
across all 16 warm-start/solve functions in the 8 joint types.

joint_grid: 817 vs C 801 ms (was -11%). Full fresh matrix in README:
serial geomean +7% vs C with Rust WINNING large_pyramid (-6%) and
many_pyramids (-3%); w=8 geomean +28%. Checked-in PGO profile retrained
for the new code (stale profile cost ~13% on joint scenes).

Same change was measured neutral for contact scatter and correctly
dropped there (state live ~40 instrs vs ~1000) — both verdicts in the
README as a paired case study.

Hash 0x61E35C31 bit-identical everywhere; 179/185/179 tests, zero
warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 18:29:55 +02:00
Admin
c5b03d3f10 box3d: README — percentage deltas in the comparison table
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 17:03:35 +02:00
Admin
c9cbb4334b box3d: check in PGO profile, apply by default via workspace .cargo/config.toml
cargo build --release on anything in the workspace now gets the PGO'd
box3d automatically (-Cprofile-use=libs/box3d/box3d.profdata; verified:
default build runs at the explicit-PGO binary's speed). The profile is
target-independent — x86_64 cross-build with the ARM-trained profile
compiles clean — and degrades gracefully when stale (unmatched functions
keep normal heuristics). Retrain with libs/box3d/pgo.sh.

Fresh four-way interleaved matrix in the README: default box3d is now
faster than or equal to rapier-simd on all three scenes (1118 vs 1451,
1510 vs 1690, 912 vs 914 ms) and faster than non-PGO C on two of three
(C keeps joint_grid 816 vs 912). 179/185/179 tests green with the
config active.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 16:59:17 +02:00
Admin
604a0b60d7 box3d: PGO build recipe — 11-19% over plain fat-LTO, hash bit-identical
pgo.sh: instrument -> train on the benchmark scenes -> merge -> rebuild.
Paired same-machine runs: large_pyramid 1177 vs 1457 ms (-19%, now 15%
faster than the non-PGO C build), junkyard -14%, many_pyramids -11%.
Determinism hash unchanged under the PGO binary (0x61E35C31 across
runs/workers/task systems) — PGO changes layout/inlining, never
arithmetic. README notes the C-reference fairness caveat.

Also documented as tried-and-dropped (noise-floor in paired A/B, per
the keep-only-measurable-wins rule): cache-line padding of stage-sync
atomics, narrow velocity-only scatter writes, compound child Arc clone
(already eliminated by the earlier scratch fix).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:37:51 +02:00
Admin
5b88fcf311 box3d: README — add C box3d column to the rapier comparison table
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:17:23 +02:00
Admin
6187f463b2 box3d: README — drop rapier-without-simd references (not a realistic comparison)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:16:48 +02:00
Admin
3370d15264 box3d: perf round 3 — many_pyramids 1.28x -> 1.06x vs C, now within 5% of rapier-simd
Disassembly-driven (fork agents confirmed the stalls, killed the
bounds-check and recycle-rate hypotheses with instruction-level and
runtime-counter evidence — recycle counts are bit-identical to C):

- Manifolds inline-when-single store: Contact.manifolds Vec<Manifold> ->
  enum { None, One(Manifold), Many(Vec) } with deref-as-slice. Convex
  contacts keep their manifold inline (the Rust equivalent of C's block-
  allocator arena locality — the per-contact heap chase was the main
  stall in collide/prepare/store). Contact is #[repr(C)] with manifolds
  last so hot header fields stay on the leading cache lines. Public
  ContactData API unchanged via Deref; contact_solver.rs needed zero
  changes. Pure storage change: determinism hash identical (0x61E35C31).
- #[inline(never)] on update_contact + the four convex stage functions:
  C compiles these standalone; LLVM had inlined all of them into one
  13.6 KB execute_block paying constant register-spill traffic.

Definitive cold-machine matrix: serial geomean 1.15x -> 1.12x vs C
(many_pyramids 2071 vs 1949 ms, large_pyramid 1501 vs 1392); 8-worker
geomean 1.35x -> 1.30x. vs rapier-simd (adjacent runs): box3d ahead 16%
on large_pyramid and 3% on joint_grid, behind 5% on many_pyramids (was
21%). README grids updated.

179/185/179 tests green, zero warnings, hash unchanged across workers/
arch/task systems.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 15:14:52 +02:00
Admin
630577cb98 rapier: restore simd-stable (vendor wide + safe_arch), retest vs box3d
Re-vendors wide 0.7 + safe_arch, restores the upstream simd-stable
wiring in rapier3d/parry3d manifests and the cfg-simd source, and drops
the added 'stripped build does not support SIMD' guards (upstream's
simd-vs-enhanced-determinism exclusivity guard kept).

Interleaved single-thread retest (min of 4): SIMD buys rapier 1.8-2.2x;
box3d vs rapier-simd is now near parity — large_pyramid 1579 vs 1638 ms,
joint_grid 957 vs 1008 ms (box3d ahead), many_pyramids 2389 vs 1970 ms
(rapier ahead). box3d README grid updated with the honest three-column
table; box3d keeps cross-arch determinism + zero deps at that speed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 14:17:26 +02:00
Admin
470cffcdac box3d: rapier comparison — ~2x faster single-threaded, bench in libs/rapier/crates/bench
Same scenes/geometry/materials/dt, matched solver budget (4 substeps vs
4 solver iterations), interleaved min-of-4 runs: large_pyramid 2.23x,
many_pyramids 1.82x, joint_grid 1.88x (geomean ~1.97x). Table + fairness
notes at the top of the box3d README (vendored rapier has no SIMD;
enhanced-determinism measured free on these scenes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 13:54:05 +02:00
Admin
35c256a76d box3d: perf round 2 — 8-worker geomean 1.47x -> 1.35x vs C, serial 1.15x
- joint prepare: read BodySim through references (was deref-copying
  220 bytes twice per joint per step; prepare_joint now at C parity)
- FMA contraction extended to joint solvers (32 sites; hash re-baselined
  to 0x61E35C31, still bit-identical across workers/arch/task systems)
- scheduler: workers spin ~tens of us before committing to a kernel
  sleep (semaphore try_acquire spin phase; A/B: large_world w=8
  24 -> 11.5 ms, joint_grid w=8 1.58x -> 1.49x, other scenes neutral;
  intentional deviation from C documented in README)
- tried and reverted: chunks_exact twin-pair edge SAT (won 5% on
  junkyard compounds, cost box-box scenes 4-8%; keeps C 1:1 loop shape)
- README: fresh benchmark matrix, second-round notes, stale external
  task-hook claim fixed

179/185/179 tests green, zero warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 11:09:25 +02:00
Admin
364d65680a box3d: performance pass — serial geomean 1.30x -> 1.13x vs C, 8-worker 1.6x -> 1.47x
Profiling-driven (sample + disasm comparison vs clang -O3). All changes
safe Rust except one debug_assert-guarded extension of the existing
SyncSlice unsafe contract. Determinism preserved: hash bit-identical
across workers 1/2/4, NEON/SSE2/scalar, internal/external task systems
(new baseline 0x9018E2D8 after approved FMA contraction).

- f32/f64::mul_add contraction in hot scalar math (= C's -ffp-contract=on;
  89 sites; wide SIMD ops untouched like C intrinsics). large_pyramid
  now at parity with C (1387 vs 1373 ms serial)
- FloatW::get/set: direct lane load/store instead of vector-through-stack
  round trip; layout asserted at compile time
- gather_bodies by reference (removes 20-register spill storm)
- per-worker capacity-preserving scratch for convex + mesh collide paths
  (C-arena equivalent; mesh path allocated per triangle and serialized
  the parallel collide pass on allocator locks)
- update_contact: borrow shapes instead of cloning (deep compound
  geometry clones + cross-worker Arc traffic; junkyard w=8 -39%)
- scheduler semaphore: two-level atomic fast path (C uses
  dispatch_semaphore_t; old Mutex+Condvar locked every enqueue)
- SyncSlice::get_ref/get_mut unchecked indexing under the existing
  unsafe contract, debug_assert-guarded (-6% serial)
- README/PORTING: new numbers, FMA sync conventions, known remainders

179/185/179 tests green (default/double-precision/disable-simd), zero
warnings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:10:44 +02:00
Admin
995aa23bc1 box3d: recording replay player + test_recording port
Full op-stream player in recording_replay.rs (b3RecPlayer port):
opcode dispatch for ~150 ops, StateHash verification at every step
marker, query replay with bitwise comparison, keyframe ring with
budget-driven interval doubling, seek/restart/scrub, validate_replay.

tests/test_recording.rs ports test_recording.c (17 tests incl.
record-at-4-workers/replay-at-1-and-4 hash equality). 179/185/179
tests green across default/double-precision/disable-simd, zero
warnings, determinism hash unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
66b42fc9dd box3d: multithreading — scheduler, parallel_for, atomic solver stages
Port of the C threading design: worker threads with a fixed task ring and
help-while-waiting finish (scheduler.rs), atomic block-claiming parallel_for,
and the solver's stage machinery (per-block syncIndex CAS, sync-bits stage
advancement, mainClaimed race). Parallel narrow phase, broad-phase pairs,
sensors, finalize. Shared access goes through documented disjointness
primitives (sync.rs: SyncPtr/SyncSlice/AtomicIndex); worker_count 1 keeps the
serial path bit-identically. Results are bit-identical at any worker count
(determinism hash 0x7A796F4F asserted at 1/2/4 workers). 8 workers: 3.4-5.7x
over serial on heavy scenes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
60ec705ab2 box3d: SIMD (SSE2/NEON), double-precision large world, snapshots, benchmarks
- contact solver wide ops + V32 now have real SSE2 and NEON paths selected
  by target arch; scalar fallback behind the disable-simd feature. All three
  paths are bit-identical (cross-arch determinism verified: same ragdoll
  hash on NEON, SSE2 under Rosetta, and scalar).
- double-precision feature (C BOX3D_DOUBLE_PRECISION): f64 world positions
  with the exact C boundary-function semantics; enables the far-from-origin
  test halves (157 tests in DP mode, 151 default).
- world snapshots: recording substrate subset (buffer/writers/geometry
  registry/readers) + world_snapshot.c port; bit-identical continuation
  after restore, corrupt-image rejection.
- examples/benchmark.rs: all 10 C benchmark scenarios; serial Rust runs
  1.05-1.55x slower than C -O2 at one worker (geomean ~1.3x with fat LTO).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00
Admin
848e715c6c box3d: pure Rust port of Box3D (erincatto/box3d @ 29bf523)
Full engine port in libs/box3d: math, geometry, GJK/TOI, hull builder,
dynamic tree, manifolds, constraint graph, solver (serial, scalar SIMD
path), all 8 joint types, sensors, mover, world API. 147 ported C unit
tests green in debug and release. See libs/box3d/README.md for the
upstream revision and sync notes, PORTING.md for conventions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 16:06:18 +02:00