Click or drag to resize
DigitalRuneFAQ
General

How can I use a variable time step?

If, for some reason, you want to force the simulation to use a variable time step, then you have to update FixedTimeStep before each SimulationUpdate call:

C#
mySimulation.Settings.Timing.FixedTimeStep = variableTime;
mySimulation.Update(variableTime);

Can I use DigitalRune Physics for 2D games?

The RigidBody class has flags which let you disable rotations about certain axes (e.g, LockRotationX). And you can use constraints like a PointOnPlaneConstraint to keep all movement in the 2D plane. But: A 3D physics engine is more complex than a 2D engine and it has to do additional work to keep objects in a 2D plane. A dedicated 2D engine would be more efficient for pure 2D games.

Bodies pushed by kinematic bodies are not moving correctly

If you use a moving kinematic object, do not change the Pose directly in each frame. Instead, set the velocity (LinearVelocity and AngularVelocity) in each frame and let the simulation compute the new pose.

If you change the pose of a rigid body directly, the simulation "teleports" the body to the new position and does not treat it as a moving body with a non-zero velocity. Collision response between a kinematic and a dynamic body will only be smooth if you use LinearVelocity and AngularVelocity, and let the simulation move the body.

Procedurally controlled bodies are not moving

You may have to disable "sleeping" for the body:

C#
myRigidBody.CanSleep = false;

"Sleeping" means: The simulation is allowed to deactivate slow moving bodies to improve performance and stability. If you apply a velocity which is less than the sleeping threshold, the body does not wake up. See SleepingSettings.

Large, heavy body is not moving

The MassFrame has a limit (MassFrameMassLimit, which, is around 1e10 per default). If an object has a mass beyond this limit, it will be treated like a kinematic body that is not affected by forces or collisions. MassFrameMassLimit is static property that can be changed.

How can I check if a dynamic body has stopped moving?

To find out if a body is done moving, you could check the RigidBodyIsSleeping flag. The simulation sets this flag if a body has stopped moving. See Sleeping. Please note that it is possible that "sleeping" is disabled for a rigid body or that the sleeping settings of the simulation are not suitable for your purpose (e.g. the sleeping time threshold is too large).

You could also manually check if a body is not moving. There are several options, for example:

  1. Choose three points on the body and check if their movement is under a threshold over several frames.
  2. Check if linear and angular velocity is very low for several frames.
  3. Check if kinetic energy of the body is very low for several frames.

Usually, option 2 is used. Please note, that small simulation errors can cause bodies to jitter a bit, therefore these test need to use tolerance values. To get more robust results you could add additional conditions, e.g. "the linear velocity must not be rising".

How can I move a body to a target position over several frames?

There are several options:

  1. Simply change Pose manually step-by-step over several frames. - But be aware that bodies moved this way do not properly push other bodies.
  2. Set a RigidBodyLinearVelocity and RigidBodyAngularVelocity which moves the body to the target position. - Bodies moved this way properly interact with other bodies. But if they hit another heavy body the other body might block them.
  3. Like option 2 but set the RigidBodyMotionType to Kinematic. Kinematic bodies push other dynamic bodies - but there movement is not blocked by other bodies.
  4. Apply forces (AddForce, AddTorque) or use a custom ForceEffect.
  5. Use one of the predefined Constraints or a custom constraint to move the body. Constraints are more stable than using forces.

The solution depends on your requirements and your game physics experience. Constraints provide the most sophisticated solution, but you need more experience to get them right.

How should I handle a large number of static bodies?

First, if not already done, set a broad-phase collision filter that disables collision computation for static vs. static. See the code example in Best Practices and Recommended Literature. Per default, the physics engine computes collisions between two static bodies. The collision info is computed only once - but if you have many static bodies, many contact sets an be generated which needlessly clog the system.

Tip 1: Use a CompositeShape

The broad-phase of the collision detection already uses spatial partitioning to manage all rigid bodies. But each rigid body has an overhead: It can be enabled/disabled, could have individual collision filtering, individual material, etc.. So it is better to reduce the number of rigid bodies and combine them if possible.

