Game Development Reference
In-Depth Information
dist = relCenter.x;
if (dist > box.halfSize.x) dist = box.halfSize.x;
if (dist < -box.halfSize.x) dist = -box.halfSize.x;
closestPt.x = dist;
dist = relCenter.y;
if (dist > box.halfSize.y) dist = box.halfSize.y;
if (dist < -box.halfSize.y) dist = -box.halfSize.y;
closestPt.y = dist;
dist = relCenter.z;
if (dist > box.halfSize.z) dist = box.halfSize.z;
if (dist < -box.halfSize.z) dist = -box.halfSize.z;
closestPt.z = dist;
// Check we're in contact.
dist = (closestPt - relCenter).squareMagnitude();
The contact properties need to be given in world coordinates, so before we calcu-
late the contact normal, we need to find the closest point in world coordinates. This
simply means transforming the point we generated earlier:
Excerpt from src/collide_fine.cpp
// Compile the contact.
Vector3 closestPtWorld = box.transform.transform(closestPt);
We can then calculate the contact properties as before in the chapter. The final
code puts all this together to look like this:
Excerpt from src/collide_fine.cpp
unsigned CollisionDetector::boxAndSphere(
const Box &box,
const Sphere &sphere,
CollisionData *data
)
{
// Transform the center of the sphere into box coordinates.
Vector3 center = sphere.getAxis(3);
Vector3 relCenter = box.transform.transformInverse(center);
// Early-out check to see if we can exclude the contact.
if (real_abs(relCenter.x) - sphere.radius > box.halfSize.x ||
real_abs(relCenter.y) - sphere.radius > box.halfSize.y ||