BepuPhysics v2 Documentation
repository·master·Indexed 25 days ago
https://github.com/bepu/bepuphysics2A high-performance, C#-based 3D rigid body physics engine targeting .NET 8. It features a wide range of collision shapes (spheres, capsules, boxes, triangles, cylinders, convex hulls, compounds, and meshes), linear and angular continuous collision detection (CCD), and efficient scene-wide ray and sweep queries. The engine is designed for extreme speed, utilizing SIMD intrinsics via System.Numerics.Vectors and System.Runtime.Intrinsics for optimal performance on compatible hardware.
What's inside BepuPhysics v2
- BepuPhysics v2 is a high-performance 3D rigid body physics engine written in C#. It is a complete rewrite of BEPUphysics v1. The engine is designed for speed and supports a wide variety of collision shapes, constraints, and queries. It targets .NET 8 and is compatible with any supported platform.
Core Features of BepuPhysics v2
masterBepuPhysics v2 provides the following capabilities:
- Collision Shapes: Spheres, capsules, boxes, triangles, cylinders, convex hulls, compounds, and meshes.
- Constraints: A wide variety of constraint types available in the
BepuPhysics/Constraints/directory. - Collision Detection: Linear and angular continuous collision detection (CCD).
- Optimization: Extremely low-cost sleep states for resting bodies.
- Queries: Efficient scene-wide ray and sweep queries.
- Specialized Implementations: Includes a character controller example and support for 'Newts'.
- Extensibility: An extensible collision pipeline (e.g., custom voxel collidables).
Understand the design intent and API philosophy of BepuPhysics2
masterBepuPhysics2 is a low-level physics engine designed for maximum performance. It prioritizes performance over safety and ease of use, which means it exposes much of its underlying data directly to the user.
Key characteristics to be aware of:
- Low-level API: The engine provides raw access to data to allow developers to build their own high-level abstractions.
- Performance-optimized storage: Object data is split and packed into specialized formats to leverage SIMD and cache efficiency.
- Uncommon C# idioms: The engine makes heavy use of value types (
struct),refsemantics, pointers, and SIMD instructions. - Manual management: The engine generally allows the user to 'break stuff' in exchange for speed; users are responsible for managing complexity and ensuring correctness.
Developers using this engine should be comfortable with value type semantics, performance-oriented C# features, and memory management.
Manage mobile bodies in v2
masterIn v2, there is no explicit
Bodytype. Instead, bodies are managed throughSimulation.Bodies.- Allocation: Use
Simulation.Bodies.Addto create a body. This returns a handle that uniquely identifies the body. - Access: Use
Simulation.Bodies.HandleToLocationto find the current memory location of a body. - Properties: To access or modify properties like
PoseorVelocity, create aBodyReferencefrom the body handle. Alternatively, you can manually perform lookups into theSimulation.Bodiessets and their raw property buffers for performance.
- Allocation: Use
Understand BepuPhysics v2 versioning and breaking changes
masterBepuPhysics v2 does not follow semantic versioning. When upgrading to a newer version, you should expect breaking changes.
- Compile Errors: Breaking changes are intended to be obvious and should appear as compile errors.
- Behavioral Changes: While the project avoids 'sneaky' behavioral changes that don't cause compile errors, you should not expect different versions of the library to produce identical simulation results due to changes in determinism.
- NuGet Limitations: NuGet packages are available but may not cover all possible features or conditional compilation configurations.
Resolve constraint oscillations and bouncing
masterIf your simulation exhibits unusual oscillations, bouncing, or explosions, it is likely due to constraint instability. This usually stems from either incomplete force propagation or excessive constraint stiffness.
Incomplete Force Propagation
Manifests as bouncing or mild wiggling, often in tall stacks of bodies. The solver fails to converge for all constraints simultaneously.
- Solution: Increase
Simulation.Solver.IterationCount(set this viaSimulation.Create) or increase the frequency ofSimulation.Timestepcalls with a smallerdt. - Note on Mass Ratios: High mass ratios (e.g., a very heavy object depending on a very light one) make convergence difficult. To stabilize extreme mass ratios, try reducing lever arms, adjusting inertias, or adding more paths for impulse propagation.
Excessive Constraint Stiffness
Occurs when constraint frequency is too high relative to the solver update rate.
- Guideline: Avoid using a constraint frequency greater than half of your solver update rate. For example, if the solver runs at 60Hz, keep constraint spring settings at 30Hz or below.
- Solution: If you cannot reduce stiffness, increase the solver's execution rate using substepping or more frequent
Simulation.Timestepcalls.
- Solution: Increase
Build the BepuPhysics Library
masterTo build the library, use the latest version of Visual Studio with the .NET desktop development workload installed. Open and build the
Library.slnfile.Requirements:
- Target Framework: .NET 6
- C# Version: Requires C# 9.0 or later.
- Code Generation:
BepuPhysics.csprojuses T4 templates. If you modify these templates, you must use a build pipeline capable of processing them (such as Visual Studio).
Build a Simulation with Simulation.Create
masterTo create a simulation, use
Simulation.Create. This method requires two callback parameters that must be implemented as structs (not classes) to allow the compiler to inline them and avoid virtual dispatch overhead:TNarrowPhaseCallbacks: Handles collision-related logic such as collision filtering, contact manifolds, and materials. ImplementINarrowPhaseCallbackswithin this struct.TPoseIntegratorCallbacks: Controls per-body velocity integration (e.g., implementing gravity or damping). ImplementIPoseIntegratorCallbackswithin this struct.
Additionally, you must provide a
SolveDescriptionto configure the solver, which allows you to set the number of velocity iterations and substeps. Using more substeps is often more efficient for stabilizing difficult constraints than increasing velocity iterations.Optional parameters include initial allocation sizes for the resource pool and an
ITimestepper(defaults toDefaultTimestepper).Ensure single-machine simulation determinism
masterTo ensure that a simulation produces the same physical results on a single machine given the same inputs, you must:
- Maintain Order: Ensure every interaction with the physics simulation (including the order of adding and removing bodies) is reproduced in the exact same order.
- Configure Determinism: Meet one of the following conditions:
- Run the simulation with a single thread (do not provide an
IThreadDispatcherto the time step function). - Provide multiple threads and set the
Simulation.Deterministicproperty totrue.
- Run the simulation with a single thread (do not provide an
Note: The
Deterministicproperty defaults tofalseand may impact performance in large or chaotic simulations.Include BepuPhysics v2 in your project
masterThere are two primary ways to include BepuPhysics v2 in your project:
- Clone the Source (Recommended): Because the library uses various conditional compilation symbols and NuGet packages may not include all features, the recommended approach is to clone the source repository and reference the project directly in your solution. This ensures you have access to all features and conditional logic.
- NuGet Packages: You can use the official NuGet packages available on NuGet, but be aware they may not cover all possible features.
Run partial performance benchmarks
masterTo run a high-coverage subset of performance tests, use the
-ffilter flag with the following benchmark patterns. This is useful for a quicker execution of core components like collision batching, constraints, and shape tests.-f *CollisionBatcherTaskBenchmarks.* *GroupedCollisionTesterBenchmarks.* *GatherScatterBenchmarks.* *OneBodyConstraintBenchmarks.* *TwoBodyConstraintBenchmarks.* *ThreeBodyConstraintBenchmarks.* *FourBodyConstraintBenchmarks.* *SweepBenchmarks.* *ShapeRayBenchmarks.* *ShapePileBenchmark.* *RagdollTubeBenchmark.*Use substepping to increase solver stability
masterWhen increasing the full simulation update rate (
Simulation.Timestep) is too expensive, use the solver's substepping feature to increase the frequency of the solver and integrator without increasing the frequency of collision detection.To implement substepping, pass a
SolveDescriptionwith the desired number of substeps when callingSimulation.Create.Example behavior: If
Simulation.Timestepis called at 60Hz and you configure 4 substeps, the solver and integrator will effectively run at 240Hz.Optimization Tip: When using high substep counts, you can often reduce the number of solver velocity iterations to save performance. Using 1 velocity iteration with substepping is often a 'sweet spot'.