Skip to main content

Rigid Actors

Rigid actors represent non-deformable bodies. They serve as standalone dynamic or static objects and as the building blocks for more complex constructs such as articulated bodies.

A rigid actor's state is fully described by a position (Real3) and an orientation (Quaternion), and solution updates can be parameterized in terms of 6 independent degrees of freedom (DoFs; 3 translational and 3 rotational).

Static vs. Dynamic

Certain rigid actors can have their positions prescribed directly by setting the isStatic / is_static flag. Static actors may still act as colliders for other actors, but they do not respond to contact reactions or other external forces. While the term "static" may suggest that static actors are stationary (and this is often true), they can still move with nonzero velocity if their prescribed positions are updated at each time step. Common use cases for static actors are environmental obstacles such as ground planes, walls, tables, and similar. The remainder of this page is concerned with modeling dynamic rigid actors.

Formulation

Continuous Model

Let BR3\mathcal B\subset \mathbb{R}^3 be a rigid body's volume in a reference configuration. Its mass and center of mass are

m=BρdXandXCoM=1mBρXdX ,m=\int_{\mathcal B}\rho\,d\mathbf{X} \qquad\text{and}\qquad \mathbf{X}_\mathrm{CoM}=\frac{1}{m}\int_{\mathcal B}\rho\,\mathbf{X}\,d\mathbf{X}~,

where ρ\rho is the mass density field and X\mathbf{X} is a material point in the body. For the remainder of this discussion, use a body frame centered at the center of mass, with axes aligned with the actor's local frame, and define the body-frame offset r=XXCoM\mathbf{r}=\mathbf{X}-\mathbf{X}_\mathrm{CoM}. Let c\mathbf{c} be the world-space center of mass and let RSO(3)\mathbf{R}\in\mathrm{SO}(3) be the world-from-body rotation, which is also the rotation of the actor's worldFromLocal transform. The position c\mathbf{c} is the world-space image of the centerOfMass parameter and, in general, differs from the translation of worldFromLocal.

The mass second-moment tensor in the body frame is

J=BρrrTdX .\mathbf{J}=\int_{\mathcal B}\rho\,\mathbf{r}\mathbf{r}^T\,d\mathbf{X}~.

For some vector aR3\mathbf{a}\in\mathbb{R}^3, the corresponding skew-symmetric matrix skew(a)\operatorname{skew}(\mathbf{a}) is defined by

skew(a)b=a×bbR3 .\operatorname{skew}(\mathbf{a})\mathbf{b}=\mathbf{a}\times\mathbf{b}\quad\forall\mathbf{b}\in\mathbb{R}^3~.

The body-frame angular velocity Ω\boldsymbol{\Omega} then satisfies

R˙=Rskew(Ω) .\dot{\mathbf{R}}=\mathbf{R}\operatorname{skew}(\boldsymbol{\Omega})~.

Let I=tr(J)1J\mathbf{I} = \operatorname{tr}(\mathbf{J})\mathbf{1}-\mathbf{J} be the conventional moment-of-inertia tensor about the center of mass. The kinetic energy decomposes into translational and rotational contributions

T=Ttrans+Trot ,T=T_\mathrm{trans}+T_\mathrm{rot}~,

where

Ttrans=12mc˙22andTrot=12ΩTIΩ=12ωTRIRTω=12tr ⁣(R˙JR˙T) .T_\mathrm{trans}=\frac{1}{2}m\left\Vert\dot{\mathbf{c}}\right\Vert_2^2 \qquad\text{and}\qquad T_\mathrm{rot} =\frac{1}{2}\boldsymbol{\Omega}^T\mathbf{I}\boldsymbol{\Omega} =\frac{1}{2}\boldsymbol{\omega}^T\mathbf{R}\mathbf{I}\mathbf{R}^T\boldsymbol{\omega} = \frac{1}{2}\operatorname{tr}\!\left(\dot{\mathbf{R}}\mathbf{J}\dot{\mathbf{R}}^T\right)~.

