Вращение OpenGL в пространстве просмотра - PullRequest
2 голосов
/ 23 апреля 2020

Я хочу сделать объект, определенный в пространстве моделирования, для перевода в пространство просмотра. Количество перевода контролируется путем нажатия и перетаскивания мыши (варьируя deltaX и deltaY). И вот код, который работает хорошо: (ссылка https://gist.github.com/ptbrowne/2048812)

glPushMatrix();
glLoadMatrixd(cam2wld[cameraIndex].matrix());
glTranslated(deltaX, deltaY, 0);
glMultMatrixd(wld2cam[cameraIndex].matrix());
glMultMatrixd(obj2wld.matrix());
glGetDoublev(GL_MODELVIEW_MATRIX, obj2wld.matrix());
glPopMatrix();

Я также хочу повернуть объект относительно оси x камеры (экрана), количество вращения зависит от повторного перетаскивания мышью. Однако при изменении с

glTranslated(deltaX, deltaY, 0);

на

glRotated(deltaX + deltaY, 1, 0, 0);

Объект переводится вместо этого. Есть идеи, как решить проблему? Спасибо.

1 Ответ

2 голосов
/ 23 апреля 2020

Я предполагаю, что wld2cam[cameraIndex] - это матрица вида, а cam2wld[cameraIndex] - это матрица обратного вида:

glLoadMatrixd(cam2wld[cameraIndex].matrix());
glRotated(deltaY, 1, 0, 0);
glMultMatrixd(wld2cam[cameraIndex].matrix());

Что вы на самом деле делаете, это поворачиваете модель вокруг точка зрения. Ось вращения (1, 0, 0) является осью X пространства обзора. Если расстояние от камеры до модели велико, а угол невелик, это вращение выглядит как перевод:

Вам необходимо определить ось вращения. Например, происхождение мира. В поле зрения происхождение мира:

const GLdouble *viewMat = cam2wld[cameraIndex].matrix();
GLdouble pivotX = viewMat[12];
GLdouble pivotY = viewMat[13];
GLdouble pivotZ = viewMat[14];

glLoadMatrixd(cam2wld[cameraIndex].matrix());

glTranslated(pivotX, pivotY, pivotZ);
glRotated(deltaY, 1, 0, 0);
glTranslated(-pivotX, -pivotY, -pivotZ);

glMultMatrixd(wld2cam[cameraIndex].matrix());

Если вы хотите выполнять сложные матричные операции, то я рекомендую использовать такую ​​библиотеку, как OpenGL Matmatics (GLM) :

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
glm::dmat4 c2w = glm::make_mat4<double>(cam2wld[cameraIndex].matrix());
glm::dmat4 t   = glm::translate(glm::dmat4(1.0), glm::dvec3( deltaX, deltaY, 0.0));
glm::dmat4 w2c = glm::make_mat4<double>(wld2cam[cameraIndex].matrix());
glm::dmat4 o2w = glm::make_mat4<double>(obj2wld.matrix());

glm::dmat final = c2w * t * w2c * o2w;
glLoadMatrixd(glm::value_ptr(final));
...