Try to create a single rigid body with a CompositeShape that contains all static parts. And set an AabbTreeT as the spatial partition for this composite shape, for example:

C#
compositeShape.Partition = new AabbTree<int>();

This should give you a significant speedup.

The AabbTreeT has a property BottomUpBuildThreshold which you can set to a lower value if the building of the tree takes too long. (In our test-suite, we have a test-level with a composite shape with 80 000 boxes (on PC). The level building takes quite some time, but after creation it runs in real-time.)

Tip 2: Use several CompositeShapes

One extreme is: A single rigid bodies with a composite shape of N parts. The other extreme is: N individual rigid bodies.  The optimal case could lie between those extremes, for example: 10 rigid bodies with 100 parts each. That depends on your level geometry and should be determined by experimentation.

Tip 3: TriangleMeshShape

Using a TriangleMeshShape could be even faster because you only need a vertex and index buffer to define the mesh containing all the parts. The disadvantage of a triangle mesh is that it is sometimes less stable than composite shapes of convex bodies: The triangles are "thin" and that can lead to tunneling and other simulation problems.

Forces and Force Effects

Body controlled by force is not moving

Perhaps you call RigidBodyAddForce only once. In this case the force is applied only for a single time step. To apply a permanent force, the method needs to be called every frame.

How to damp only a single axis of a moving body

Damping is really simple. Damping can be done using a force effect which directly reduces the velocity (without applying any forces). Here is the gist of a damping class:

C#
public class Damping : ForceField  
{  
  public float LinearDamping { get; set; }  
  public float AngularDamping { get; set; }  
  public override void Apply(RigidBody body)  
  {  
    float fixedTimeStep = Simulation.Settings.Timing.FixedTimeStep;  
    body.LinearVelocity = (1 - LinearDamping * fixedTimeStep) * body.LinearVelocity;  
    body.AngularVelocity = (1 - AngularDamping * fixedTimeStep) * body.AngularVelocity;  
  }
}

Following article describes the used damping formula: Damping in Computer Games. You don't even need to use the "exact" formulas or a force effect. Try to simply reduce the angular velocity manually between SimulationUpdate calls (or at SimulationSubTimeStepFinished events if your simulation is sub-stepping):

C#
var localVelocity = body.Pose.ToLocalDirection(body.AngularVelocity); 
localVelocity.X *= 0.9f;        // Damp on a single axis. 
body.AngularVelocity = body.Pose.ToWorldDirection(localVelocity);

Buoyancy: Bodies do not move fluently. Instead, they move, stop, move, stop, and so on.

This could be caused by the rigid body sleeping. Please disable sleeping and check if the problem disappears. (To disable sleeping you just have to set SleepingSettingsTimeThreshold to a large value.)

If sleeping is the culprit, you can create your own Buoyancy effect which wakes up all rigid bodies in the water. Something like:

C#
class MyBuoyancy : Buoyancy
{
  public override void Apply(RigidBody body)
  {
    body.WakeUp();
    base.Apply(body);
  }
}

I want to shoot a body so that it hits a certain target. Which force/impulse do I have to apply?

This link should cover what your looking for: Trajectory of a projectile. Look at the vacuum based formulas. These formulas are also explained in detail in the book "Game Programming Gems 2", chapter "Inverse Trajectory Determination".

When using this formulas in the physics simulation, you will probably not hit the target exactly for two main reasons:

  • The numerical integration used in the simulation is not exact.
  • If the simulation uses a Damping effect: Vacuum-based formulas do not consider damping (a.k.a. drag). You might want to remove damping globally or maybe only for the projectiles (while they are flying).

A quick note on impulses and velocities: If you want to shoot an object, you can apply an impulse. Or you simply set the start velocity of the projectile body directly - without worrying about impulse formulas.

How to use GlobalAreaOfEffect.Exclude

The predicate GlobalAreaOfEffectExclude is a simple callback function. That means you can implement any kind of logic. For example:

