Sign in to follow this  
Boldt

Collision detection Module

Recommended Posts

I have started worked on a generic collision detection module for use in game and physics engines. I was just wondering what queries such a module should support. I have some pretty obvious like contacts for physics engines, intersection queries between primitives and raycast, and cast with a frustum. But are there any more queries that you would suppose a module should support. What kind of groupings should be possible on collision entities and what kind of states for collision entities. So far i have thought about moving and static collision entities. I hope for some advice. Thanks Niels

Share this post


Link to post
Share on other sites
you should implement a mechanism to avoid self collisions, like for example, contiguous links in a chain.

This can be tricky to implement efficiently, but a quick method of culling objects into collidable groups is providing a masking mechanism, which requires the use of bitmasks, and simple operators (& operator mostly). This limits you to 32 separate groups, which may or may not be satisfactory, but it's quick.

Also, another thing I've liked when using collision systems is the implementation of callbacks at various stages of collision events. For example, Give a callback for when two objects are about to be tested. THe callback will then tell the collision system if it should carry on the testing for that pair of objects, or not.

Another one for when the objects collide, obviously. Then you pass the collision informations through the callbacks to other subsystems (physics, for collision response).

That gives a reasonable amount of control over collision events, without too much effort with the interface.

an example


class CCollObject
{
public:
CCollObject(void* pxOwner)
: m_pxOwner(pxOwner)
, m_uCollisionTypeID{0}
, m_uCollisionIgnoreMask{0}
{}

void SetCollisionTypeID(u_int uID) { m_uCollisionTypeID = uID; }
void AddCollisionIgnore(u_int uMask) { m_uCollisionIgnoreMask |= uMask; }
void RemoveCollisionIgnore(u_int uMask) { m_uCollisionIgnoreMask &= ~uMask; }
void SetCollisionIgnore(u_int uMask) { m_uCollisionIgnoreMask = uMask; }


private:
void* m_pxOwner;
u_int m_uCollisionTypeID;
u_int m_uCollisionIgnoreMask;
};

class CCollSystem
{
public:
CCollSystem()
: m_pfnPreCollisionCallBack(NULL)
, m_pfnPostCollisionCallBack(NULL)
{}

void SetPreCollisionCallBack(bool (*pfnPreCollisionCallBack)(CCollObject* pxObjA, CCollObject* pxObjB)) { m_pfnPreCollisionCallBack = pfnPreCollisionCallBack; }

void SetPostCollisionCallBack(bool (*pfnPostCollisionCallBack)(CCollReport* pxReport)) { m_pfnPostCollisionCallBack = pfnPostCollisionCallBack; }

void FindAllCollisions()
{
for(int i = 0; i < m_lpxCollObjects.size(); i ++)
{
for(int j = i+1; j < m_lpxCollObjects.size(); j ++)
{
if (m_lpxCollObjects[i].GetCollisionTypeID() & m_lpxCollObjects[j].GetCollisionIgnoreMask())
{
continue;
}
if (m_lpxCollObjects[j].GetCollisionTypeID() & m_lpxCollObjects[i].GetCollisionIgnoreMask())
{
continue;
}
if (m_pfnPreCollisionCallBack && !m_pfnPreCollisionCallBack(m_lpxCollObjects[i], m_lpxCollObjects[j])
{
continue;
}

TestCollisions(m_lpxCollObjects[i], m_lpxCollObjects[j]);
}
}
}

void TestCollisions(CCollObject* pxObjA, CCollObject* pxObjB)
{
CCollReport xCollReport;

if(pxObjA->Collide(pxObjB, &xCollReport))
{
if(m_pfnPostCollisionCallBack)
{
m_pfnPostCollisionCallBack(&xCollReport);
}
}
}

private:
bool (*m_pfnPreCollisionCallBack)(CCollObject* pxObjA, CCollObject* pxObjB);
bool (*m_pfnPostCollisionCallBack)(CCollReport* pxReport);

list<CCollObject*> m_lpxCollObjects;
};




Share this post


Link to post
Share on other sites
I can see your point with the collision groups. The way I thought about them was to have an 'in theory' unlimited number of groups. Then you could use collision notifications to control a lap counter for a car game etc.

But what if you separates my idea from the collision module and creates another module that have a more flexible grouping of objects and put this on top of the collision module. Would that be useable? You could then use this module if you wanted and still have the limited flexibility in the core collision module.

Self Intersection: What about having an articulated CCollObject something like
 
class ArticulatedCCollObject : public CCollObject {


public:

///tells what collision must be reported inside the articulated entity
unsigned mCollisionMode;
///we have the following options
const unsigned NO_SELFINTERSECTION = 0x1;
const unsigned NO_NEIGHBOURINTERSECTION = 0x2;
const unsigned SELFINTERSECTION = 0x4;

};




You will treat this object as an ordinary CCollObject when doing intersection test in bounding volume hierarchies and first when you enter the narrowphase you will start thinking about the internal nodes of the object.

Is it necessary to have m_uCollisionIgnoreMask for each object. Would it not be better to have a global control of this, so you dont have to update each entity, or am I overlooking something here.

Thanks
Niels

Share this post


Link to post
Share on other sites
Quote:
Original post by Boldt
Self Intersection: What about having an articulated CCollObject something like
*** Source Snippet Removed ***

You will treat this object as an ordinary CCollObject when doing intersection test in bounding volume hierarchies and first when you enter the narrowphase you will start thinking about the internal nodes of the object.


I don't really like grouping elements into one collision entity. Rather, each bit that forms an unmovable entity should be clustered together, like say, a seat (4 cylindrical legs, and a disk on top). Things like chains, each node would be it's own collisoin object.

Quote:
Original post by Boldt
Is it necessary to have m_uCollisionIgnoreMask for each object. Would it not be better to have a global control of this, so you dont have to update each entity, or am I overlooking something here.


Each object belongs to one group (usually, just one bit of the group set), and is ignoring a whole numbers of objects, so each objects have independant masks.

TO be fair, is objects are of type 1, they should all be ignoring the same objects too. The use of bitmasks is very quick, and can work for small scale systems. It's the way Math Engine used to work, if I remember correctly, a long time ago.

The problem is not grouping per-se, but quickly deciding if a collision should be performed or not. If you spend as much time filtering objects as testing collisions, then you have a problem.

Quote:
Original post by Boldt
But what if you separates my idea from the collision module and creates another module that have a more flexible grouping of objects and put this on top of the collision module. Would that be useable? You could then use this module if you wanted and still have the limited flexibility in the core collision module.


-> Ditto. That filtering can be done outside the collision system, of course, then you use the callbacks to skip a collision test or not.

Share this post


Link to post
Share on other sites

Quote:

I don't really like grouping elements into one collision entity. Rather, each bit that forms an unmovable entity should be clustered together, like say, a seat (4 cylindrical legs, and a disk on top). Things like chains, each node would be it's own collisoin object.


The reason I wanted to do this is because I want to use spatial coherency. The links in the chain will probably be close together, so I thinks it makes good sense to consider them as one entity in a possible broadphase part of the collision detection module.

Then I could group maybe 20 or fifty objects together.

Off course you will only group objects, that you know have some spatial relationship

Best Regards
Niels

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this