The second form of rotational energy reexpresses the first in terms of the world-space angular velocity ω=RΩ\boldsymbol{\omega}=\mathbf{R}\boldsymbol{\Omega}. The first form can be recovered from the third by invoking the expression of R˙\dot{\mathbf{R}} above and inverting the definition of I\mathbf{I} in terms of J\mathbf{J}.

For a constant world-space force f\mathbf{f} applied at body-frame offset r\mathbf{r} from the center of mass, the external potential contributing to the general dynamics formulation is

Uext=Utrans+Urot ,U_\mathrm{ext}=U_\mathrm{trans}+U_\mathrm{rot}~,

where

Utrans=fcandUrot=fRr .U_\mathrm{trans}=-\mathbf{f}\cdot\mathbf{c} \qquad\text{and}\qquad U_\mathrm{rot}=-\mathbf{f}\cdot\mathbf{R}\mathbf{r}~.

For multiple loads, these potentials are summed. Other (possibly non-conservative) forces on rigid actors typically arise from interactions like contact or constraints, as documented on separate dedicated pages.

Discretization

Time discretization of the translational term of kinetic energy TtransT_\mathrm{trans} follows straightforwardly from the generic recipe outlined for systems whose configurations are in linear spaces with configuration-independent mass matrices. The discretization of rotational inertia, on the other hand, involves some nontrivial choices, which are discussed in the remainder of this section.

The first expression for TrotT_\mathrm{rot} above may initially look like a quadratic form in angular velocity, but Ω\boldsymbol{\Omega} is defined in a frame following the body's rotation, which introduces an implicit dependence on rotational state. This emerges as a gyration term when deriving the Newton–Euler equations of motion from variational arguments, and is made more explicit by the second form using world-space angular velocity ω\boldsymbol{\omega}, where the mass matrix clearly depends on rotational state. The default incremental-potential discretization of rotational inertia in SuperDex Physics is instead derived from the third form, following the approach of Ferguson et al. (2021), but using the Lie algebra linearization of Romanyà-Serrasolsas et al. (2025) to formulate the discrete residual and Newton Jacobian. While the cited references formulate an incremental potential for backward Euler integration of rotational inertia, we generalize this to the implicit stage problem of our unified time integration framework.

At stage ii, define the discrete rotational velocity by the finite difference

R˙i=RiRi0Δti .\dot{\mathbf{R}}_i=\frac{\mathbf{R}_i-\mathbf{R}_i^0}{\Delta t_i}~.

Here R˙i\dot{\mathbf{R}}_i denotes this stage difference, not the exact derivative R˙(t)\dot{\mathbf{R}}(t) of a continuous rotation trajectory. For an exact rotation rate, right multiplication by RT\mathbf{R}^T gives the skew-symmetric world-frame angular-velocity matrix R˙RT=skew(ω)\dot{\mathbf{R}}\mathbf{R}^T=\operatorname{skew}(\boldsymbol{\omega}). Applying the same operation to the stage difference generally also produces a symmetric part. SuperDex Physics therefore decomposes it as

R˙iRiT=skew(ωi)+Si ,\dot{\mathbf{R}}_i\mathbf{R}_i^T=\operatorname{skew}(\boldsymbol{\omega}_i)+\mathbf{S}_i~,

where skew(ωi)\operatorname{skew}(\boldsymbol{\omega}_i) and Si\mathbf{S}_i are respectively the skew-symmetric and symmetric parts of the left-hand side. Equivalently,

R˙i=(skew(ωi)+Si)Ri .\dot{\mathbf{R}}_i=\left(\operatorname{skew}(\boldsymbol{\omega}_i)+\mathbf{S}_i\right)\mathbf{R}_i~.

The symmetric term Si\mathbf{S}_i is not an additional physical velocity; it retains the part of the finite-difference rotation velocity that would be lost if only ωi\boldsymbol{\omega}_i were stored. After each stage, SuperDex Physics stores the pair (ωi,Si)(\boldsymbol{\omega}_i,\mathbf{S}_i) as its rotational velocity state. For the simplest case of backward Euler, the stage-start rotation and velocity representation are simply the previous completed step's solution: Ri0=Rn\mathbf{R}_i^0 = \mathbf{R}_n, ωi0=ωn\boldsymbol{\omega}_i^0 = \boldsymbol{\omega}_n, and Si0=Sn\mathbf{S}_i^0 = \mathbf{S}_n. When generalizing to our unified multistep/multistage framework, the stage-start and completed-step solutions are reconstructed from prior and intermediate states as discussed below.

