Skip to content

v0.4.0-preview.1

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 30 Oct 18:53
· 8 commits to main since this release
  • Soft bodies complete the 3D feature set for this preview line; the 3D engine stays [Experimental("OPHYS0002")]. Every 3D scene, soft bodies included, is within its stability limits on x64 and arm64 with identical metrics, and results are bit-identical across x64, arm64, WebAssembly, vector widths and thread counts. Not every speed row meets the bar yet (within 1.15x of the fastest stable managed engine, BepuPhysics v2 or 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.05 1.08 1.25
    ragdoll-pile-3d 2.19 1.12 1.70
    sleep-wake-3d 2.51 1.51 1.40
    queries-3d (settle phase) 1.27 1.26 1.19
    cloth-drape-3d (soft body, against Jitter2) 0.93 3.9 2.5
    heightfield-terrain-3d 1.13 0.89 0.64
    mesh-terrain-3d 1.08 0.89 0.85
    joint-grid-3d 0.10 0.16 0.09

    On an Apple M2 (t1 / t8) every 3D row meets the bar except ragdoll-pile-3d t1 (1.27) and sleep-wake-3d t1 (1.64), and cloth-drape-3d is 0.84 / 1.87. joint-chains-3d and pyramid-3d-30 have no stable managed reference, and the other soft-body scenes (soft-pile-3d, soft-rigid-3d, soft-mesh-3d, soft-skinned-3d) have none either; they are judged on their stability limits, which they meet. Every 2D scene is within the bar at every thread count.

  • 3D soft bodies solve about 2.5 times faster on a cloth (indicative, one thread), and large bodies use several threads. Moved results (soft bodies only; rigid worlds and 2D are unchanged). The step works on float32 positions relative to each body, the constraints are coloured once at creation (edges, bends and tetrahedra solved colour by colour, in Vector128 lanes where four constraints of a colour are available, with the same bits as the scalar loop), bodies of 1024 particles or more are split across threads by colour, contact detection and the particle pair search run in tasks that are joined in particle order, and particle pairs are searched once per step instead of once per substep. The order in which constraints are solved changes, so soft-body states, snapshot bytes and hashes differ from the previous preview; the snapshot layout is unchanged. Details in docs/spec/softbody.md (Solver).

  • 3D soft bodies follow a skeleton (skinning). SoftSkin.Create builds per-particle joint weights (four influences, linear blend skinning), a maximum distance and an optional back-stop sphere from a skeleton and the mesh; set it as SoftBodyDef.Skin. SoftBody.SetSkeletonPose (ragdoll-style local rotations) or SetSkeletonTransforms (world joint poses) drives it before each step, with teleport to place or reset; GetSkinnedPosition, CopySkinnedPositions, HasSkin, Slot and PhysicsWorld3D.GetSoftBody(slot) (to find the bodies again after Restore) are new. A particle with maximum distance 0 is kinematic and equals its linearly blended position bit for bit; the others are held within their distance (and out of the back-stop) after every step, and win against contacts. Snapshot section version 2 is written only while a skinned body exists, so other worlds keep their bytes and hashes; version 1 sections still load. DebugSoftBody.FirstTargetPoint carries the targets. New scene soft-skinned-3d (a sleeve on a swinging arm) with skinMaxDistance, skinBackstop and skinCuffError metrics. See docs/spec/softbody.md.

  • 3D: the bounding-box stage takes about half the time, with identical results. The world box of a sphere, box, capsule or sharp hull is computed straight from the body arrays with only the rotation-matrix entries the shape needs, and a hull's six extremes come from one pass with the three axes as lanes of one 128-bit vector (the same operations in the same order as the scalar code, so every platform and vector width gives the same bits). Profile build, one thread, indicative: large-pile-3d 0.24 to 0.11 ms, ragdoll-pile-3d 0.08 to 0.04, sleep-wake-3d 0.07 to 0.035. No world hash moves. See docs/spec/world3d.md, round 35.

  • 3D soft bodies (core). PhysicsWorld3D.AddCloth, AddSoftBox, AddSoftBall, AddSoftBody(SoftBodyMesh, ...) and AddSoftBody(SoftBodyDef) make cloth, rubber and jelly from a triangle or tetrahedral mesh: extended position-based dynamics with edge, isometric-bend, tetrahedron-volume and pressure constraints, particles that collide with every shape, with each other and with friction, two-way coupling with dynamic rigid bodies, pins, sleeping, debug geometry (DebugContent.SoftBodies), SoftSubsteps and SoftIterations options. The SoftBody handle reads particles without allocating. Soft bodies are stored apart from rigid bodies and solved serially after the rigid step, in a new optional snapshot section (0x534F4654) that is written, hashed and counted only once a soft body exists: worlds without soft bodies keep every byte and hash, and snapshot format version 1 is unchanged. New scenes cloth-drape-3d, soft-pile-3d, soft-rigid-3d, soft-mesh-3d with soft-body metrics and a Jitter2 driver; fuzz targets world3d-softbodies and world3d-softbody-snapshot. DebugContent.All is now 1023; it is a constant, so code compiled against an earlier preview keeps All = 511 and does not draw soft bodies until it is rebuilt.