Repository navigation
v0.2.0-preview.1
Pre-release-
The snapshot format is frozen at version 1. Its layout (header, options, bodies, shapes, constraints, islands and registered sections,
docs/spec/architecture.md) no longer changes within version 1. A later change is a new format version. Results may still move between previews. -
Raw tier (
[Experimental("OPHYS0001")]):IBox<TSelf>gainsTranslated(ReadOnlySpan<double>), which the exact origin shift uses. A type that implementsIBox<TSelf>outside the library must add it. -
The 3D engine stays
[Experimental("OPHYS0002")]. It meets the speed bar on most scenes but not all yet: within 1.15x of the fastest stable managed engine (BepuPhysics v2, Jitter2), per scene and thread count. Measured on a Ryzen 9 7950X3D (ours / reference median step time, t1 / t8 on one core complex / t32):scene t1 t8 t32 large-pile-3d 1.10 1.23 1.47 ragdoll-pile-3d 2.75 1.42 2.17 sleep-wake-3d 2.75 1.60 1.41 queries-3d (settle phase) 1.31 1.42 1.38 heightfield-terrain-3d 1.17 0.95 0.68 mesh-terrain-3d 1.10 0.92 0.68 joint-grid-3d 0.10 0.16 0.06 joint-chains-3d and pyramid-3d-30 have no stable managed reference and are judged on their stability limits, which they meet. Every 3D scene is within its stability limits, and every 2D scene is within the bar at every thread count. These rows predate the narrowphase entry below, which takes 3-6% off the ragdoll, box-pile and sleep-wake rows.
-
Warmupprimes more of the process. Its trial world now drops a pile that lands, settles and falls asleep (150 steps) and runs box and sphere casts and box and capsule overlaps, so those paths are loaded before a host's first step. Worlds, hashes and snapshots are unchanged.
Moved results: 3D worlds move (the broadphase keeps tighter boxes, so pairs start and end at different steps), and 2D and 3D worlds move again because positions now advance on a 2^-32 grid (see the origin shift entry).
-
3D narrowphase is cheaper in ragdoll and box piles, with identical results (ragdoll-pile-3d about 5%, sleep-wake-3d about 3%, large-pile-3d about 4% per step, one thread, indicative): a capsule against a box skips box edges that cannot be nearest, box edge axes are rejected before they are normalized, separated boxes nearest on an edge pair skip GJK, and pairs that need a narrowphase run in their own method. No world hash moves.
-
3D ray casts and sphere casts are faster (ray 0.59x, sphere cast 0.79x,
OverlapSphereAll0.84x the time on a 3000-body pile, one thread, indicative). Spheres, capsules, boxes and hulls are tested in closed form, and the GJK route only runs for starts inside, grazing hits, edge regions and other shape kinds. Which shape is hit and the hit counts do not change; the last bits ofFraction,Distance,PointandNormalof ray and sphere-cast hits do (within the old route's tolerance), so worlds that cast (vehicle wheel rays) move. -
3D: a substep schedule per island. Islands without a joint (and not touching a kinematic body or holding a vehicle) now run 2 substeps of 1 solve and 2 relax passes (
WorldOptions3D.ContactSubsteps,ContactVelocityIterations,ContactRelaxIterations;ContactSubsteps = 0restores the world-wide schedule); islands with joints keepSubsteps. Piles and terrain step about 1.15-1.35x faster and worlds with those islands move; adding a joint changes only the island that receives it. The options are saved in snapshots and covered by the world hash. -
3D broadphase defaults:
BroadphaseMarginis 0.03 (was 0.1), boxes stretch over four steps of motion, and the tree is refitted between rebuilds. About half as many pairs are kept alive in piles; sleep-wake scenes step about 1.2× faster and large piles at eight threads about 1.15×. Stability is unchanged on every 3D scene. -
A fast body still inside the supported range no longer fails the step with an argument error when its stretched box would cross the range limit; the stretch stops at the limit.
-
ShiftOriginis exact. A shifted world now steps through exactly the states of the unshifted world, translated (positions differ by the offset; velocities, rotations and contact data are bit-identical), instead of drifting from it. The shift moves the stored broadphase boxes in place instead of rebuilding them. To make that true, a body's position increment each step is rounded to a multiple of 2^-32 (2.3e-10 m; a body slower than about 1.4e-8 m/s at 60 Hz does not move), shape bounds are rounded outward to the same grid, and the broadphase margin is rounded to it. Positions handed in as 31.32 fixed-point values are already on the grid. -
3D box-against-box face contacts are built without loading polyhedra. The reference face is now the one the separating axis test chose (no second choice by area), so manifolds and the worlds that contain boxes move. The box-box manifold costs about 0.78× as much per fresh manifold in a sleep-wake pile (845 against 1090 ns).