The axis of rotation is build of all lined up points that do not change their position when the rotation is performed. You can see easily that [0,0,0] ever belongs to the axis, because regardless of what rotation matrix you apply to [0,0,0], the result will ever be [0,0,0]. In other words, every and each axis of rotation passes through [0,0,0].
Now, well, perhaps you don't want this. Perhaps you want an axis that passes through [1,2,3], but if you apply a rotation to [1,2,3] it will in general result in something differing from [1,2,3]. To solve this, you do the following:
1. translate by [1,2,3] * (-1)
3. translate by [1,2,3] * (+1)
Look at the desired point and observe what happens (I'm using row vectors here):
p1 := [1,2,3]
p2 := p1 * T(-1,-2,-3) = p1 + [-1,-2,-3] = [0,0,0] // application of first translation
p3 := p2 * R = [0,0,0] * R = [0,0,0] // application of rotation gives always [0,0,0] for input [0,0,0]
p4 := p3 * T(1,2,3) = [0,0,0] + [1,2,3] = [1,2,3] // application of second translation
Notice that due to the surrounding translations the desired origin of rotation is temporarily shifted to [0,0,0] so that is guaranteed fixed during rotation.
You may observe that if you don't apply any translation (I mean as part of the model or camera transform here), then the local origin is still at the world's [0,0,0]. That is the reason why, when computing a model's world transform matrix, the rotation is done before the translation. (Similarly, the scaling is done before the rotation, before scaling does neither change point [0,0,0] nor the direction of any of the principal axes, which is important for the rotation afterwards.)
Now, if your camera's transform is already set to a copy of the model's head transform, then in general both a translation and a rotation are already applied. If you want to rotate the camera around a local axis of something, you need to temporarily not only undo the translation but also the rotation. If the copied world transform is named M, you need to apply its inverse
then do the rotation, so in summary:
R * M-1
then redo the former undo, so in summary:
M * R * M-1
With a given transform of the camera C you have then the new world transform of the camera as:
C' := M * R * M-1 * C
In your case C is the copy of the world transform of the head. M is the world transform of the head, too, because you want to apply the rotation R in the head's local space. That means that C == M and hence due to
C' := M * R * M-1 * C = M * R * M-1 * M = M * R
you get M-1 * M canceling out on the right side, leaving the equation of a simple parenting (a.k.a. forward kinematic). Et voila: All you need is to rotate the camera locally and handle it as child of the model's head.
Edited by haegarr, 31 January 2014 - 12:26 PM.