Jump to content
  • Advertisement
Sign in to follow this  
ramy

Collision detection

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

Hello everybody, could anybody assist me with the following: -obb collision detection tutorials, and the point of intersection. -i also dont understand how to compute it. -in a car racing game, wat type of collision would fit cars other than obb? several ppl tried, but i got confused, so could somebody help me in these plz? thanks in advanced

Share this post


Link to post
Share on other sites
Advertisement
I'm not sure what would work better than OBBs for cars. If you wanted to be more accurate (but more complicated), you could treat them as a collection of convex objects (tires, chassis, etc.) connected rigidly. But OBBs are a lot easier and are a good approximation.

Both static and dynamic (i.e. moving) collision detection can be performed between OBBs using the separating axis theorem. For static intersection you should be able to get a normal and depth, and for dynamic intersection you can reconstruct the contact features.

Simple boolean intersection is pretty easy - in the collision detection section of the articles on this site is a gamasutra article which explains the algorithm. Swept intersection is a little trickier, and reconstructing the point of intersection can get a little complicated as well.

However, it's all covered in Dave Eberly's book '3D Game Engine Design' (and also his physics book), as well as in code and .pdf's on his Magic Software site. If you're serious about the OBB approach, that's where you'll want to look.

Share this post


Link to post
Share on other sites
i am serious, thx alot.

i have taken a look in magic software, and in gamasutra, i kinda got mixed up, why 15 sides?

anyways, ill try that book u told me.

thx

Share this post


Link to post
Share on other sites
15 sides for 15 potential separation axis tests.

3 faces of polygon A
3 Faces of polygon B

Dir1 of polygonA x Dir1 of polygonB
Dir1 of polygonA x Dir2 of polygonB
Dir1 of polygonA x Dir3 of polygonB


Dir2 of polygonA x Dir1 of polygonB
Dir2 of polygonA x Dir2 of polygonB
Dir2 of polygonA x Dir3 of polygonB

Dir3 of polygonA x Dir1 of polygonB
Dir3 of polygonA x Dir2 of polygonB
Dir3 of polygonA x Dir3 of polygonB

erad up on separation axis theorem and it's uses.

Share this post


Link to post
Share on other sites
yep.

then from there it's 'projecting' the box on those axes, and finding if the projection segements overlap.

then to find the collision point is a bit more work.

Share this post


Link to post
Share on other sites
ok i got that, that was pretty useful, can u explain the collision point plz olii? :D

Share this post


Link to post
Share on other sites
//A
VECTOR& a, //extents
VECTOR& Pa, //position
VECTOR* A, //orthonormal basis

does anybody know what does orthonormal mean in the above information?

these 3 vectors are information of a box, in the obb.

Share this post


Link to post
Share on other sites
The orthonormal basis is just 3 mutually orthogonal unit-length axes (i.e. they are all perpendicular to each other). As an example, the X, Y and Z axes in world space are an orthonormal basis.

Share this post


Link to post
Share on other sites
I'm slightly tipsy, so forgive me if the explainations don;t seem to make a lot of sense....

the orthonormal basis can be as simple as the 3x3 orientation matrix.

pull out each rows or columns of the matrix (depending if it's a row-major or column-major matrix sytem you use) to get the 3 vectors you need.

ok, as far as finding the collision points, I might as well detail the calculations.


struct OBBox
{
Vector P; // centre of the box
Vector L[3]; // axes of the box
Vector E; // extent of the box
};

// calculate projection of a box onto an axis and return the
//interval of projection
void OBBox::ProjectOnAxis(const Vector& Axis, float &min, float &max) const
{
float p = P.Dot(Axis);
float r = abs(D[0].Dot(Axis)) * E.x + abs(D[1].Dot(Axis)) * E.y + abs(D[2].Dot(Axis)) * E.z;
min = p - r;
max = p + r;
}

// see if two box intervals over an axis intersect, and if so
// calculate the amount of overlap
bool OBBox::AxisOverlap(const Vector& Axis, const OBBox& Box, float &depth) const
{
float min1, max1;
float min2, max2;
this->ProjectOnAxis(Axis, min1, max1);
Box->ProjectOnAxis(Axis, min2, max2);

if (min1 > max2 || min2 > max1) return false;

float d0 = abs(max1 - min2);
float d1 = abs(max2 - min1);
depth = (d0 < d1)? d1 : d0;
return true;
}

bool OBBOx::Intersect(const OBBox& Box, Vector& Normal, float& depth) const
{
Vector Axis[15];
float d[15];

Vector* pAxis = &Axis[0];
float* pd = &d[0];

*pAxis = this->L[0];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[1];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[2];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;

*pAxis = Box.L[0];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = Box.L[1];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = Box.L[2];
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;

*pAxis = this->L[0].Cross(Box.L[0]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[0].Cross(Box.L[1]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[0].Cross(Box.L[2]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;

*pAxis = this->L[1].Cross(Box.L[0]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[1].Cross(Box.L[1]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[1].Cross(Box.L[2]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;

*pAxis = this->L[2].Cross(Box.L[0]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[2].Cross(Box.L[1]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;
*pAxis = this->L[2].Cross(Box.L[2]);
if (!AxisOverlap(Box, *pd)) return false; pAxis++; pd++;

// no separation axis found.
// find the collision plane, and the penetration depth
Vector D = Box.P - this->P;
return FindIntersectionPlane(D, Axis, d, Normal, depth);
}

bool OBBox::FindIntersectionPlane(const Vector& D, Vector* Axis, float* d, Vector& Normal, float& depth)
{
// fond the separation plane with the minimum intersection and
// use it as the collision plane
float dmin;
int imin=-1;
for(int i = 0; i < 15; i ++)
{
float dist = Axis.GetLength();

// sanity check
if (dist < 1.0E-6f)
continue;

d /= dist;

if (imin == -1 || d < dmin)
{
dmin = d;
imin = i;
}
}

// degenerate case. error.
if (imin == -1)
return false;

// makes sure the collison plane normal is facing the right way
if (Axis[imin] * D < 0.0f)
Axis[imin] *= -1.0f;

Normal = Axis[imin];
depth = d;

return true;
}



Share this post


Link to post
Share on other sites
Sign in to follow this  

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