C#
// Create a global list of excluded bodies in your game.
public static List<RigidBody> ExcludedRigidBodies = new List<RigidBody>(); 
... 
// The Exclude-predicate checks whether a rigid body is in the list. 
globalAreaOfEffect.Exclude = rigidBody => ExcludedRigidBodies.Contains(rigidBody);

How can I create a custom IAreaOfEffect implementation?

For example:

C#
public class CustomGlobalAreaOfEffect : IAreaOfEffect 
{
  public List<RigidBody> ExcludedRigidBodies { get; private set; }

  public CustomGlobalAreaOfEffect()
  {
    ExcludedRigidBodies = new List<RigidBody>();
  }

  public void Apply(ForceField forceField)
  {
    var simulation = forceField.Simulation;
    if (simulation != null)
    {
      foreach (var body in simulation.RigidBodies)
        if (body.MotionType == MotionType.Dynamic && !ExcludedRigidBodies.Contains(body))
          forceField.Apply(body);
    }
  }
}

Notes: If the number of excluded rigid bodies is large, List<T>.Contains() might be too expensive. You can for example store a flag in RigidBodyUserData and check the flag in the Exclude-predicate. Or you can check RigidBody.CollisionObject.CollisionGroup.

Why do bodies seem to fall a bit slower than in reality?

If the game objects are large, you might have the feeling that the objects fall a bit slower than you would expect in reality - especially if the scene is abstract with no reference objects. This is caused by the scale of the objects - in the real world we observe small falling objects more frequently than huge falling object. For example: Bodies in the samples are usually around 1 m in size, like a big rock or crate in a game. If the bodies would be 1 cm, the falling velocity of the bodies relative to their size would be much higher and feel different.

So the simulation speed is correct - as long as the simulation can keep up with the target frame rate. If the simulation is too slow for the target frame rate, it will drop some simulation time to avoid freezing the game. That means, if the frame rate drops significantly below the target frame rate, the bodies will appear to move in slow-motion. (See also Timing)

Character Controllers

How can I get the velocity of the KinematicCharacterController?

C#
var velocity = (myCharacterController.Position - oldPosition) / deltaTime;

How I can I create a complex character controller where individual limbs can collide with objects (instead of using one capsule shape for the whole character)?

A common approach is to have the character controller capsule that handles the movement and a ragdoll for detailed collision detection with the limbs. You need to disable collisions between the character controller body and the ragdoll bodies (e.g. using CollisionGroup).

If you want to have a very detailed character, you can combine the character controller with a ragdoll and configure collision filters to do this:

  • The capsule collides only with the landscape and big objects, like big crates.
  • Big objects are pushed by the character controller.
  • The capsule does not collide with small objects, like small rocks.
  • The ragdoll collides with the small objects, e.g. to kick small rocks when walking through.
  • The ragdoll collides with the raycasts for arrows and bullets.
  • ...
Ragdolls

What is the difference between velocity motors vs. quaternion motors?

Velocity motors simply set the linear and angular velocities of the bodies in each frame to move the bodies to the target positions. If such motors are used, the ragdoll follows the target animation very closely, and the ragdoll is kept upright. Forces and impacts acting on the bodies have minimal impact because the velocity motors override the bodies' velocities in each frame.

Constraint motors use physics constraints (like QuaternionMotor) to control the relative orientation of the bodies. This is used in the ActiveRagdollSample of the Samples. Since only the relative orientation is controlled, the ragdoll falls to the floor but keeps playing the animation. Bodies controlled by constraints react to impacts.

How can I rotate the ragdoll bodies around the model origin?

Given:

  • The current pose of the rigid body (RigidBody.Pose). Let's call it pWB.
  • The pose of the character/model. Let's call it pWM.
  • A pose which rotates a vector by 90°. Let's call it pR.

Wanted:

  • The pose of the rigid body rotated by 90° relative to model space. Let's call it pWB'.

Solution:

  • pWB' = pWM * pR * pMW * pWB           = pWM * pR * (pWM)^-1 * pWB