The stage-start rotation and rotational velocity then define the predictor

R~i=Ri0+Δti(skew(ωi0)+Si0)Ri0 .\widetilde{\mathbf{R}}_i=\mathbf{R}_i^0+\Delta t_i\left(\operatorname{skew}(\boldsymbol{\omega}_i^0)+\mathbf{S}_i^0\right)\mathbf{R}_i^0~.

The rotational contribution to the stage incremental potential is

Φi,rot=12Δti2tr ⁣((RiR~i)J(RiR~i)T)=1Δti2tr ⁣(RiJR~iT)+C ,\begin{aligned} \Phi_{i,\mathrm{rot}} &=\frac{1}{2\Delta t_i^2}\operatorname{tr}\!\left((\mathbf{R}_i-\widetilde{\mathbf{R}}_i)\mathbf{J}(\mathbf{R}_i-\widetilde{\mathbf{R}}_i)^T\right) \\ &=-\frac{1}{\Delta t_i^2}\operatorname{tr}\!\left(\mathbf{R}_i\mathbf{J}\widetilde{\mathbf{R}}_i^T\right)+C~, \end{aligned}

where CC may vary from step to step, but is independent of the stage-end rotation Ri\mathbf{R}_i, so it may safely be omitted from the incremental potential. The second equality uses the invariance of tr(J)\operatorname{tr}(\mathbf{J}) under rotational similarity transforms and is helpful for simplifying Lie derivatives used in the implementation.

Solution Reconstruction

Because rotations form a nonlinear Lie group, the linear combinations in the general time integration method are instead evaluated in the Lie algebra relative to a base rotation. For base Rb\mathbf{R}_b, the Lie-algebra linear combination of rotations {Rj}\{\mathbf{R}_j\} with coefficients {cj}\{c_j\} is given by

C ⁣(Rb;{(cj,Rj)})=exp ⁣(skew ⁣(jcjlog ⁣(RjRbT)))Rb .\mathcal{C}\!\left(\mathbf{R}_b;\{(c_j,\mathbf{R}_j)\}\right) =\exp\!\left(\operatorname{skew}\!\left(\sum_j c_j\log\!\left(\mathbf{R}_j\mathbf{R}_b^T\right)\right)\right)\mathbf{R}_b~.

Here exp\exp is the matrix exponential on so(3)\mathfrak{so}(3), evaluated by the Rodrigues formula: for a rotation vector θ=θu\boldsymbol{\theta}=\theta\mathbf{u} with angle θ\theta and unit axis u\mathbf{u},

exp ⁣(skew(θ))=1+sin(θ)skew(u)+(1cos(θ))skew(u)2 .\exp\!\left(\operatorname{skew}(\boldsymbol{\theta})\right) =\mathbf{1}+\sin(\theta)\operatorname{skew}(\mathbf{u}) +\left(1-\cos(\theta)\right)\operatorname{skew}(\mathbf{u})^2~.

The map log\log denotes its inverse: log(R)\log(\mathbf{R}) is a rotation vector θ\boldsymbol{\theta} with θ2π\Vert\boldsymbol{\theta}\Vert_2\leq\pi such that R=exp(skew(θ))\mathbf{R}=\exp(\operatorname{skew}(\boldsymbol{\theta})). The three rotation reconstructions corresponding to the general time integration formulas are then

Rn=C ⁣(Rn;{(αr,Rn+1r)}r=1l) ,Ri0=C ⁣(Rn;{(a~ij,Rj)}j=1i1) ,Rn+1=C ⁣(Rn;{(b~i,Ri)}i=1s) .\begin{aligned} \mathbf{R}_n^\star &=\mathcal{C}\!\left(\mathbf{R}_n;\{(\alpha_r,\mathbf{R}_{n+1-r})\}_{r=1}^l\right)~, \\ \mathbf{R}_i^0 &=\mathcal{C}\!\left(\mathbf{R}_n^\star;\{(\widetilde a_{ij},\mathbf{R}_j)\}_{j=1}^{i-1}\right)~, \\ \mathbf{R}_{n+1} &=\mathcal{C}\!\left(\mathbf{R}_n^\star;\{(\widetilde b_i,\mathbf{R}_i)\}_{i=1}^s\right)~. \end{aligned}

