Recursive AI

The 3D preview: rigid bodies and cloth

All onephysics recipes

Try OnePhysics’s 3D engine: a sphere dropped on a box, and a cloth draped over a block, with a snapshot and a world hash like the 2D engine’s.

The 3D engine is a preview inside the preview, marked [Experimental("OPHYS0002")]: it works and is deterministic, but its API and results may change between previews. Using it is a compiler error until you acknowledge that, here with #pragma warning disable OPHYS0002.

C#
#pragma warning disable OPHYS0002        // the 3D engine is a preview
using RecursiveAI.OneMath;
using RecursiveAI.OnePhysics;
using RecursiveAI.OnePhysics.Physics3D;
 
var world = new PhysicsWorld3D();
world.AddBox(new Vector3F(20, 1, 20), at: new Vector3D(0, -0.5, 0), type: BodyType.Static);
var ball = world.AddSphere(0.5f, at: new Vector3D(0, 5, 0));
ball.OnCollisionEnter += c => Console.WriteLine($"ball hit the ground along {c.Normal}");
 
// A cloth dropped over a box (soft bodies are new in 0.4.0-preview.1).
world.AddBox(new Vector3F(1, 1, 1), at: new Vector3D(3, 0.5, 0), type: BodyType.Static);
SoftBody cloth = world.AddCloth(width: 2f, depth: 2f, segments: 16, at: new Vector3D(3, 2, 0));
 
for (int i = 0; i < 180; i++) world.Step(1f / 60);
Console.WriteLine($"ball at {ball.Position}");
Console.WriteLine($"cloth middle at {cloth.GetPosition(8 * 17 + 8)}, corner at {cloth.GetPosition(0)}");
if (world.Raycast(new Vector3D(0, 10, 0), new Vector3F(0, -1, 0), out var hit)) Console.WriteLine($"ray hit at {hit.Point}");
Console.WriteLine($"snapshot {world.Snapshot().Length} bytes, hash {world.ComputeHash():X16}");
Text
ball hit the ground along (-0, -1, -0)
ball at (0, 0.49990872712805867, 0)
cloth middle at (2.996202104142867, 1.0705060136970133, -0.0004592029581544921), corner at (2.1870665550231934, 0.42688015825115144, -0.7950175404548645)
ray hit at (0, 0.9999087271280587, 0)
snapshot 29448 bytes, hash 14867385E479387F

Good to know

  • The 3D world has the same members as the 2D one, with 3D math types: PhysicsWorld3D, AddBox, AddSphere, Raycast, Snapshot, ComputeHash.
  • Soft bodies are new in 0.4.0-preview.1: AddCloth, AddSoftBox and AddSoftBall with the Cloth, Rubber and Jelly materials, or AddSoftBody from your own triangle or tetrahedral mesh. Particles collide with every shape and with each other and push dynamic bodies. GetPosition(i) reads one particle without allocating; particle 8 * 17 + 8 is the middle of a 16-segment cloth.
  • 3D also has characters, vehicles, ragdolls and buoyancy. Results are bit-identical across x64, arm64, WebAssembly, vector widths and thread counts.

See soft bodies and the changelog.