4
\$\begingroup\$

I'm writing a physics simulation in Ogre3D and I'm trying to figure out how to calculate the collision normal between two Ogre::AxisAlignedBox's.

I am checking for collisions using the "intersects" function then calculating the collision normals as below, but I am almost certain that this is where I am going wrong as my collisions are very unpredictable:

Ogre::AxisAlignedBox intersection = boxA.intersection(boxB);
Vector firstCollisionNorm = boxA.getCenter() - intersection.getCenter();
Vector secondCollisionNorm = boxB.getCenter() - intersection.getCenter();

After this, I am normalizing the collision normals, calculating the impulse magnitude using dot product, mass and relative velocity, then I multiply the collision normals by the magnitude to get the final impulse force vector, which is added to my current force vector as "impulseForce / deltaTime" for the next step of euler intergration.

If anyone could help me out I would greatly appreciate it!

Thanks

\$\endgroup\$
3
  • \$\begingroup\$ What part of this process is unpredictable? The theory behind your implementation sounds accurate, but what kind of behavior are you getting? \$\endgroup\$
    – Evan
    Commented Feb 11, 2013 at 16:39
  • \$\begingroup\$ Also, when calculating the impulse magnitude using dot product, which vectors are you using for this? Dot product returns a range of values between -magnitude->0<-magnitude+. This could be the culprit if your impulse forces seem inconsistent. \$\endgroup\$
    – Evan
    Commented Feb 11, 2013 at 16:50
  • \$\begingroup\$ opentk.com/node/869 I hope this will help :) \$\endgroup\$ Commented Mar 16, 2013 at 20:01

1 Answer 1

2
\$\begingroup\$

The collision normal should be one of the faces of your boxes. Since you obviously allow some interpenetration you need to pick the closest face:

size = intersection.getSize();

float ax = fabs(size.x);
float ay = fabs(size.y);
float az = fabs(size.z);

float sx = boxA.getCenter().x < boxB.getCenter().x ? -1.0f : 1.0f;
float sy = boxA.getCenter().y < boxB.getCenter().y ? -1.0f : 1.0f;
float sz = boxA.getCenter().z < boxB.getCenter().z ? -1.0f : 1.0f;

if (ax <= ay && ax <= az)
    firstCollisionNorm = Vector(sx, 0.0f, 0.0f);
else if (ay <= az)
    firstCollisionNorm = Vector(0.0f, sy, 0.0f);
else
    firstCollisionNorm = Vector(0.0f, 0.0f, sz);

Then set secondCollisionNorm = -firstCollisionNorm.

\$\endgroup\$
1
  • \$\begingroup\$ You have two sx there i think you mean sz you missed. I edited for you. \$\endgroup\$
    – Ray_Garner
    Commented Jan 9, 2018 at 7:56

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .