Collision Detection & Response: Together or Seperate?
let''s say i do something like so:
// returns true if collision happens
bool CollideObjects( Object* A, Object* B );
Now in that function i find out of two objects collide. The question is:
Should the collision response be in the same function as the collision detection?
problem: My system has multiple collision geometries. Different types are inherited from the basic CollisionObject. I have a sphere, polygon, line, and all geometries have a box as well.
In my current system, my objects also have an object "Type" such as Player, Enemy, Weapon, World, etc.. So when i do a collision check, i currently check to see if they collide, then i do the resolution action for those objects.
The difficulty here is that the two things are disassociated and some object types need to knwo about the collision geometry as well. A bouncing ball type of enemy for instance, needs to know how to bounce off other objects. It can''t do that unless it knows the other object''s collision geoetry.
So basically, my problem is that some objects need to know not only if they collided, but need to know how they collided. If i seperate the detection from the response, it''s difficult and i end up with many switch statements and repetetive code. If i merge the two operations together, my cleanly partitioned and Object Oriented system gets real messy.
If you have already come across this issue, which route did you go and how did you go about it?
Thanks for your input.
i dont believe it should,
as you have a method which detects the collision between whatever , you giving the method the two objects.
then have two loops checking each object against each other
eg
[edited by - johnnyBravo on June 3, 2004 11:08:35 PM]
as you have a method which detects the collision between whatever , you giving the method the two objects.
then have two loops checking each object against each other
eg
for(int a=0;a<objCount-1;a++) for(int b=a+1;b<objCount;b++) if(checkCollision(obj[a],obj[b]){ //do bounce etc }
[edited by - johnnyBravo on June 3, 2004 11:08:35 PM]
uh... that doesn''t get at the issue described above. I know how to iterate through a list and compare. What i need to know is if i should react in the same function as i detect. like:
-OR-
foreach object { bool result = TestCollision( Object A, Object B ); if (result) { ReactToCollision( Object A, Object B ); } }
-OR-
void DoCollision( Object A, Object B ) { // do math test for collision here bla bla bla if (got_hit) { // deal with it - // but now i''ve got all the leftover geometry // info from the collision test to work with. Woohoo! } }
So return the useful geometry data as part of the return value of the function. Or, you could have the CollideObjects take a functor of some sort to call when the objects do collide.
Why not, when checking collisions, create some custom struct(s) that will hold all collision information that you desire. Then you can use this information whenever you please.
ie:
so basically then your collision function just needs to fill in this info. Would that work?
ie:
GetCollisionInfo(Object A, Object B, collInfo);where collInfo isstruct collisionInfo {int numPixelsColliding;float percentCollision;blah blah blah};
so basically then your collision function just needs to fill in this info. Would that work?
I was trying to figure out the exact same problem back in April for a game I've been writing. I ended up doing them seperately, mainly I think because of the possibility that even if "CollideObjects" returns true, the objects won't necessarily collide. In my code, as well as returning a boolean, the collision detection function returns the time at which the objects collide. You then have to loop through all the objects in the world, and find the one with the earliest collision time. Only when you've found that can you do your response.
In my code, I store the "collision normal" of each object I detect a collision with, the time of collision, and a pointer to the object, which is so far the only data I have needed to calculate a response. The "collision normal" is the normal to the plane between the objects when they collide, the response is just to slide along this plane. The collision response function has to be called on both the objects involved, with the normal inverted for one of them.
The movement code for an object looks like this:
The function pMap->CollisionDetection is the one that searches through all the objects in the world looking for collisions, and if it finds any returns a pointer to the earliest one, with the time of collision and collision normal as 'out' parameters. Hopefully that makes sense.
[edited by - foolish_mortal on June 4, 2004 5:29:26 PM]
[edited by - foolish_mortal on June 4, 2004 5:31:53 PM]
In my code, I store the "collision normal" of each object I detect a collision with, the time of collision, and a pointer to the object, which is so far the only data I have needed to calculate a response. The "collision normal" is the normal to the plane between the objects when they collide, the response is just to slide along this plane. The collision response function has to be called on both the objects involved, with the normal inverted for one of them.
The movement code for an object looks like this:
REAL time_so_far = 0.0f;while ( time_so_far < time_interval && m_vecVelocity.SquaredMagnitude() > 0.0f ){ REAL time_to_collision; CVector3 vecCollisionNormal; CCollisionObject * pCollisionObject = pMap->CollisionDetection( this, time_interval - time_so_far, time_to_collision, vecCollisionNormal ); time_so_far += time_to_collision; m_vecOrigin += m_vecVelocity * time_to_collision; if ( pCollisionObject ) { pCollisionObject->CollisionResponse( this, -vecCollisionNormal ); CollisionResponse( pCollisionObject, vecCollisionNormal ); }}
The function pMap->CollisionDetection is the one that searches through all the objects in the world looking for collisions, and if it finds any returns a pointer to the earliest one, with the time of collision and collision normal as 'out' parameters. Hopefully that makes sense.
[edited by - foolish_mortal on June 4, 2004 5:29:26 PM]
[edited by - foolish_mortal on June 4, 2004 5:31:53 PM]
i return the collision response as a scalar vector in my collision test. the reason i feel this is important is because not only must you test for collisions, but you must test your responses for collisions as well. wrapping them in a single function,(obviously you''ll break your internal code into several private functions in the case of a class structure) will allow you to recurse nicely thru the entire process, and keep you from exposing your collsion or response code to non-participating modules.
Dredd
________________________________________
"To die with your sword still in its sheath is most regrettable" -- Miyomoto Musashi
Dredd
________________________________________
"To die with your sword still in its sheath is most regrettable" -- Miyomoto Musashi
Thanks for the ideas. I like the idea of returning a data package with collision info in it. My biggest problem with that is that i''m working with multiple collision geometries. Data required to handle a Circle/Polygon collision may not mean much for a Box/Point collision. I need to figure out some basic standard data that can be used. hmmm...
My system is time based, but i''m not doing collision detection along a timeline like a sweep. I should be, but it may be more trouble than it''s worth, i''ve decided.
My system is time based, but i''m not doing collision detection along a timeline like a sweep. I should be, but it may be more trouble than it''s worth, i''ve decided.
quote:Original post by leiavoia
Thanks for the ideas. I like the idea of returning a data package with collision info in it. My biggest problem with that is that i''m working with multiple collision geometries. Data required to handle a Circle/Polygon collision may not mean much for a Box/Point collision. I need to figure out some basic standard data that can be used. hmmm...
My system is time based, but i''m not doing collision detection along a timeline like a sweep. I should be, but it may be more trouble than it''s worth, i''ve decided.
Hmm, maybe then the data package could contain all the data needed by any type of collision, then depending on the collision, you only fill in certain parts of it...would that work?
This is a bit of a tricky situation, and I recently went through the same thing. I finally did what I just mentioned in the last paragraph, cause I wasn''t worried about the minimal extra memory footprint
that would work, actually.
What i''m thinking is to have a struct that has data for any and all possible collisions like you said.
Then you just fill in the required parts in the CheckForCollision() function and also pass in a reference to the struct. Then pass a ref to the same struct to the DealWithCollision() function. So really, there is only one data object. It just gets overwritten a million times.
Thanks for the idea. I''ll certainly look into that.
What i''m thinking is to have a struct that has data for any and all possible collisions like you said.
Then you just fill in the required parts in the CheckForCollision() function and also pass in a reference to the struct. Then pass a ref to the same struct to the DealWithCollision() function. So really, there is only one data object. It just gets overwritten a million times.
Thanks for the idea. I''ll certainly look into that.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement