Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

When testing bounding spheres as part of the collision detection process, I'm using this method:

    public static BoundingSphere TransformBoundingSphere(Matrix m, BoundingSphere b)
    {
        var center = b.Center;
        var edge = b.Center + Vector3.Right * b.Radius;

        var worldCenter = Vector3.Transform(center, m);
        var worldEdge = Vector3.Transform(edge, m);

        return new BoundingSphere(worldCenter, (worldEdge - worldCenter).Length());
    }

... to get a sphere in world coordinates (where m is a world matrix for the object encompassed by the original sphere).

(Yes, I'm aware that this relies on uniform scaling.)

This is obvious, reliable and easy, but is there a better way?

share|improve this question

2 Answers 2

up vote 1 down vote accepted

If the scaling is uniform and it is a known quantity, why not simply multiply b.Radius by the known scale. This will save cpu cycles by not having to perform the 2nd Vector3.Transform and a square root in the .Length() call

public static BoundingSphere TransformBoundingSphere(Matrix m, BoundingSphere b)
{
    var worldCenter = Vector3.Transform(b.Center, m);

    return new BoundingSphere(worldCenter, b.Radius * myUniformScale);
}
share|improve this answer
    
Thanks. I'll file this one under "d'oh!" –  David Lively Aug 18 '12 at 20:43

If you are sure your has a uniform scale and no skew components, then the non-translation part of the matrix can be expressed as M_33 = R * (s * I), where R is the an orthogonal rotation matrix, and s is the uniform scale. This is vaguely annoying so solve, but in 3d comes out to be:

scale_x = sqrt(m00^2 + m01^2 +m02^2);
// scale_y = sqrt(m10^2 + m11^2 +m12^2);
// scale_z = sqrt(m20^2 + m21^2 +m22^2);
// Assert(scale_x == scale_y == scale_z);
newRadius = b.radius * scale_x;

For transforms for game objects (that tend to have requirements like 'uniform scale'), it's often easier to store object transforms in their components, and compute the full matrix when necessary, as opposed to storing the full matrix and then having to extract the components.

struct Transform 
{
   Vector3 translation;
   Quaternion rotation; 
   float scale;

   Matrix44 ToMatrix44();
};

This form also assures the transform has the appropriate form and epsilon-ish errors don't sneak in, while maintaining composability.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.