查看时的 OpenGL 旋转 Space
OpenGL Rotation in Viewing Space
我想使在建模 space 中定义的对象在查看 space 中进行翻译。通过单击并拖动鼠标(改变 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);
改为翻译对象。知道如何解决问题吗?谢谢。
我假设wld2cam[cameraIndex]
是视图矩阵,cam2wld[cameraIndex]
是逆视图矩阵:
glLoadMatrixd(cam2wld[cameraIndex].matrix());
glRotated(deltaY, 1, 0, 0);
glMultMatrixd(wld2cam[cameraIndex].matrix());
你实际上做的是围绕视角旋转模型。旋转轴 (1, 0, 0) 是视图 space x 轴。如果相机到模型的距离大,角度小,这个旋转就好像是一个平移:
您必须为旋转定义一个枢轴。比如世界的起源。鉴于space世界的起源:
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 Mathematics (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));
我想使在建模 space 中定义的对象在查看 space 中进行翻译。通过单击并拖动鼠标(改变 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);
改为翻译对象。知道如何解决问题吗?谢谢。
我假设wld2cam[cameraIndex]
是视图矩阵,cam2wld[cameraIndex]
是逆视图矩阵:
glLoadMatrixd(cam2wld[cameraIndex].matrix()); glRotated(deltaY, 1, 0, 0); glMultMatrixd(wld2cam[cameraIndex].matrix());
你实际上做的是围绕视角旋转模型。旋转轴 (1, 0, 0) 是视图 space x 轴。如果相机到模型的距离大,角度小,这个旋转就好像是一个平移:
您必须为旋转定义一个枢轴。比如世界的起源。鉴于space世界的起源:
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 Mathematics (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));