Incorrect frustum culling with center/half-size AABB

I’m trying to implement an axis-aligned bounding box with center/half-size instead of min/max. And I have some problems when it comes to create a method to detect if the aabb is visible or not.

I try to do the same as on this website at “Method 5″: http://fgiesen.wordpress.com/2010/10/17/view-frustum-culling/. I’m trying to implement this formula:

return dot3(center + extent * signFlip, plane) > -plane.w;

But it doesn’t work at all and I don’t find what’s going wrong. Objects in my scene seems to appear and disappear in a strange way, sometimes appears when I’m not watching them or disappears when frustum faces them (I look at draw calls to determine if the isVisible test returns true or false).

Here is my code:

The Axis-aligned bounding box

public sealed class AxisAlignedBox
{
    public Vector3 Center;
    public Vector3 HalfSize;
}

The method in the frustum that tests if the aabb is visible or not:

public bool Intersects(AxisAlignedBox aabb)
    {
        Vector3 v;
        float d;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[0], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[0].Normal, out d);
        if (d > -_planes[0].D) return true;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[1], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[1].Normal, out d);
        if (d > -_planes[1].D) return true;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[2], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[2].Normal, out d);
        if (d > -_planes[2].D) return true;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[3], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[3].Normal, out d);
        if (d > -_planes[3].D) return true;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[4], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[4].Normal, out d);
        if (d > -_planes[4].D) return true;

        Vector3.Multiply(ref aabb.HalfSize, ref _signPlane[5], out v);
        Vector3.Add(ref aabb.Center, ref v, out v);
        Vector3.Dot(ref v, ref _planes[5].Normal, out d);
        if (d > -_planes[5].D) return true;

        return false;
    }

_signPlane is an array of Vector3 using the following formula and applied for each plane once per frame when the frustum is updated:

        public static void Sign(ref Vector3 v, out Vector3 result)
    {
        result.X = Math.Sign(v.X);
        result.Y = Math.Sign(v.Y);
        result.Z = Math.Sign(v.Z);
    }

Leave a Reply