Если у нас есть такая структура для описания матрицы 4х4:
class Matrix4x4
{
public:
union
{
struct
{
Type Xx, Xy, Xz, Xw;
Type Yx, Yy, Yz, Yw;
Type Zx, Zy, Zz, Zw;
Type Wx, Wy, Wz, Ww;
};
struct
{
Vector3<Type> Right;
Type XW;
Vector3<Type> Up;
Type YW;
Vector3<Type> Look;
Type ZW;
Vector3<Type> Pos;
Type WW;
};
Type asDoubleArray[4][4];
Type asArray[16];
};
};
Если все, что у вас есть, это углы Эйлера, то есть углы, представляющие отклонение от оси, угол наклона и крена, а также точку в трехмерном пространстве для позиции, вы можете рассчитать векторы Right, Up и Look. Обратите внимание, что Right, Up и Look - это только векторы X, Y, Z, но, поскольку это камера, мне проще ее так назвать. Самый простой способ применить ваше вращение к матрице камеры - это построить серию матриц вращения и умножить нашу матрицу камеры на каждую матрицу вращения.
Хорошая ссылка для этого здесь: http://www.euclideanspace.com
Как только вы применили все необходимые повороты, вы можете установить вектор Pos в положение камеры в мировом пространстве.
Наконец, перед тем, как применить преобразование камеры, вам нужно взять инверсию камеры относительно ее матрицы. Это то, на что вы собираетесь умножить матрицу вида модели, прежде чем начнете рисовать полигоны. Для вышеприведенного класса матрицы обратное вычисляется следующим образом:
template <typename Type>
Matrix4x4<Type> Matrix4x4<Type>::OrthoNormalInverse(void)
{
Matrix4x4<Type> OrthInv;
OrthInv = Transpose();
OrthInv.Xw = 0;
OrthInv.Yw = 0;
OrthInv.Zw = 0;
OrthInv.Wx = -(Right*Pos);
OrthInv.Wy = -(Up*Pos);
OrthInv.Wz = -(Look*Pos);
return OrthInv;
}
Итак, наконец, со всей конструкцией нашей матрицы, вы будете делать что-то вроде этого:
Matrix4x4<float> cameraMatrix, rollRotation, pitchRotation, yawRotation;
Vector4<float> cameraPosition;
cameraMatrix = cameraMatrix * rollRotation * pitchRotation * yawRotation;
Matrix4x4<float> invCameraMat;
invCameraMat = cameraMatrix.OrthoNormalInverse();
glMultMatrixf(invCameraMat.asArray);
Надеюсь, это поможет.