# RigidBodies: Almost got it!

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

## Recommended Posts

Today was a really bad day. I tried to finish my rigid body simulator, which was almost done. But there was one bug I couldn't get rid of. I tried for hours without success...until I got so angry that I started to cry and kick things around my room ;-) So you guys are my last hope! The problem: There's two hovercraft (simple boxes) that can be accelerated and steered. They float around, rotate and do everything you'd expect of a hovercraft :-) The collision detection is also implemented (Thank's, Oliii!!!!): it decides if a collision has occured, calculates the point of collision (one global and two relative to both hovers) and finds the MTD / collisionNormal. So what's missing? Right! Collision response! I've implemented the following function (adapted from "Physics for game developers"):
// This function is called after the bodies collided
// (one vertex hit an edge of the other body)
// colNormal is a vector perpendicular to the edge
// b1 and b2 are the two involved bodies
void ApplyImpulse( CBody *b1, CBody *b2, CVector collisionNormal )
{
// Calculate the relative velocity
CVector relativeVelocity;
CVector tempVec1, tempVec2;
tempVec1 = b1->velocity + b1->velocityAngular ^ b1->colPoint;
tempVec2 = b2->velocity + b2->velocityAngular ^ b2->colPoint;
RotateVector( b1->orientation, tempVec1 );
RotateVector( b2->orientation, tempVec2 );
vRelativeVelocity = tempVec1 - tempVec2;

// Now it's time for the impulse
float impulse;

impulse =	(-(1+fCr) * (vRelativeVelocity*vCollisionNormal)) /
( (1/b1->mass + 1/b2->mass) +
(collisionNormal * ( ( (b1->colPoint ^ collisionNormal)/b1->inertia )^b1->colPoint) ) +
(collisionNormal * ( ( (b2->colPoint ^ collisionNormal)/b2->inertia )^b2->colPoint) ));

// Apply impulse to bodies (NOTE: angular effects are missing!)
b1->velocity += (impulse*vCollisionNormal) / b1->mass;
b2->velocity -= (impulse*vCollisionNormal) / b2->mass;
}


it is called right after the collision detection stuff. The problem with this function is: it works only in some cases: one hover crashes into the other, they bounce off, rotate accordingly etc. But in other cases (e.g. when I crash into the craft from the other side) the forces are somehow reversed. So insted of bouncing off, they get pulled together, collide again, get pulled together again etc. -> the objects totally freak out! The same is true for rotation: sometimes they rotate in the reverse direction that I'd expect (causing them to get faster and faster...). What could cause this behavior? Is there a wrong sign (+/-) somewhere? Could it be that I calculate the collision-normal in a wrong way? Please tell me everything that comes to your mind! Thank's a lot for your help! (you may save me from commiting suicide ;-))

##### Share on other sites
why this?
RotateVector( b1->orientation, tempVec1 );
RotateVector( b2->orientation, tempVec2 );

I suppose r1 and r2 are relative to the centre of gravity of the object. Velocities should be world relative, so no need to rotate.

to make it simpler, you should have r1 and r2 in world coordinates.

this is what I have

n, normal, roughly points from B to A (roughly in the direction (b1->pos - b2->pos)).
r1, r2 are in world coordinates.

Vector r1 = b1->colPoint - b1->position;
Vector r2 = b2->colPoint - b2->position;
Vector v1 = b1->velocity + b1->angularvelocity ^ r1;
Vector v2 = b2->velocity + b2->angularvelocity ^ r2;
Vector v = v1 - v2;

float vn = v * n;
if (vn > 0.0f) return;

float numer = -(1 + cor) * (vn);
float m = b1->inverse_mass + b2->inverse_mass;
float i1 = (((r1 ^ n) * b1->inverseinertia) ^ r1) * n;
float i2 = (((r2 ^ n) * b2->inverseinertia) ^ r2) * n;
float denom = m + i1 + i2;

float j = numer / denom;

Vector jn = j * n;

b1->velocity += jn;
b2->velocity -= jn;
b1->angularvelocity += r1 ^ jn;
b2->angularvelocity -= r2 ^ jn;

