Game Development Reference
section 2.1.9. The X axis we know already: it is the contact normal generated by the
collision detector. The Y axis and Z axis need to be calculated. 2
Unfortunately there can be any number of different Y and Z axes generated from
one X axis. We'll need to select just one. If we are working with anisotropic friction
(friction that is different in different directions), then there will be one set of basis
vectors that is most suitable. For the isotropic friction in this topic, and for frictionless
simulations, any set is equally valid. Since we are ignoring friction for now, we create
an arbitrary set of axes by starting with the Y axis pointing down the world Y axis
(recall that the algorithm required the base axis, in our case the X axis, plus an initial
guess at a second axis, which may end up being altered):
* Creates an orthonormal basis where the x-vector is given
* and the y-vector is suggested, but can be changed. Both
* y and z vectors are written to in this function. We assume
* that the vector x is normalized when this function is called.
void makeOrthonormalBasis(const Vector &x, Vector *y, Vector *z)
// Calculate z from the vector product of x and y.
z = (*x) % (*y);
// Check for y and z in parallel
if (z->squaredMagnitude() == 0.0) return;
// Calculate y from the vector product of z and x.
(*y) = (*z) % x;
// Normalize the output vectors
This follows the algorithm given in section 2.1.9. The Y axis assumption is provided
when the function is called:
Vector y(0, 1.0, 0), z;
makeOrthonormalBasis(contactNormal, &y, &z);
2. This is just a convention adopted in this topic. There is no reason why the X axis has to be the contact
normal. Some people prefer to think of the Y axis as the contact normal. If you are one of them, the rest of
this section can be adjusted accordingly.