Как преобразовать координаты мира в координаты камеры?

У меня есть входной 3D-вектор, наряду с шагом и рысканием камеры. Может ли кто-нибудь описать или предоставить ссылку на ресурс, который поможет мне понять и реализовать необходимое преобразование и сопоставление матриц?

Ответ 1

Матрица преобразования "мир-камера" - это инверсия матрицы "камера-мир" . Матрица "камера-мир" представляет собой комбинацию перевода в положение камеры и поворот к ориентации камеры. Таким образом, если M - матрица вращения 3x3, соответствующая ориентации камеры, а t - положение камеры, то матрица 4x4 от камеры к миру:

M00 M01 M02 tx
M10 M11 M12 ty
M20 M21 M22 tz
0   0  0   1

Обратите внимание, что я предположил, что векторы представляют собой векторы столбцов, которые умножаются справа на выполнение преобразований. Если вы используете противоположное соглашение, обязательно переставьте матрицу.

Чтобы найти M, вы можете использовать одну из формул, перечисленных в Wikipedia, в зависимости от вашего конкретного соглашения для рулона, высоты тона и рыскания. Имейте в виду, что эти формулы используют соглашение о том, что векторы представляют собой векторы строк, которые умножаются слева.

Вместо вычисления матрицы "камера-мир" и ее инвертирования более эффективная (и численно стабильная) альтернатива заключается в том, чтобы напрямую вычислить матрицу "мир-камера". Для этого просто инвертируйте положение камеры (отрицая все 3 координаты) и ее ориентацию (отрицая углы рулона, высоты тона и угла поворота, а также регулируя их в правильном диапазоне), а затем вычислите матрицу, используя тот же алгоритм.

Ответ 2

Если у нас есть такая структура, чтобы описать матрицу 4x4:

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];
    };
};

Если все, что у вас есть, - это углы Эйлера, то есть углы, представляющие рыскание, шаг и бросок, и точку в 3d-пространстве для позиции, вы можете вычислить векторы 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);

Надеюсь, что это поможет.

Ответ 3

То, что вы описываете, называется "Перспективная проекция", и в Интернете есть множество ресурсов, которые объясняют математическую матрицу и дают код, необходимый для этого. Вы можете начать с страницы википедии