The question is, do you want to transform the object or the world? In other words, you can rotate the object and move (translate) it to a specific position or you can rotate the world around a specific point (orbit camera).
As pointed out by 'scg': T * R != R * T
A Transformation formula for the object would be: T * C * R * -C
(T: Translate, C: Center, R: Rotation)
Now, there are a lot of operations involved. If you look at a Translation- or Rotationmatrix, there are a lot of zeros. You can eliminate those steps:
Example:
typedef struct mat4_rec {
float
a11, a12, a13, a14,
a21, a22, a23, a24,
a31, a32, a33, a34,
a41, a42, a43, a44;
} mat4_t;
mat4_t* translate(mat4_t *m, float x, float y, float z)
{
m->a14 += m->a11 * x + m->a12 * y + m->a13 * z;
m->a24 += m->a21 * x + m->a22 * y + m->a23 * z;
m->a34 += m->a31 * x + m->a32 * y + m->a33 * z;
m->a44 += m->a41 * x + m->a42 * y + m->a43 * z;
return m;
}
To translate a 4x4 Matrix (M *= T). These are a lot less operations than a full 4x4 Multiplication.
Rotation (M *= R) would look like this:
mat4_t* rotate(mat4_t *m, float rad, float x, float y, float z)
{
float s = sinf(rad);
float c = cosf(rad);
float t = 1.0f - c;
float a11 = x * x * t + c;
float a12 = x * y * t - z * s;
float a13 = x * z * t + y * s;
float a21 = y * x * t + z * s;
float a22 = y * y * t + c;
float a23 = y * z * t - x * s;
float a31 = z * x * t - y * s;
float a32 = z * y * t + x * s;
float a33 = z * z * t + c;
float m11 = m->a11;
float m12 = m->a12;
float m13 = m->a13;
float m21 = m->a21;
float m22 = m->a22;
float m23 = m->a23;
float m31 = m->a31;
float m32 = m->a32;
float m33 = m->a33;
float m41 = m->a41;
float m42 = m->a42;
float m43 = m->a43;
m->a11 = m11 * a11 + m12 * a21 + m13 * a31;
m->a12 = m11 * a12 + m12 * a22 + m13 * a32;
m->a13 = m11 * a13 + m12 * a23 + m13 * a33;
m->a21 = m21 * a11 + m22 * a21 + m23 * a31;
m->a22 = m21 * a12 + m22 * a22 + m23 * a32;
m->a23 = m21 * a13 + m22 * a23 + m23 * a33;
m->a31 = m31 * a11 + m32 * a21 + m33 * a31;
m->a32 = m31 * a12 + m32 * a22 + m33 * a32;
m->a33 = m31 * a13 + m32 * a23 + m33 * a33;
m->a41 = m41 * a11 + m42 * a21 + m43 * a31;
m->a42 = m41 * a12 + m42 * a22 + m43 * a32;
m->a43 = m41 * a13 + m42 * a23 + m43 * a33;
return m;
}
To implement the transformation: T * C * R * -C
mat4_t m; // <- set to identiy or something else
// T - move position of object by one unit along the x axis
translate(&m, 1, 0, 0);
// C - move pivot point down along the y axis
translate(&m, 0, -1, 0);
// R - 180 degress around the z axis
rotate(&m, M_PI, 0, 0, 1);
// -C - restore pivot point
translate(&m, 0, 1, 0);
// multiply matrix by any vector (M * V)