Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm currently attempting to add an overlap tester for an axis aligned and orientated bounding box but the solution only seems to work accurately when the OBB's angle is between -10 and +10. As the angle approaches +90 degrees the collision area seems to at first move to the right half of the OBB and then become non existent. Between 90 and 270 I couldn't get an overlap and then when it comes round a full 360 the area registers accurately again.

Any light on this subject would be great. I'm using positive X for 0 degrees increasing CCW.

EDIT: Did a little more research and realized that projecting a vector onto another requires more than just a dot product. Could any one give me a correct version of one of the check axis methods below?

EDIT 2: Actually just a dot product should do I think since the vectors being projected onto are unit length.

public static bool overlapAABB_OBB(AABB a, OBB o)
    {
        float rads = MathHelper.ToRadians(-o.angle);
        T = Vector2.Subtract(o.position, a.position);
        Ax.X = 1;
        Ax.Y = 0;
        Ay.X = 0;
        Ay.Y = 1;
        Ox.X = (float)Math.Cos(rads);
        Ox.Y = (float)Math.Sin(rads);
        Oy.X = -Ox.Y;
        Oy.Y = Ox.X;
        if (checkAX(a, o) &&
           checkAY(a, o) &&
           checkOX(a, o) &&
           checkOY(a, o))
            return true;
        else
            return false;
    }

    private static bool checkAX(AABB a, OBB o)
    {
        float TAx = Vector2.Dot(T, Ax);
        float WoOxAx = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax);
        float HoOyAx = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax);
        if (TAx > a.halfWidth + WoOxAx + HoOyAx)
            return false;
        else
            return true;
    }

    private static bool checkAY(AABB a, OBB o)
    {
        float TAy = Vector2.Dot(T, Ay);
        float WoOxAy = Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ay);
        float HoOyAy = Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ay);
        if (TAy > a.halfHeight + WoOxAy + HoOyAy)
            return false;
        else
            return true;
    }

    private static bool checkOX(AABB a, OBB o)
    {
        float TOx = Vector2.Dot(T, Ox);
        float WaAxOx = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Ox);
        float HaAyOx = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Ox);
        if (TOx > o.halfWidth + WaAxOx + HaAyOx)
            return false;
        else
            return true;
    }

    private static bool checkOY(AABB a, OBB o)
    {
        float TOy = Vector2.Dot(T, Oy);
        float WaAxOy = Vector2.Dot(Vector2.Multiply(Ax, a.halfWidth), Oy);
        float HaAyOy = Vector2.Dot(Vector2.Multiply(Ay, a.halfHeight), Oy);
        if (TOy > o.halfHeight + WaAxOy + HaAyOy)
            return false;
        else
            return true;
    }
share|improve this question
1  
Since this is a well known algorithm, I'm assuming this is just a flaw in your implementation. Most likely too localized for the site. –  Byte56 Jan 11 '13 at 3:30
    
I thought I was close as I followed the calculation as best as I could I just didn't realise |ProjB(A)| meant the absolute value of vector B on A –  Mazk1985 Jan 11 '13 at 16:52

1 Answer 1

up vote 1 down vote accepted

dot product is negative when the angle between the two vectors is greater than 90º, for the code to work properly you would need to take the absolute value of the dot product.

//...
private static bool checkAX(AABB a, OBB o)
{
    float TAx    = Math.Abs( Vector2.Dot(T, Ax) );
    float WoOxAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Ox, o.halfWidth), Ax) );
    float HoOyAx = Math.Abs( Vector2.Dot(Vector2.Multiply(Oy, o.halfHeight), Ax) );
    if (TAx > a.halfWidth + WoOxAx + HoOyAx)
        return false;
    else
        return true;
}
//...

this also applies to checkAY, checkOX, and checkOY

share|improve this answer
    
Nice one. Thank you very much. I did eventually get it to work but I replaced every dot product with a custom method that got the projection vector and then worked out it length but your way eliminates 12 square roots per overlap so that's awesome. Thanks again. –  Mazk1985 Jan 11 '13 at 16:37
    
you're welcome! –  rraallvv Jan 11 '13 at 17:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.