Game Development Reference
In-Depth Information
+
=
ax
+
by
+
cz
d
h
i
ax
+
by
+
cz
+
d
ex
+
fy
+
gz
ex
+
fy
+
gz
+
h
ix
+
jy
+
kz
ix
+
jy
+
kz
+
l
which is exactly the two-step, transform-then-move process we had before, but all in
one step. If the first three columns give the directions of the three axes in the new
basis, the fourth column gives us the new position of the origin.
We could also view this as multiplying a 4
×
4 matrix by the 1
×
4vector:
=
abcd
ef gh
ijkl
0001
x
y
z
1
ax
+
by
+
cz
+
d
ex
+
fy
+
gz
+
h
ix
+
jy
+
kz
+
l
1
In other words, we start and end with a homogeneous coordinate. Because we are not
interested in four-dimensional coordinates, the bottom row of the matrix is always
[0 0 0 1] and the last value in the vector is always 1. We can therefore use just the
version of the equation given in equation 9.6 and make the fourth value in the mul-
tiplied vector (the 1) magically appear as it is needed. We don't store the fourth value
in the Vector3 class.
The matrix-vector multiplication gets implemented in the Matrix4 class as
Excerpt from include/cyclone/core.h
/**
* Holds a transform matrix, consisting of a rotation matrix and
* a position. The matrix has 12 elements; it is assumed that the
* remaining four are (0,0,0,1), producing a homogenous matrix.
*/
class Matrix4
{
// ... Other Matrix4 code as before ...
/**
* Transform the given vector by this matrix.
*
* @param vector The vector to transform.
*/
Vector3 operator*(const Vector3 &vector) const
{
return Vector3(
vector.x * data[0] +