ReactPhysics3D  v0.10.2
C++ Physics engine library
Loading...
Searching...
No Matches
reactphysics3d::ConstraintSolverSystem Class Reference

This class represents the constraint solver that is used to solve constraints between the rigid bodies. More...

#include <include/reactphysics3d/systems/ConstraintSolverSystem.h>

Public Member Functions

 ConstraintSolverSystem (PhysicsWorld &world, Islands &islands, RigidBodyComponents &rigidBodyComponents, TransformComponents &transformComponents, JointComponents &jointComponents, BallAndSocketJointComponents &ballAndSocketJointComponents, FixedJointComponents &fixedJointComponents, HingeJointComponents &hingeJointComponents, SliderJointComponents &sliderJointComponents)
 Constructor.
 
 ~ConstraintSolverSystem ()=default
 Destructor.
 
void initialize (decimal dt)
 Initialize the constraint solver.
 
void solveVelocityConstraints ()
 Solve the constraints.
 
void solvePositionConstraints ()
 Solve the position constraints.
 

Detailed Description

This class represents the constraint solver that is used to solve constraints between the rigid bodies.

The constraint solver is based on the "Sequential Impulse" technique described by Erin Catto in his GDC slides (http://code.google.com/p/box2d/downloads/list).

A constraint between two bodies is represented by a function C(x) which is equal to zero when the constraint is satisfied. The condition C(x)=0 describes a valid position and the condition dC(x)/dt=0 describes a valid velocity. We have dC(x)/dt = Jv + b = 0 where J is the Jacobian matrix of the constraint, v is a vector that contains the velocity of both bodies and b is the constraint bias. We are looking for a force F_c that will act on the bodies to keep the constraint satisfied. Note that from the virtual work principle, we have F_c = J^t * lambda where J^t is the transpose of the Jacobian matrix and lambda is a Lagrange multiplier. Therefore, finding the force F_c is equivalent to finding the Lagrange multiplier lambda.

An impulse P = F * dt where F is a force and dt is the timestep. We can apply impulses a body to change its velocity. The idea of the Sequential Impulse technique is to apply impulses to bodies of each constraints in order to keep the constraint satisfied.

— Step 1 —

First, we integrate the applied force F_a acting of each rigid body (like gravity, ...) and we obtain some new velocities v2' that tends to violate the constraints.

v2' = v1 + dt * M^-1 * F_a

where M is a matrix that contains mass and inertia tensor information.

— Step 2 —

During the second step, we iterate over all the constraints for a certain number of iterations and for each constraint we compute the impulse to apply to the bodies needed so that the new velocity of the bodies satisfy Jv + b = 0. From the Newton law, we know that M * deltaV = P_c where M is the mass of the body, deltaV is the difference of velocity and P_c is the constraint impulse to apply to the body. Therefore, we have v2 = v2' + M^-1 * P_c. For each constraint, we can compute the Lagrange multiplier lambda using : lambda = -m_c (Jv2' + b) where m_c = 1 / (J * M^-1 * J^t). Now that we have the Lagrange multiplier lambda, we can compute the impulse P_c = J^t * lambda * dt to apply to the bodies to satisfy the constraint.

— Step 3 —

In the third step, we integrate the new position x2 of the bodies using the new velocities v2 computed in the second step with : x2 = x1 + dt * v2.

Note that in the following code (as it is also explained in the slides from Erin Catto), the value lambda is not only the lagrange multiplier but is the multiplication of the Lagrange multiplier with the timestep dt. Therefore, in the following code, when we use lambda, we mean (lambda * dt).

We are using the accumulated impulse technique that is also described in the slides from Erin Catto.

We are also using warm starting. The idea is to warm start the solver at the beginning of each step by applying the last impulstes for the constraints that we already existing at the previous step. This allows the iterative solver to converge faster towards the solution.

For contact constraints, we are also using split impulses so that the position correction that uses Baumgarte stabilization does not change the momentum of the bodies.

There are two ways to apply the friction constraints. Either the friction constraints are applied at each contact point or they are applied only at the center of the contact manifold between two bodies. If we solve the friction constraints at each contact point, we need two constraints (two tangential friction directions) and if we solve the friction constraints at the center of the contact manifold, we need two constraints for tangential friction but also another twist friction constraint to prevent spin of the body around the contact manifold center.


The documentation for this class was generated from the following files: