Jump to content
  • Advertisement

Archived

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

leiavoia

Collision Detection & Response: Together or Seperate?

This topic is 5221 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

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.

Share this post


Link to post
Share on other sites
Advertisement
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

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]

Share this post


Link to post
Share on other sites
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:


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!
}

}



Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
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:


GetCollisionInfo(Object A, Object B, collInfo);

where collInfo is

struct collisionInfo {

int numPixelsColliding;
float percentCollision;
blah blah blah
};



so basically then your collision function just needs to fill in this info. Would that work?

Share this post


Link to post
Share on other sites
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:


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]

Share this post


Link to post
Share on other sites
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


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!