Game Development Reference
In-Depth Information
by the coordinate vector:
M p local =
p world
In other words, the basis matrix converts local coordinates to world coordinates.
We can put this together into code. This function operates on the contact normal
to create a set of orthonormal axes and then generates a basis matrix representing the
contact coordinate scheme. The matrix can act as a transformation to convert contact
coordinates into world coordinates:
Excerpt from src/contacts.cpp
/**
* Constructs an arbitrary orthonormal basis for the contact.
* This is stored as a 3x3 matrix, where each vector is a column
* (in other words the matrix transforms contact space into world
* space). The x direction is generated from the contact normal,
* and the y and z directions are set so they are at right angles to
* it.
*/
void Contact::calculateContactBasis()
{
Vector3 contactTangent[2];
// Check whether the Z axis is nearer to the X or Y axis.
if(real_abs(contactNormal.x) > real_abs(contactNormal.y))
{
// Scaling factor to ensure the results are normalized.
const real s = (real)1.0f/
real_sqrt(contactNormal.z*contactNormal.z +
contactNormal.x*contactNormal.x);
// The new X axis is at right angles to the world Y axis.
contactTangent[0].x = contactNormal.z*s;
contactTangent[0].y = 0;
contactTangent[0].z = -contactNormal.x*s;
// The new Y axis is at right angles to the new X and Z axes.
contactTangent[1].x = contactNormal.y*contactTangent[0].x;
contactTangent[1].y = contactNormal.z*contactTangent[0].x -
contactNormal.x*contactTangent[0].z;
contactTangent[1].z = -contactNormal.y*contactTangent[0].x;
}
else
{
// Scaling factor to ensure the results are normalized.
const real s = (real)1.0/