# ParticleTools: Collider

## Patches

• Collider: Kineme3D Object
• Collider: Quad
• Collider: Triangle Structure

## Parameters

Parameter Notes
Backface Culling If enabled, collisions are unidirectional — the collision surface is permeable to objects traveling in the direction of the normal, and is impermeable to objects traveling in the opposite direction.
Bounce Multiplier for the rebounding velocity in the direction of the collision surface's normal. Typically between 0 and 1. When this value is 1, after the collision, the object will have the same normal velocity it started with, but in the opposite direction. When this value is 0, after the collision, the object will stay on the collision surface (unless affected by other forces).
Drag Multiplier for the rebounding velocity in the direction tangental to the collision surface's normal. Typically between 0 and 1. When this value is 0, after the collision, the object will have the same normal-tangent velocity it started with. When this value is 1, after the collision, the object will have zero velocity tangental to the normal of the collision surface (unless affected by other forces).
Range Only applies to the Collider: Quad patch. Defines the bounding box of the quad — the quad's bounds are extended by this amount.

## Use

Colliders operate only on moving objects — if an object is stationary and is crossed by a moving collider, the collider will not interact with it.

## Implementation

VEE uses the OPCODE Collision Detection system.

Here's the VEE code that detects the collision between object `o` and object `m_opcModel`, and then adjusts the object's velocity accordingly.

```   VEE_Vector3 l= o->location() - location();
ICEMATHS_API ICE::Point loc = * ( ICEMATHS_API ICE::Point *) & l;

VEE_Vector3 vel = o->velocity();
VEE_Vector3 dir = vel;
float speed = dir.length();
if(speed > 1.0e-8)
dir *= (1.0f / speed);

m_rayCollider.SetMaxDist(speed * m_dt * 2.0f + 0.1);

ray.mOrig = loc;
dir.normalize();
ray.mDir = * ( ICEMATHS_API ICE::Point *) & dir;

m_rayCollider.Collide(ray, m_opcModel, (const Matrix4x4 *) & m_opcMatrix);

bool contact = m_rayCollider.GetContactStatus();

if(!contact)
continue;

const Opcode::CollisionFace * face = m_collisionFaces.GetFaces();

const VEE_Vector3 normal = m_normals[face->mFaceID];

float gamma = dot(normal, vel);

VEE_Vector3 tangential = vel - gamma * normal;
VEE_Vector3 normalBounce = - gamma * normal;

VEE_Vector3 newVel =
tangential * (1.0f - m_drag) + normalBounce * m_bounce;

o->collision(normal);
o->setVelocity(newVel);```

(from vee-0.1.7/src/extensions/vee_opcode_collision.C)