(Solved) BoundingOrientedBox never returning collisions

I’m looking to Incorporate Oriented Bounding Boxes in my project, for which I decided to try out the code here: https://github.com/CartBlanche/MonoGame-Samples/blob/master/CollisionSample/BoundingOrientedBox.cs. Plugging the vertices produced by the BoundedOrientedBox into my DebugShapeRenderer shows that the oriented boxes are appearing exactly as I expect them to. However, these BoundingOrientedBoxes always return false when polling for collisions via BoundingOrientedBox.Intersects(ref BoundingOrientedBox other). I did a cursory glance over the code and output the box properties, but everything seems pretty reasonable. Does anyone here have experience working with this class, and may be able to point me in the right direction? I have attached an image showing a state where two BoundingOrientedBoxes are clearly intersecting, yet calling .Inersects on the Cube’s BoundingOrientedBox, supplying the overlapping cylinder’s BoundingOrientedBox, still return’s false.

Can you check if it works if you don’t have any rotation? This line looks incorrect to me, because the inverse absolute rotation of other is used to transform the vector between the positions instead of the inverse relative transform. I haven’t tested this, so not sure if this is the issue.

Great thought Jjagg, but unfortunately even without any rotation applied to the BoundingOrientedBoxes, the issue persists. I did some further testing this morning, and found that the BoundingOrientedBox does find an Intersection when one BoundingOrientedBox is completely engulfing the other. In the upper example, the non-rotated AABBs (drawn in yellow) find an Intersection, but the oriented bounding boxes (drawn in red) do not. In the lower example, both the AABBs and the oriented bounding boxes find an Intersection, as the one oriented bounding box is now completely enveloping the other.



It looks like if I want to make any more progress here I’m going to have to really dig in to the BoundingOrientedBox Intersection code and see what I can find :wink:

1 Like

Good luck! Please do post back, should you figure it out :slight_smile:

1 Like

After doing some more digging I happened upon this post http://xboxforums.create.msdn.com/forums/t/83491.aspx wherein the user ‘Wipeless XNA’ runs into what appears to be the same issue as myself. He later points out his findings, “However, say your box has no rotation or only rotates about the x-axis [the separation plane check] automatically becomes 0 and returns Disjoint”. In his followup post, he suggests an additional condition before the set of tests on each axis, which skips over those checks if the second box does not contain any nonzero values on the axis in question. I implemented his suggestion, and it appears to have solved the problem for myself as well! More rigorous testing will need to be done, but in the mean time I am marking this thread as solved. In case the aforementioned link expires, I will post the solution code below, which begins on line 576 of BoundingOrientedBox.cs:

        if (bX.X != 0 &&  bY.X != 0 && bZ.X != 0) 
        { 
            // a.X ^ b.X = (1,0,0) ^ bX 
            axis = new Vector3(0, -bX.Z, bX.Y); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Y * axis.Y) + Math.Abs(hA.Z * axis.Z) + Math.Abs(Vector3.Dot(axis, hy_B)) + Math.Abs(Vector3.Dot(axis, hz_B))) 
                return ContainmentType.Disjoint; 

            // a.X ^ b.Y = (1,0,0) ^ bY 
            axis = new Vector3(0, -bY.Z, bY.Y); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Y * axis.Y) + Math.Abs(hA.Z * axis.Z) + Math.Abs(Vector3.Dot(axis, hz_B)) + Math.Abs(Vector3.Dot(axis, hx_B))) 
                return ContainmentType.Disjoint; 

            // a.X ^ b.Z = (1,0,0) ^ bZ 
            axis = new Vector3(0, -bZ.Z, bZ.Y); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Y * axis.Y) + Math.Abs(hA.Z * axis.Z) + Math.Abs(Vector3.Dot(axis, hx_B)) + Math.Abs(Vector3.Dot(axis, hy_B))) 
                return ContainmentType.Disjoint; 
        } 

        if (bX.Y != 0 && bY.Y != 0 && bZ.Y != 0) 
        { 
            // a.Y ^ b.X = (0,1,0) ^ bX 
            axis = new Vector3(bX.Z, 0, -bX.X); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Z * axis.Z) + Math.Abs(hA.X * axis.X) + Math.Abs(Vector3.Dot(axis, hy_B)) + Math.Abs(Vector3.Dot(axis, hz_B))) 
                return ContainmentType.Disjoint; 

            // a.Y ^ b.Y = (0,1,0) ^ bY 
            axis = new Vector3(bY.Z, 0, -bY.X); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Z * axis.Z) + Math.Abs(hA.X * axis.X) + Math.Abs(Vector3.Dot(axis, hz_B)) + Math.Abs(Vector3.Dot(axis, hx_B))) 
                return ContainmentType.Disjoint; 

            // a.Y ^ b.Z = (0,1,0) ^ bZ 
            axis = new Vector3(bZ.Z, 0, -bZ.X); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.Z * axis.Z) + Math.Abs(hA.X * axis.X) + Math.Abs(Vector3.Dot(axis, hx_B)) + Math.Abs(Vector3.Dot(axis, hy_B))) 
                return ContainmentType.Disjoint; 
        } 

        if (bX.Z != 0 &&  bY.Z != 0 && bZ.Z != 0) 
        { 
            // a.Z ^ b.X = (0,0,1) ^ bX 
            axis = new Vector3(-bX.Y, bX.X, 0); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.X * axis.X) + Math.Abs(hA.Y * axis.Y) + Math.Abs(Vector3.Dot(axis, hy_B)) + Math.Abs(Vector3.Dot(axis, hz_B))) 
                return ContainmentType.Disjoint; 

            // a.Z ^ b.Y = (0,0,1) ^ bY 
            axis = new Vector3(-bY.Y, bY.X, 0); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.X * axis.X) + Math.Abs(hA.Y * axis.Y) + Math.Abs(Vector3.Dot(axis, hz_B)) + Math.Abs(Vector3.Dot(axis, hx_B))) 
                return ContainmentType.Disjoint; 

            // a.Z ^ b.Z = (0,0,1) ^ bZ 
            axis = new Vector3(-bZ.Y, bZ.X, 0); 
            if (Math.Abs(Vector3.Dot(mB_T, axis)) >= Math.Abs(hA.X * axis.X) + Math.Abs(hA.Y * axis.Y) + Math.Abs(Vector3.Dot(axis, hx_B)) + Math.Abs(Vector3.Dot(axis, hy_B))) 
                return ContainmentType.Disjoint; 
        }
1 Like

Awesome :slight_smile: Thanks for sharing!

im having issue with ray intersection always return null, anyone?

That’s strange. The sample code doesn’t seem to have changed since I originally made this post. Did you modify the BoundingOrientedBox sample code as instructed in this post (Solved) BoundingOrientedBox never returning collisions to resolve the false negative when there is no rotation or rotation only about the x axis? If that isn’t the issue, did you try visualizing your collider data through the use of a shape renderer to make sure the colliders are actually intersecting where you think they are? Beyond those suggestions I’m afraid I can’t offer much help, as I haven’t worked with oriented bounding box collision detection via the separating axes theorem (or really even used MonoGame) in some time.

it doesn’t intersect when my Orientedbox rotation is Quaternion.identity. and my ray from vector.zero to direction forward. it only work when i put Quaternion.CreateFromYawPitchRoll(0.00001f, 0.00001f, 0.0f);
seem like the yam and pitch cannot be 0

Have you tried?..