Как преобразовать мировые координаты в координаты камеры? - PullRequest
13 голосов
/ 29 марта 2009

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

Ответы [ 3 ]

15 голосов
/ 29 марта 2009

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

M<sub>00</sub> M<sub>01</sub> M<sub>02</sub> t<sub>x</sub>
M<sub>10</sub> M<sub>11</sub> M<sub>12</sub> t<sub>y</sub>
M<sub>20</sub> M<sub>21</sub> M<sub>22</sub> t<sub>z</sub>
0   0  0   1

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

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

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

7 голосов
/ 31 марта 2009

Если у нас есть такая структура для описания матрицы 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);

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

0 голосов
/ 29 марта 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...