Thus, the most recent completed rotation Rn\mathbf{R}_n is the base for constructing Rn\mathbf{R}_n^\star, while Rn\mathbf{R}_n^\star is the base for both the stage-start and completed-step reconstructions.

Properties of the Discrete Problem

The derivation of the discrete equations from an incremental potential results in a symmetric Newton Jacobian and allows for the use of nonlinear solution techniques that are specialized to problems with optimization structure. It is therefore preferred for robustness in complicated nonlinear problems, where rigid bodies interact with other systems through contact and constraints. However, unlike some other discretizations of rigid body dynamics, this formulation does not provide exact conservation of angular momentum or rotational kinetic energy at finite time step sizes, only convergence in the limit of Δt0\Delta t \to 0. It may introduce noticeable dissipation at moderate-to-large time step sizes.

A nonlinear residual that directly discretizes the Newton–Euler equations without deriving from an incremental potential is available as an experimental feature, and can be selected with experimental::EnableNewtonEulerInertia. This formulation may provide higher accuracy in certain limiting cases, such as applying a constant torque along a principal axis of a free-floating rigid body initialized to rotate about that axis. In this case, at a fixed time step size, the default formulation's dissipation will cause the angular velocity to asymptote to a constant value rather than continuing to increase linearly. While exact conservation properties may provide satisfying solutions to simple test problems, they are rarely needed in practical scenarios, where numerous dissipative mechanisms are often at play. For robust nonlinear convergence in complex scenes, it is recommended to use the default rotational inertia formulation with a time step size that provides sufficient accuracy for a given application.

Creating Rigid Actors

Dynamic Rigid Body

// Load a sphere mesh shape
ShapeHandle sphereShape = context->LoadShapeFromFile(
"sphere/icosphere_3subdiv.1.mochi.json",
Real3{0.2_r, 0.2_r, 0.2_r}, // bake scale
error);

// Create a dynamic rigid sphere
RigidActorParams params;
params.name = "sphere";
params.shape = sphereShape;
params.density = 1000_r; // kg/m^3
params.colliderType = ColliderType::Sphere;
params.worldFromLocal = TransformRT(Real3{0_r, 1.2_r, 0_r});

Actor* sphere = scene->CreateRigidActor(params, error);

Static Rigid Body (Ground Plane)

// Create an implicit plane shape (no mesh needed)
ShapeHandle planeShape = context->CreatePlaneShape(
Real3{0_r, 1_r, 0_r}, // normal (Y-up)
0_r, // distance from origin
error);

// Create a static ground plane
RigidActorParams params;
params.name = "ground";
params.shape = planeShape;
params.isStatic = true;
params.colliderType = ColliderType::Plane;

Actor* ground = scene->CreateRigidActor(params, error);

Setting Initial Velocity

Dynamic rigid actors can be given an initial linear and/or angular velocity at creation time.

RigidActorParams params;
params.name = "projectile";
params.shape = shape;
params.density = 1000_r;
params.linearVelocity = Real3{0_r, -1_r, 0_r}; // downward at 1 m/s
params.angularVelocity = Real3{0_r, 0_r, 3.14_r}; // spinning about Z

Actor* projectile = scene->CreateRigidActor(params, error);

Parameters Reference

RigidActorParams

The creation fields are defined by RigidActorParams (C++, Python).

