Basic collision response problem

Started by
3 comments, last by roos 19 years, 4 months ago
Hi, I am working on a demo that lets you drive around and crash into other cars... The collision detection is very basic, it's just a circle-circle intersection test. The collision response is linear (so no angular effects). Right now, if I ram two cars together at a high velocity, they will bounce off of each other just fine. However, suppose the cars are just separated by 1 inch. Then you hold down on the acceleration. What happens currently is, you move forward an inch, collide instantly, then get bounced away, and then keep colliding again and again. But, since your velocity is so small (since you're only 1 inch away there's no time to accelerate), the collisions happen pretty much one right after another, so the collision sound effect is played like 60 times in one second. In fact, if the amount you get bounced away is less than the tolerance for detecting a collision vs. a penetration, then it will even freeze because it is constantly detecting a collision... So, does anyone know of any good way to prevent this kind of thing happening? For now, my idea is, if you detect a collision and the relative velocity between the two objects (v1 - v2) has a magnitude less than some number, then instead of treating it as an official "collision", simply undo the collision by reverting both objects to their previous position. Thanks, roos
Advertisement
sounds like you just need to do something like this

if(car1.velocity > X && (Collision(car1,car2) == true))
{
do_collsion_stuff();
};

thats sudo code because i dont know your code but hopefully your collision detection is simaler

[grin]hope i helped
____________________________"This just in, 9 out of 10 americans agree that 1 out of 10 americans will disagree with the other 9"- Colin Mochrie
Raptorstrike's example will work for collisions when the care is moving forwards. If you want to handle reversing collisions as well, you may have to do something a little more complex.

Assuming that you use posetive velocity for forwards, and negative velocity for backwards, and X is the minimum velocity (in either direction) that you want to detect a collision, the following process should work.

if(Collision(car1, car2)==true){   // Forward collision   if( !car1.collisionFlag &&       ( car1.velocity > X   ||         car1.velocity < -X  )   {      car1.collisionFlag = true;      do_collsion_stuff();    };} else {   car1.collisionFlag = false;}


edit: code refactor
How about using an invunerable timer for each object?

example:

class object{public:   int invunerableTime;   object(void) : invunerableTime(0) {}      void update(void)   {      if (invunerableTime <= 0)      {         // do collision tests      }      else      {         // invunerable, decrease time left         invunerableTime -= getElapsedTime();      }   }   void draw(void)   {      if (invunerableTime > 0)      {         // invunerable during draw! flicker...         if (getTime() & 16) return;      }   }   void registerHit(unsigned damage = 0)   {       if (damage)       {          // make object invunerable for a while          invunerableTime += 50;       }   }};



Maybe a new idea for your game?


Cheers!
Thanks for your help guys :)

I gave it some more thought, and the best way to go seemed to be a simple hack:

if( ABS( impact ) < MIN_IMPACT )
impact = MIN_IMPACT * SGN( impact );


So, basically, this prevents the situation from ever happening where you repeatedly collide with the same object again and again... On the other hand, I guess it does look a little fake that you could be driving at 0.0001 mph, crash into a car, and then go hurtling backwards. But for a properly tweaked value of MIN_IMPACT, I seem to get fairly believable results...

This topic is closed to new replies.

Advertisement