Положение и ориентация openGL из матрицы просмотра модели

Моя проблема заключается в следующем:

У меня есть вложенный объект в мою сцену opengl, и я знаю только их относительное положение и ориентацию.

Как получить абсолютное положение и ориентацию внутреннего объекта? Я думаю о вычислении матрицы представления модели внутреннего объекта, и после этого у меня есть текущая матрица, но как мне преобразовать ее в положение и ориентацию? Другими словами, для двух векторов с плавающей запятой, поэтому я могу вызвать следующий код:

glTranslatef(position.x,position.y,position.z);

glRotatef(alignment.x,1.0f,0.0f,0.0f);
glRotatef(alignment.y,0.0f,1.0f,0.0f);
glRotatef(alignment.z,0.0f,0.0f,1.0f);

Заранее спасибо!


person Adam Loska    schedule 19.11.2009    source источник
comment
Извините, слишком устал для полного ответа на данный момент. Перевод и поворот на самом деле просто умножение со специальными матрицами. (Легко гуглить: матрица перевода вращения). Просто делайте умножения и следите за правильным порядком. Затем выполните умножение матрицы на вектор, и все готово. (Если на это не будет ответа, когда я проснусь завтра, я посмотрю еще раз...)   -  person Andreas    schedule 19.11.2009


Ответы (1)


Если у вас есть матрица просмотра модели объекта, вы можете извлечь позицию с помощью следующего кода:

// ... Some rotations/translations has been applied
GLfloat matrix[16]; 
glGetFloatv (GL_MODELVIEW_MATRIX, matrix);
const float position_x = matrix[12];
const float position_y = matrix[13];
const float position_z = matrix[14];

Вращение немного сложнее, посмотрите на: углы Эйлера. Матрица вращения, которую мы хотим, представляет собой транспонирование zyx-one =>

//c1 = cos(alignment_x)
//c2 = cos(alignment_y)
//c3 = cos(alignment_z)
//s1 = sin(alignment_x)
//s2 = sin(alignment_y)
//s3 = sin(alignment_z)
//matrix[0] = c1 * c2
//matrix[1] = -c2 * s1
//matrix[2] = s2
//matrix[4] = c3 * s1 + c1 * s2 * s3
//matrix[5] = c1 * c3 - s1 * s2 * s3
//matrix[6] = -c2 * s3
//matrix[8] = s1 * s3 - c1 * c3 * s2
//matrix[9] = c3 * s1 * s2 + c1 * s3
//matrix[10] = c2 * c3

Извлечение фактических углов из этого довольно запутанно, потому что есть пара особенностей, если мы их проигнорируем, мы получим:

// Assumes c2 != 0, you'll need more code to handle the special cases
if (matrix[0] != 0.0f || matrix[1] != 0.0f) {
    const float alignment_x = atanf(-matrix[1], matrix[0]);
    float c2;
    if (0 != cosf(alignment_x)) {
        c2 = matrix(0) / cosf(alignment_x);
    } else {
        c2 = matrix(1) / -sinf(alignment_x);
    }
    const float alignment_y = atanf(matrix[2], c2);
    const float alignment_z = atanf(-matrix[6], matrix[10]);
} else {
    alignment_y = atanf(matrix[2], 0);
    //Too tired to deduce alignment_x and alignment_z, someone else?
}

Весь приведенный выше код предполагает, что вы используете только повороты/перемещения, а не масштабирование или перекос.

Позвольте мне закончить, сказав, что углы Эйлера - это зло, на вашем месте я бы искал альтернативное решение любой проблемы, которую вы пытаетесь решить;)

/A.B.

person Andreas Brinck    schedule 25.11.2009
comment
привет, я был бы очень благодарен, если бы вы могли предоставить остальную часть кода, потому что я думаю, что это именно то, что мне нужно в данный момент. у меня тоже есть матрица просмотра модели, и я хочу извлечь 3 угла, чтобы делать такие вещи, как glRotatef (x, 1, 0, 0); glRotatef(y,0,1,0); glRotatef(z,0,0,1); самостоятельно. в моем случае я точно знаю, что с матрицей не выполняются переводы, но я думаю, что это не относится к расчету вращения (?) Будут ли результирующие значения в диапазоне значений от 0 до 360 или от -PI до PI или такие диапазоны? - person Simon; 20.05.2010
comment
как это здесь: songho.ca/opengl/gl_anglestoaxes.html#anglestoaxes относится к вашему коду? вы просто извлекаете углы для всех возможных матриц? - person Simon; 21.05.2010
comment
Да и нет, на странице Сонг Хо показано, как рассчитать матрицу вращения для одной из 6 возможных комбинаций углов Эйлера. То, что вы просите, является обратным: как мне рассчитать конкретный набор углов Эйлера с учетом матрицы вращения? Как я уже сказал в своем первоначальном ответе, это довольно сложно сделать, поскольку есть особенности, которые делают расчет нечетким. Код, который я предоставил выше, даст все углы в радианах. - person Andreas Brinck; 21.05.2010