ParameterC++ TypePython NameDefaultDescription
nameDynamicStringname""Human-readable name for the actor.
layerDynamicStringlayer""Contact layer. Contact can be selectively enabled or disabled between actors on the same or different layers.
shapeShapeHandleshape(none)Handle to the shape geometry. Created via LoadShapeFromFile, CreatePlaneShape, CreateTriMeshShape, etc.
worldFromLocalTransformRTworld_from_localIdentityInitial transform (rotation + translation) of the actor in world space.
colliderTypeColliderTypecollider_typeAutoCollision geometry representation used by other actors to detect contact with this actor. See Collider Representations.
isStaticboolis_staticfalseIf true, the actor has infinite mass and is not moved by the solver.
contactContactParamscontact(defaults)Contact and friction parameters. See Contact Parameter Reference.
sdfGridSdfParamssdf(defaults)Grid SDF resolution and padding parameters. Only relevant when colliderType is Sdf.
hasGravityboolhas_gravitytrueWhether gravity is applied to this actor. Ignored for static actors.
densityoptional<real>density(unset)Material density in kg/m^3. Used to compute mass, center of mass, and inertia from the shape geometry.
massoptional<real>mass(unset)Total mass in kg. Overrides density-based mass computation.
centerOfMassoptional<Real3>center_of_mass(unset)Center of mass in the actor's local frame. If unset, computed from the shape assuming uniform density.
momentOfInertiaoptional<Real6>moment_of_inertia(unset)Upper-triangle of the 3x3 rotational inertia tensor (Ixx, Ixy, Ixz, Iyy, Iyz, Izz). If unset, computed from the shape.
boundaryElementTypeActorBoundaryElementTypeboundary_element_typeDefault (P1Q3)Quadrature order for boundary surface integrals used in contact evaluation.
boundarySubsamplingoptional<BoundarySubsamplingParams>boundary_subsampling(unset)Optional subsampling of boundary elements for contact.
linearVelocityoptional<Real3>linear_velocity(unset)Initial linear velocity in m/s.
angularVelocityoptional<Real3>angular_velocity(unset)Initial angular velocity in rad/s (rotation vector).

Mass and Inertia

For dynamic rigid actors, mass properties are required for integration. The density, mass, centerOfMass, and momentOfInertia parameters can be combined in several ways:

  1. From density — Provide density and SuperDex Physics computes total mass, center of mass, and rotational inertia from the shape geometry automatically.
  2. Explicit mass — Set mass directly. If the inertia tensor is not provided, it is derived from the shape geometry and scaled to match the specified mass.
  3. Explicit mass and inertia — Set mass, centerOfMass, and momentOfInertia directly. Useful when mass properties are known from a CAD model or URDF file.
caution

Do not set both density and mass at the same time. If neither is specified, a default density is used. If centerOfMass or momentOfInertia is provided without the other, the missing value is computed assuming uniform density.

Shapes

Rigid actors support several shape types:

Shape TypeCreation MethodTypical Use
PlaneCreatePlaneShape / create_plane_shapeGround planes, infinite walls
Triangle meshCreateTriMeshShape / create_tri_mesh_shapeArbitrary surface geometry defined programmatically
Mesh from fileLoadShapeFromFile / load_shape_from_filePre-built mesh assets (.mochi.json, .mochi.h5)
Sphere (implicit)CreateSphereShape / create_sphere_shapeAnalytically defined spheres
Box (from tetmesh)Tetmesh utility functionsBox colliders with volumetric mesh

The shape defines the visual and collision geometry. The colliderType parameter then controls which collision representation is used at runtime (SDF, bounding sphere, AABB, etc.).

For full details on shape creation and management, see the Shapes page.

Role in Articulated Bodies

Rigid actors also serve as the links (bones) within articulated body actors. In that context, individual rigid links do not own independent degrees of freedom — their transforms are derived from the joint states of the parent articulated actor. The RigidActorParams struct is reused as the linkParams array in ArticulatedActorParams. See Articulated Actors for details.

Examples

  • Rigid Bodies: demonstrates a sphere and cube falling onto a table, and four ways to create shapes and actors. Python example: examples/example_rigid_bodies.py.
  • Articulated Actors — Rigid links connected by joints, forming kinematic trees.
  • Contact — Contact formulation, collider representations, friction, and filtering.
  • Shapes — Shape creation, loading, and management.
  • Constraints — Attaching rigid actors to other actors or to world-space anchors.
  • Solvers — Newton solver, linear solvers, and time integration methods.

References