Collision System

Started by
5 comments, last by BloodLust666 17 years, 11 months ago
What's the best approach for creaing a collision system? I know how to test collision, but i mean how should i make the class(es) and whatnot for each collision object. I was thinking of basing it off of the Nuclear Glory idea on how they have different ways of checking the intersection (via ellipses or boxes) except i'm only using 2D (for now), but yea; if anyone has m/b something they've made or would like to give me some advice, i'd appreciate it :) thanks in advance
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
Advertisement


You have a list of entities that are ingame.

Entities have an update function. Each entity has its update function called for every frame.

In the update function you:

-Run AI, entity game logic, player control on the entity.
-Run physics on your entities (origin += velocity, velocity -= velocity * friction)
-Run collision tests against other entities as well as collision tests against the world.
-Render the entity if necessary (within FOV, onscreen, etc).

That's all that comes to mind at the moment. These can be split apart into their own entity functions, and you run a loop through all entities for each function, as opposed to one loop for all functions. Find what suits your project.
I would have collisions performed by a separate collision manager for efficiency reasons (otherwise each entity pair will be checked twice, once by each entity, unless you do some kludgy code to prevent it). You then have a coarse collision test (bounding-box or sphere) that is dead fast (perhaps a bool CoarseCollide(Entity other) method on your Entity class?) and a fine collision test that only gets run between pairs that pass the coarse collision test.
hmm... well, this is what i have so far in my brainstorm notes.

enum eCollisionTest{    rect =0,    circle,    ellipse};class cCollisionObject{private:   entity *pointertoentitytofollow;   eCollisionTest Collisiontype;};class cCollisionManager{private:   struct sCollisionCheck   {      long ObjType;      long ObjToCheck;   };   vector<cCollisionObject>    ObjectList;   vector<sCollisionCheck>     CollisionCheckList;public:   void DefineCollision(long Object, long Objecttocollidewith);     // This fuction will be like the one in nuclear glory.  you define some     // numbers as a type (ie #define ENEMIES 5 #define CHARACTERS 4) then     // when you want the character to be tested on the enemy you would     // do DefineCollision(CHARACTERS, ENEMIES)   void RunCollision(); // Called once per frame};void cCollisionManager::RunCollision(){   for ( Iterate through the ObjectList)   {      for (Iterate through CollisionCheckList)      {         if (current object in objectlist is in collision list)           for (iterate through objectlist minus current object           {               if (if objecttocheck matches in the collisionchecklist, test collision and move appropriately)           }      }   }}


see, this looks like wayyyy too much looping, especially when i'm coming to make bigger demos and even games, the loop will be really long and won't be efficient. is there m/b a different way or if someone has the source of some collision system i can look at, that would help a lot : )

-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML
You may check this thread:

http://www.gamedev.net/community/forums/topic.asp?topic_id=387741&whichpage=1�

I've presented there an algorithm I used for my collision system. It may help you.
Bob has a good idea about fine/course collision detection. I use that in my engine too.

If this is 2D, consider using a unified collision geometry system, preferably convex polygons. Having multiple collision geometry types makes it really awkward. I've tried it.

Use spacial partitioning if you have a lot of objects in a large space. BSP trees or quadtrees or what have you. There are lots of approaches to this.

Don't make collision tests for which it does not make sense. Don't check bullets against other bullets (unless you really want that). This should cut down your number of checks dramatically.

And finally, check combinations, not permutations. If you object list is stored as pointers (and it probably should be), just do this (A and B are pointers to collision objects):

if (A > B) { A->CheckCollision(B); }

This prevents you from doing B->A and only allows A->B. That throws out a lot of extra checking too.

Here is my actual collision loop from my engine. I'm not going to explain it, it's just here for structure ideas. it's a static function inside that collision object class.

void CollisionObject::Cycle( float deltatime ) {	// use this for all collisions	static Vector collision_normal;	static std::vector<CollisionObject*> v;		// foreach item in the active list:	for (std::list<CollisionObject*>::iterator A = active_registry.begin(); A != active_registry.end(); A++) {		// check against objects in the local area:		v.clear(); 		qt->GetObjectsIn( v, *A );				for (unsigned int i=0; i < v.size(); i++) {						CollisionObject* objA = *A;			CollisionObject* objB = v;						// non-permutation check and "i'm not me" check			if ( objB->IsCollisionActive() && objB <= objA ) { continue; } 				 			// Order the objects for table lookup			// NOTE: Keep this here because weapons always need to hit first			if (objA->GetObjType() > objB->GetObjType()) {				CollisionObject* temp = objB;				objB = objA;				objA = temp;				}						// check to see if this pairing is "legal"			if ( collisionLUT( objA->GetObjType(), objB->GetObjType() )  ) {				// Check to see if there is an actual collision				if (  objA->TestBounds(objB)  &&  objA->Collide( *objB, deltatime, collision_normal )  ) {					// perform collision response					objB->Intersect(objA, collision_normal);					objA->Intersect(objB, collision_normal);					}							 				}							} // end of foreach(object in node)		} // end of loop	} // end of function
alright, thanks, this should be enough to look at for a while. if i have any other questions, i'll post again. thanks again
-------------------------Unless specified otherwise, my questions pertain:Windows Platform (with the mindset to keep things multi-platform as possible)C++Visual Studio 2008OpenGL with SFML

This topic is closed to new replies.

Advertisement