# OBB rotations affecting penetration depth along y axis. Is OBB class incorrect?

This topic is 3199 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have an OBB class that has the following:
        Vector3[] axes;                                     // Local x, y and z axes
Vector3 extents;                                    // Positive halfwidth extents of the OBB along each axis
Quaternion orientation = Quaternion.Identity;       // Orientation of OBB (Rotation matrix is derived from this)
Vector3 position;
Matrix rotation;

If I want to update the orientation of the OBB then I do the following:
        public void UpdateRotation(float yaw, float pitch, float roll)
{
if (yaw == 0f && pitch == 0f && roll == 0f)
{
return;
}

Quaternion rotation_Additional = Quaternion.CreateFromYawPitchRoll(yaw, pitch, roll);
orientation.Normalize();

rotation = Matrix.CreateFromQuaternion(orientation);

// Local X, Y and Z axes
axes[0] = rotation.Right;
axes[1] = rotation.Up;
axes[2] = rotation.Forward;

recreateWorld = true;
}


I can then derive the world transform for the OBB as the following:
                    world_Transform =
Matrix.CreateScale(extents * 2f) *
rotation *
Matrix.CreateTranslation(position);

Can anyone tell me if what I have got is incorrect in any way please? The reason why I ask is because I trying to locate the source of an irritating collision response bug that occurs between 2 OBBs intersecting along the Y-axis. The OBBs will resolve the collision correctly if they both have the same orientation, but the penetration depth is calculated too small if the orientations differ by even the slightest amount. I am calculating the OBB slabs correctly for intersections tests as follows:
        public void CalculateSlab(Vector3 axis, ref float min, ref float max)
{
// • A slab is the infinite region of space between two planes
// • The min and max values are then the required scalar values defining the plane positions
float pos = Vector3.Dot(position, axis);

float ext =
Math.Abs(Vector3.Dot(axes[0], axis)) * extents.X +
Math.Abs(Vector3.Dot(axes[1], axis)) * extents.Y +
Math.Abs(Vector3.Dot(axes[2], axis)) * extents.Z;

min = pos - ext;
max = pos + ext;
}


and the 1D test for intersection for each separating axis should also be correct, as it works for other shapes:
        private static bool IntersectThruAxis(Vector3 axis, CD_AABB a, CD_OBB b, ref float mtv_Distance, ref Vector3 mtv_Axis)
{
// [Separating Axis Theorem]
// • Two convex shapes only overlap if they overlap on all axes of separation
// • In order to create accurate responses we need to find the collision vector (Minimum Translation Vector)
// • Find if the two boxes intersect along a single axis
// • Compute the intersection interval for that axis
// • Keep the smallest intersection/penetration value
float a_Min = float.MaxValue;
float a_Max = float.MinValue;
float b_Min = float.MaxValue;
float b_Max = float.MinValue;

a.CalculateSlab(axis, ref a_Min, ref a_Max);
b.CalculateSlab(axis, ref b_Min, ref b_Max);

// Find distance intervals for current two slabs
// Distance is between slab min/max values
float d_S0 = a_Min - b_Max;
float d_S1 = b_Min - a_Max;

// The distance is positive if the intervals do not overlap
// Must be >= to 0 and not > 0, otherwise MTV can equal Vector3.Zero and cause NaN
if (d_S0 >= 0f || d_S1 >= 0f)
{
return false;
}

// Current distance interval for slabs [A_Min, A_Max] and [B_Min, B_Max]
float d = (d_S0 > d_S1) ? -d_S0 : d_S1;

// If d is the smallest distance so far
if (Math.Abs(d) < Math.Abs(mtv_Distance))
{
// Store the distance and the current axis
mtv_Distance = d;
mtv_Axis = axis;
}

return true;
}


I've stepped through the code and the problem is that the mtv_Distance is too small a value, which doesn't resolve the OBB penetration. Can anyone point out any glaring errors in my code so far, it would really help me as I can't understand why this is happening. Thank you.

##### Share on other sites
Have you tried with mirrored orientations? Do you find the bug with the x/z axes as well? Does the issue appear if the orientation of on object only differs on the y axis? If that works OK, assume the error is with the rotation code, or the projection onto the separating axis.

        float a_Min = float.MaxValue;        float a_Max = float.MinValue;        float b_Min = float.MaxValue;        float b_Max = float.MinValue;

what is supposed to happen here?

1. 1
2. 2
3. 3
Rutin
18
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633659
• Total Posts
3013217
×