Explanation:

  • In the DigitalRune Engine, transformations are applied from right to left. So you have to read the equation from right to left.
  • pWB transforms a vector from the local body space (indicated by the letter B) to world space (W).
  • pMW transforms from world space to model space. pMW is not given but it simply is the inverse of pWM.
  • After applying pMW * pWB, we are in model space. We multiply by pR to apply the rotation relative to the model.
  • Finally we use pWM to convert from model space to world space.

Code example:

C#
myBody.Pose = poseModel * new Pose(Matrix33F.CreateRotationY(MathHelper.ToRadians(90))) * poseModel.Inverse * myBody.Pose;

How to transition from an animated model to a ragdoll-controlled model?

Option A:

While the character is standing, the animation is played. The bodies are dynamic and in each frame the position of the bodies is updated from the animation using RagdollUpdateBodiesFromSkeleton (as in the CollisionDetectionOnlyRagdollSample). After the hit, the bodies update the skeleton using RagdollUpdateSkeletonFromBodies. Since the bodies are dynamic all the time, they will react to the impact. The disadvantage is that while the animation is active the dynamic bodies do not properly push other rigid bodies. - Often this is okay because a character controller is used and takes care of the pushing while the ragdoll is used only for collision detection.

In other words: Start with a Ragdoll with disabled joints, limits and motors.

C#
_ragdoll.Pose = _pose;
_ragdoll.UpdateBodiesFromSkeleton(_skeletonPose);
_ragdoll.DisableJoints();
_ragdoll.DisableLimits();
_ragdoll.DisableMotors();

and in each frame call

C#
_ragdoll.UpdateBodiesFromSkeleton(_skeletonPose);

to move the bodies to upright or animated skeleton position.

Then once you have detected a hit (similar to the CollisionDetectionOnlyRagdollSample), switch to the passive ragdoll:

C#
_ragdoll.EnableJoints();
_ragdoll.EnableLimits();
foreach (RagdollMotor motor in _ragdoll.Motors)
{
  if (motor != null)
  {
    motor.Mode = RagdollMotorMode.Constraint;
    motor.ConstraintDamping = 5;
    motor.ConstraintSpring = 0;
  }
}
_ragdoll.EnableMotors();

and in each frame call

C#
_ragdoll.UpdateSkeletonFromBodies(_skeletonPose);

That means: First the skeleton controls the bodies. After the hit the bodies control the skeleton.

Option B:

You use kinematic bodies and motors as in the KinematicRagdollSample. When the character is hit you make all bodies dynamic and use RagdollUpdateSkeletonFromBodies. Such a character properly pushes other objects while the animation is active. But it will not react to the impact. You can then manually call RigidBodyApplyImpulse to apply an impact impulse (after the bodies were set to dynamic).

Vehicle physics

How to limit the speed of the vehicle?

Option A) Simply clamp LinearVelocity of the chassis body manually after SimulationUpdate. This can look OK with one minor problem: If there is a large instant force (like an explosion), the body can have a larger velocity for one frame.

Option B) Create a constraint that limits the velocity. This is better because it applies the velocity limit inside the simulation update. Here is an example constraint:

C#
class LinearSpeedLimit : Constraint
{
  public float MaxSpeed { get; set; }

  protected override void OnSetup() { }

  protected override bool OnApplyImpulse()
  {
    var speed = BodyA.LinearVelocity.Length;
    if (speed <= MaxSpeed + Numeric.EpsilonF)
      return false;

    BodyA.LinearVelocity = BodyA.LinearVelocity * (MaxSpeed / speed);
    return true;
  }

  public override Vector3F LinearConstraintImpulse
  {
    get { throw new System.NotImplementedException(); }
  }

  public override Vector3F AngularConstraintImpulse
  {
    get { throw new System.NotImplementedException(); }
  }
}

And use it like this:

C#
Simulation.Constraints.Add(new LinearSpeedLimit { BodyA = chassis, BodyB = chassis, MaxSpeed = 50 });