Collision detection

Started by
29 comments, last by ramy 19 years, 5 months ago
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
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.
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
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.

Everything is better with Metal.

oliii... is this correct?(see picture)

<-Sweenie->
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.

Everything is better with Metal.

ok i got that, that was pretty useful, can u explain the collision point plz olii? :D
//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.
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.
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 projectionvoid 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 overlapbool 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;}


Everything is better with Metal.

This topic is closed to new replies.

Advertisement