---
title: "The 3D preview: rigid bodies and cloth"
url: https://recursiveai.org/onephysics/cookbook/3d-preview/
description: "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."
version: "0.4.0-preview.1"
---

# The 3D preview: rigid bodies and cloth

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`.

```csharp
#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](https://recursiveai.org/onephysics/docs/soft-bodies/) and the [changelog](https://recursiveai.org/onephysics/docs/changelog/).
