Advertisement

AABB collision problem

Started by July 14, 2013 08:38 PM
1 comment, last by robee00 11 years, 7 months ago

Hello!

I have some problems with AABB - AABB collision. I successfully get the normal of the face I hit, but when I'm trying to resolve the collision (I'm trying to get the sliding working) sometimes I go through the wall, sometimes only by a bit.

Here is the code, where I try to resolve the collision.


if(BoundingBox.intersect(bb, Game.c2.bb))
        {
            Vector3f reaction = new Vector3f();
            reaction.x = bb.norm.x * - (Vector3f.dot(bb.norm, movement));
            reaction.y = bb.norm.y * - (Vector3f.dot(bb.norm, movement));
            reaction.z = bb.norm.z * - (Vector3f.dot(bb.norm, movement));

            Vector3f.add(movement, reaction, movement);

            Vector3f.add(position, movement, position);

            bb.setVecMin(new Vector3f(position.x - BBSIZE, 0f, position.z - BBSIZE));
            bb.setVecMax(new Vector3f(position.x + BBSIZE, 1f, position.z + BBSIZE));
}
        else
        {
            position.set(tempPos);

            bb.setVecMin(new Vector3f(position.x - BBSIZE, 0f, position.z - BBSIZE));
            bb.setVecMax(new Vector3f(position.x + BBSIZE, 1f, position.z + BBSIZE));
        }

aGKIKn0.png

this is what i use and it works properly...

bool AABBIntersect(float* mina,  // min vector of boxa

                   float* maxa,  // max vector of boxa 

                   float* minb,  // min vector of boxb

                   float* maxb,  // max vector of boxb

                   float* ncoll,       // normal of collision.

                   float* dcoll)          // face intersected.

{

    // the normal of each face.

    static const float faces[6][3] = 

    { 

        {-1,  0,  0}, // 'left' face normal (-x direction)

        {1,  0,  0}, // 'right' face normal (+x direction)

        {0, -1,  0}, // 'bottom' face normal (-y direction)

        {0,  1,  0}, // 'top' face normal (+y direction)

        {0,  0, -1}, // 'far' face normal (-z direction)

        {0,  0,  1}, // 'near' face normal (+x direction)

    };

    

    // distance of collided box to the face.

    float distances[6] = 

    { 

        (maxb[0] - mina[0]), // distance of box 'b' to face on 'left' side of 'a'.

        (maxa[0] - minb[0]), // distance of box 'b' to face on 'right' side of 'a'.

        (maxb[1] - mina[1]), // distance of box 'b' to face on 'bottom' side of 'a'.

        (maxa[1] - minb[1]), // distance of box 'b' to face on 'top' side of 'a'.

        (maxb[2] - mina[2]), // distance of box 'b' to face on 'far' side of 'a'.

       (maxa[2] - minb[2]) // distance of box 'b' to face on 'near' side of 'a'.
}
     ;



    // scan each face, make sure the box intersects,

    // and take the face with least amount of intersection

    // as the collided face.

    for(int i = 0; i < 6; i ++)

    {

        // box does not intersect face. So boxes don't intersect at all.

        if(distances[i] < 0.0f) 

            return false;



        // face of least intersection depth. That's our candidate.

        if((i == 0) || (distances[i] < *dcoll)) 

        {

            ncoll[0] = faces[i][0];
            ncoll[1] = faces[i][1];
            ncoll[2] = faces[i][2];

            *dcoll = distances[i];

        }        

    }

    return true;

}

Checking for collision is like:


float mina[3] = {acenter[0]-ax_length/2, acenter[1]-ay_length/2, acenter[2]-az_length/2};
float maxa[3] = {acenter[0]+ax_length/2, acenter[1]+ay_length/2, acenter[2]+az_length/2};
float minb[3] = {bcenter[0]-bx_length/2, bcenter[1]-by_length/2, bcenter[2]-bz_length/2};
float maxb[3] = {bcenter[0]+bx_length/2, bcenter[1]+by_length/2, bcenter[2]+bz_length/2};
float Norm[3];
float dist;

AABBIntersect( minb, maxb, mina, maxa, Norm, &dist )

and response (sliding) :


ax_center += Norm[0] * -dist, ay_center += Norm[1] * -dist, az_center += Norm[2] * -dist;
Advertisement

Thank you! I had to multiply with the -dist instead of the dot product. With the dot product I always went into the wall as seen on the picture. :/

This topic is closed to new replies.

Advertisement