Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Doz

OOP Collision Detection

This topic is 5475 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m currently trying to implement some kind of pretty OOP collision detection in my game with arbitrary collision shapes. Each sprite in the game is represented by a Sprite class that has a Geometry member. This stores its bounding shape for collision. From the Geometry class I derive Circle, AABB, etc. When updating the sprites, I loop through a linked list containing all the sprites and get a Geometry* pointer from each using a member function called GetBoundingGeometry. Fine. So I need to do intersection testing on this geometry. I was thinking that each derived shape class (Circle, AABB, etc.) would have an Intersects function for each other geometry type e.g. Circle::Intersects(AABB *x). The problem is that I only get Geometry* pointers (base class), so I can''t call the right Intersects function without using an ugly switch statement or something. Does anyone know a better way of doing all this?

Share this post


Link to post
Share on other sites
Advertisement
Yes virtual functions. This would work like this :

As the instances of your specific classes have a hidden class ID (a pointer to a virtual table that contains their derived virtual functions) then for instance :

Say A is a Sphere, B a Box and Geom the base class.

then A.Collision( B );

calls Sphere::Collision( Geom &B ); for Sphere A, that tests a sphere against any other Geom.

then this function could be defined as

void Sphere::Collision( Geom &B )
{
B.Collision( *this );
// as *this (A) is known as a Sphere here and B is a Box this calls
// Box::Collision( Sphere &A );
}
Note : if the compiler does not know the class of A (seen as a base class element) then this can not be inlined. And this should normally be the case.

void Box::Collision( Sphere &A )
{
// The real stuff may be a call to Sphere::Collision( Box& ) because
// I suppose you wont define both Sphere/Box and Box/Sphere
// so there are 2 or 3 indirections, that's the drawback.
}

Else you can create your own virtual array of function pointers with double indexation, and a test of explicit ID order to switch the pointers if required. Thus you would only call one function instead of 2 or 3. But this would be hard to manage.

Someone correct me if I am wrong.

[edited by - Charles B on June 18, 2003 5:25:58 AM]

Share this post


Link to post
Share on other sites
Thanks, having to do the indirections is a bit wasteful but necessary i guess.

I''ll probably do the sphere/box, box/sphere testing in a separate friend function that is called by each class to avoid code duplication.

Cheers.

Share this post


Link to post
Share on other sites
try this method (called a visit function or something). It test the unknow-typed object against a ''this'' pointer, which is of a known type.


class cCollSphere: public cCollObject
{
public:
virtual bool VisitIntersect(const cCollObject* pCollObject)const
{
return pCollObject->Intersect(this);
}

virtual void Intersect(const cCollSphere* pSphere ) const
{
......
......
......
}
virtual void Intersect(const cCollRect* pRectangle) const
{
return pRectangle->Intersect(this);
}
};

class cCollRect: public cCollObject
{
public:
virtual bool VisitIntersect(const cCOllObject* pCollObject) const
{
return pCollObject->Intersect(this);
}

virtual void Intersect(const cCollSphere* pSphere ) const
{
......
......
......
}
virtual void Intersect(const cCollRect* pRectangle) const
{
......
......
......
}
};


Share this post


Link to post
Share on other sites
so, you obviously call the VisitIntersect() function instead of the Intersect() functions directly.

I''d guess you could still get rid of the ''Visit'' part in the function name (like (virtual bool Intersect(const cCOllObject* pCollObject) const {}), but it migh confuse the compiler, or even confuse you a bit .

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Double dispatch.

Share this post


Link to post
Share on other sites
There is an important issue with double dispatch: every time a new shape is added, all shapes must be modified in order to collide with it.

An alternative is to build a map (at runtime) that contains pointers to the collision functions. The key for each entry containes the two type ids of the classes that the function operates on. When you want to collide two objects, look up the collision function in the map and call it.

The advantage is that adding a new shape only requires adding new entries to the map. The drawback is the additional overhead of the map lookup.

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!