##### Share on other sites
HumHom...that sounds interesting! Don't got time right now but I'll check out your idea/code this afternoon :-)
<You're da man, oliii!>

##### Share on other sites
(You can press SPACE to reset the object's positions!)

Here's a little demo of the project. The hovercraft can be controlled using WSAD and the arrows. Thank's to Oliii's help it's almost working now :-D

But one problem is still left: if you drive too fast the force applied to the hovercraft gets incredible high! => BANG! Everything explodes!
(You got to be realy careful and slow!)

What could cause this strange behavior? Should I simply scale the impulse down by a constant value? (that can't be a good idea!)

[Edited by - VanKurt on June 7, 2005 11:53:44 AM]

##### Share on other sites
Quote:
 Original post by VanKurtBut one problem is still left: if you drive too fast the force applied to the hovercraft gets incredible high! => BANG! Everything explodes!(You got to be realy careful and slow!) DemoWhat could cause this strange behavior? Should I simply scale the impulse down by a constant value? (that can't be a good idea!)Thanks again for your help!!!

Wow that's a strong collision. Post your impulse code (something like oliii posted). Are you sure your momenta of inertia are correct? For boxes it is MI = Mass * (Width^2 + Height^2) / 12.

##### Share on other sites
That shouldn't be the problem because the whole thing works fine without collisions (acceleration, rotation etc.). And when your're slow enough while colliding results seem to be OK, too...

Important for the demo:
You can press SPACE to reset the object's positions! :-)

[Edited by - VanKurt on June 7, 2005 11:58:40 AM]

##### Share on other sites
Looking good, almost there. [smile]

Yeah, it looks like your impulse code has a problem... are you sure your collision normal is normalized?

##### Share on other sites
Quote:
 Looking good, almost there.
Thanks :-D
(hopefully I'll get there...I'd hate to have to give up at this point)

Quote:
 are you sure your collision normal is normalized?

Yep, it is (but maybe it's direction is reversed???). I compared my code to oliii's and it seemed to be ok. I'm doing the same calculations but it still doesn't work...ARGH!!!
I also realized that the problem with forces acting in the wrong (inverse) direction is still there... (it only occures in certain situations, very strange...)
More ideas are welcome :-D

##### Share on other sites
Here, try it with my code :
p.N is the normal of the collision.

template < class Real >void Impulse<Real>::process_collisioncontact( RigidBody<Real> & a,						RigidBody<Real>& b,						CollisionPoint<Real> p ){ 	const Real e = 1.0;	Vector2<Real> rA = p.P - a.get_pos() ;	Vector2<Real> rB = p.P - b.get_pos() ;	Real kA = rA.perp().dot( p.N ); 	Real kB = rB.perp().dot( p.N );	Real uA = kA / a.get_inertiatensor() ;	Real uB = kB / b.get_inertiatensor() ;	Real f_numer = - ( 1 + e ) * ( p.N.dot( a.linear_velocity - b.linear_velocity ) + a.angular_velocity * kA - b.angular_velocity * kB );	Real f_denom = ( 1 / a.get_mass()  ) + ( 1 / b.get_mass() ) + kA * uA + kB * uB ;	Real f = f_numer / f_denom ;	Vector2<Real> impulse = f * p.N ;	a.linear_momentum += impulse;	b.linear_momentum -= impulse;	a.angular_momentum += f * kA ;	b.angular_momentum -= f * kB ;	a.linear_velocity = a.linear_momentum / a.get_mass() ;	b.linear_velocity = b.linear_momentum / b.get_mass() ;	a.angular_velocity +=  f * uA;	b.angular_velocity +=  f * uB;}

( it can be found in my physics engine project : http://inertia2d.sf.net )

##### Share on other sites
Woops, didn't see Oliii already posted something,sry :)

Try to look if the collision normal is always in the good direction .

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

• 15
• 14
• 46
• 22
• 27
• ### Forum Statistics

• Total Topics
634047
• Total Posts
3015231
×