Skip to content

Collision Pipelines

Collision between objects is split in several phases, each implemented in a different component. Each phase is scheduled by a collision pipeline. The collision pipelines are executed in an animation loop.

The Steps

The collision pipeline follows three steps:

  1. reset of the collision
  2. a collision detection
  3. a collision response

Implementation

A collision pipeline is called from an animation loop through a CollisionVisitor executing the 3 steps of the pipeline in CollisionVisitor::processCollisionPipeline.

The visitor executes the following functions, each corresponding to a step of the pipeline:

/// Remove collision response from last step
void Pipeline::computeCollisionReset()

/// Detect new collisions. Note that this step must not modify the simulation graph
void Pipeline::computeCollisionDetection()
/// Add collision response in the simulation graph
void Pipeline::computeCollisionResponse()

Each of these functions will call a delegate, available in the Pipeline:

/// Remove collision response from last step
void doCollisionReset() override;

/// Detect new collisions. Note that this step must not modify the simulation graph
void doCollisionDetection(const sofa::helper::vector<core::CollisionModel*>& collisionModels) override;
/// Add collision response in the simulation graph
void doCollisionResponse() override;

The 3 delegate functions describe the 3 different steps, and are usually overriden in derived classes. See an example in DefaultPipeline.

Notes: In some cases, the 3 steps are called manually by the animation loop through 3 dedicated visitors (CollisionResetVisitor, CollisionDetectionVisitor and CollisionResponseVisitor). Each of these visitors executes only one step (instead of the 3). This is to avoid race conditions in a multithreaded environment.

Examples of Components

The following components are all collision pipelines, and can be placed in a simulation scene: