Tuesday, March 9, 2010

Collision Overview

Collision detection is one of the very key components of a physics engine. However, collision detection on its own is a much more broad topic. It is important to know what kinds of information your collision detection code should be providing, and the different means of accessing this information.

Generally, the primary thing we want the collision system to do is notify us if two objects are intersecting. As a secondary part of this computation, we often would like to know how to keep the objects from intersecting.

There are a couple of methods I have used, when writing collision systems, to deliver this information.

The first is a direct query method, which has the possible functional prototype

bool CollisionSystem::CollideObjects(const PhysObj& A, const PhysObj& B, ColResData* resolve = NULL);

Such a function would return true if the two objects were intersecting. We may optionally pass in a data structure to retrieve information about how to resolve the collision.

The second method is a bit more automatic. All collision information is passed to the user through callback functions. The collision system accumulates all motion of all objects, and automatically determines which objects need collision processing. If a collision event occurs, a callback function is called.

typedef void (*CollisionHandler)(PhysObj&, PhysObj&, ColResData*);
void collisionHandler(PhysObj& A, PhysObj& B, ColResData* resolve);

The physics objects are not passed in as const because the collision handler may change the state of these objects in order to resolve the collision.

We may want to have several different collision event handlers. For instance, we may want to handle an event which corresponds to objects touching, or an event which corresponds to the moment that they cease to touch. There are several different objects in the world, and we may want a different handler for different object types. Therefore, when we proved the collision system with collision handlers, we must supply the object types, and event types for which the collision handler applies

bool CollisionSystem::AddHandler(CollisionHandler handler, int AType, int BType, ColEventType event);

This function passes in a collision handler, and an int for the types of objects A and B. An int is used so that the user may map these types to any meaning desired. If the function returns false, it was not able to map the collision handler, probably because there is already a handler mapped to the given types and event. The ColEventType is an enum that may contains events like

enum ColEventType
{
ColEvt_OnNear,
ColEvt_Near,
ColEvt_OnIntersect,
ColEvt_Intersect,
ColEvt_Resolve,
ColEvt_OnSeperation,
ColEvt_OnFar
};

We may want to add more collision events, but these cover many of the bases. We want to know if two objects have just gotten near to each other, if they are near to each other, if they have just begun to intersect, if they are intersecting, if we want to resolve the collision, if they have just separated, and if they have just moved away from each other.

The way that we actually process collisions is broken up into three distinct portions
  1. Broadphase - rough estimation if objects are even close to each other
  2. Midphase - determines which parts of a complex object might be colliding
  3. Narrowphase - performs collision on convex primitives, and calculates resolution information

In the following posts, I will discuss each of these topics.

No comments:

Post a Comment