OBB vs Sphere while OBB is not centered in origin

Started by
2 comments, last by Buckeye 9 years, 5 months ago

Hi there,

I stumbled upon a bug in my implementation of OBB vs a Sphere.

Here is the problem:

I created a simple Box in 3DSMax in positive x direction from the origin

so my actual center of the box is somewhere near: 50,5,0

When I have this box in my scene and rotate it, it will always rotate around it's local origin which is fine.

I defined my OBB like this:

- center

- dimensions

- base vectors (1,0,0 /0,1,0/0,0,1)

While testing for collisions I recalculate my base vectors with the current rotation Matrix of the model.

In my opinion this is where it's buggy, because I rotate the base vectors regardless of the actual distance the object has to it's real position in object space.

Meaning collisions for object centered in object space origin are working fine. But if the object is not centered in it's object space's origin than collision detection is not right any more.

Do you have any suggestion how to fix this problem?

Is it clear what I tried to describe?

Advertisement


th[e]n collision detection is not right any more ... Is it clear what I tried to describe?

Nope. "I have some code [not shown]. It doesn't work. How do I fix it?" wink.png

Rotating an object's AABB (which it appears you have, not an OBB) about it's origin is the correct approach. For collision testing, you should then translate either the sphere into object space, or the object into sphere space. Do you do that?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Sorry for the confusion.

My obb vs sphere check (pseudocode)


A = OBB;
B = Sphere;

closestPoint = ClosestPointOnOBB(B.center, A);


delta = closestPoint - B.center;
distance = length(delta);

if (distance < B.radius) {...

function ClosestPointOnOBB(point, OBB){

A = OBB;
B = OBB.data;

//4x4 matrix
//change the rotation of the baseMatrix (consist of unityMatrix) the same rotation the OBB has

newBasematrix = B.baseMatrix * A.rotationMatrix;

//convert to vector with 3 
var axisX = (newBasematrix[0], newBasematrix[1], newBasematrix[2]);
var axisY = (newBasematrix[4], newBasematrix[5], newBasematrix[6]);
var axisZ = (newBasematrix[8], newBasematrix[9], newBasematrix[10]);


centerRelPointToOBB = point - A.center;

closestPoint = A.center;

dist = dot(centerRelPointToOBB, axisX);

if (dist > B.width / 2) {
dist = B.width / 2;
}
if (dist < -B.width / 2) {
dist = -B.width / 2;
}

closestPoint = closestPoint + axisX * dist

dist = dot(centerRelPointToOBB, axisY);

if (dist > B.height / 2) {
dist = B.height / 2;
}
if (dist < -B.height / 2) {
dist = -B.height / 2;
}

closestPoint = closestPoint + axisY * dist

dist = dot(centerRelPointToOBB, axisZ);

if (dist > B.length / 2) {
dist = B.length / 2;
}
if (dist < -B.length / 2) {
dist = -B.length / 2;
}

closestPoint = closestPoint + axisZ * dist

return closestPoint;
}

This code works fine for all OBB models which are centered in their object space center (0,0,0).

If the model (e.g. Box) is created in Blender or whatever at 100,0,0 (x,y,z) in object space. Then my check does work as long as I don't try to rotate my model. Then the collision will fail at a certain threshold.

Is it clear now?

To save yourself a lot of time -

First step in debugging: examine your code for obvious typos and logic errors.

Second step in debugging: before asking someone else to stare at your code, at a minimum, gather some information about the problem. See if you can find the problem yourself, or, at a minimum, find a few lines of code (say, less than 50 happy.png ) where the problem occurs. Set breakpoints in your code and, when running the program, examine actual values of variables at several points in your code where you think the problem may be. Determine if those values are what you expect. At some point you'll find incorrect values. Continue to set breakpoints to determine where "good" values turn to "bad" values. The problem is occurring between those two points in your code.

1. For information, does "unityMatrix" mean identity matrix?

2. Have you confirmed that OBB.rotationMatrix represents only the OBB's local rotation?

3. Have you confirmed OBB.center is (for your example) ( 100, 0, 0 )?

By "confirm," I mean, as mentioned above, setting breakpoints in your code and examining the actual values while the code is running.


Then the collision will fail at a certain threshold ... Is it clear now?

Not really.

Some tough love. Although you've posted some code, you post is still "Here's some code. It doesn't work sometimes ["doesn't work" and "sometimes" not defined]. What's wrong?" E.g., it's not clear what you mean by "doesn't work," "is not right any more," or "threshold." The code detects hits when it shouldn't? Doesn't detect hits when it should? Detects hit with a wrong location? Does "threshhold" mean distance between the sphere and the box? Rotation of the box? A combination of the two? The size of the sphere? The size of the box?

When you determine an error condition (bad hit, distance, rotation??), set up that condition in your program, even setting hard-coded values for sphere/box parameters. Then go to the second step for debugging mentioned above.

Without knowing what problem you're having (other than there may be a problem in some 50-60 lines of code), I would just make a guess than you're making assumptions about the results of your rotation calcs, and the signed comparisons with the box extents.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement