Simulate a sheet that bends and sags while its four corners stay pinned. OnePhysics returns particle positions, not rendered frames; tearing is not supported.
dotnet new console dotnet add package RecursiveAI.OnePhysics
Requires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneMath; using RecursiveAI.OnePhysics.Physics3D; var world = new PhysicsWorld3D(); var cloth = world.AddCloth( width: 2f, depth: 2f, segments: 8, at: new Vector3D(0, 2, 0), pinCorners: true); for (int i = 0; i < 120; i++) world.Step(1f / 60); Console.WriteLine($"Corner Y: " + $"{cloth.GetPosition(0).Y:F3}"); // GetPosition(40) is the center particle. Console.WriteLine($"Center Y: " + $"{cloth.GetPosition(40).Y:F3}");
The example needs no input files. It creates a 2 × 2 meter sheet centered at height 2, steps it for two simulated seconds and samples a pinned corner and the center.
AddCloth throws SoftBodyException when a supplied value is out of range.
RecursiveAI.OneMath comes with OnePhysics as a dependency.
Unzip the example, then dotnet run.
Corner Y: 2.000 Center Y: 1.774
Variations
Pin one edge instead of four corners
Create an unpinned sheet, then pin its first row. With eight cells per side, that row has nine particles.
using RecursiveAI.OneMath; using RecursiveAI.OnePhysics.Physics3D; var world = new PhysicsWorld3D(); var cloth = world.AddCloth( width: 2f, depth: 2f, segments: 8, at: new Vector3D(0, 2, 0)); for (int i = 0; i <= 8; i++) cloth.SetPinned(i, true); for (int i = 0; i < 120; i++) world.Step(1f / 60); Console.WriteLine($"Edge Y: " + $"{cloth.GetPosition(4).Y:F3}"); // GetPosition(40) is the center particle. Console.WriteLine($"Center Y: " + $"{cloth.GetPosition(40).Y:F3}");
Edge Y: 2.000 Center Y: 0.982
Related recipes
Start a 3D world · Save and restore a world
The short answer
Use PhysicsWorld3D.AddCloth to create a sheet, pin the particles that should stay fixed, and advance the world with Step. Read the deformed sheet with GetPosition. The program above creates the geometry itself, so you can run it without a mesh file, graphics engine or scene editor.
The important choice is what holds the fabric. Four pinned corners make a suspended sheet. A pinned edge lets the rest hang down. No pins allow the entire sheet to fall. Those are different boundary conditions, not different cloth materials.
How do I simulate cloth in C#?
Start with the generated sheet in the snippet at the top. width and depth are its full extents in meters. at is the center of the sheet, which initially lies in the x–z plane. The segments argument gives the number of cells along each side, not the number of particles. Eight cells produce nine particles per row, and therefore 81 particles in total. The center index in this example is 4 * 9 + 4, or 40.
Call Step at a fixed interval. Here, each step advances the world by one sixtieth of a second; 120 steps advance two simulated seconds. The output shows that the pinned corner stays at its initial height while the center drops. It does not draw the sheet: a renderer needs to consume the updated positions separately.
For an existing graphics mesh, keep its vertex indexing consistent with the simulation mesh. OnePhysics exposes GetPosition for a single particle and CopyPositions for bulk reads. Do not treat a particle’s new position as a rigid transform for the entire sheet: each particle can move independently within the constraints.
What is a soft body?
In OnePhysics, a soft body is a mesh of particles held together by edge, bend and volume constraints. Cloth is an open surface; rubber and jelly presets also support volumetric objects. Use the cloth preset for a sheet rather than treating it as a thin rigid box.
Particles act as small spheres for collisions. The documented collision behavior includes static, kinematic and dynamic rigid shapes, and particle self-collision. The simple example has no floor or other collider, so it isolates sag under gravity and the effect of pinning. A hanging edge can descend below the original sheet’s height without that being a collision failure.
SetPinned(i, true) fixes a particle at its current position. This is useful when you want a whole edge or selected attachment points rather than the four corners provided by pinCorners. A destroyed soft-body handle throws StaleHandleException; do not keep reading it after calling Destroy.
Is cloth simulation a mass-spring model?
OnePhysics documents its soft-body solver as extended position-based dynamics, or XPBD, rather than a mass-spring force model. You configure constraints and their compliance: zero compliance is the stiffest setting. The cloth preset resists stretching, bends easily and enables self-collision.
For more control, SoftBodyDef exposes edge and bend compliance, damping, particle radius, mass and pins. World options include soft-body substeps and iterations. Keep the mesh, attachment pattern and time step fixed while changing one setting, so you can tell which change affects the shape.
This release does not support tearing. A sheet’s constraints can deform its geometry, but you cannot use the example to simulate a rip opening through the fabric.
Source: soft-body guide at the pinned release and the sheet creation API.