在我的应用程序中,我有一组对象躺在场景中。它们都在盒子里分组。当用户缩小以查看整个框并开始旋转它时,枢轴点位于框的中间。当您放大以查看内部的特定对象然后旋转相机以便您正在查看的对象(或前方的空间)时,它们仍然围绕此前一个轴点旋转。
我想要实现的是将枢轴点始终放在相机前面。换句话说,当你缩小并看到框时,它会像现在一样旋转。当您放大到特定的物体/空间时,相机会围绕它旋转。
我创建了简单的图像以显示我的意思 - 三角形是相机,红色框是一些物体/空间,橙色圆圈是元素在旋转时进行的路径。第一个是我现在拥有的,第二个是我想拥有的。
我知道在OpenGL中没有类似于相机的东西,所以事实上它是整个世界在移动而不是一点。到目前为止,我已经创造了类似的东西:
glPushMatrix();
glTranslatef(translate[0], translate[1], translate[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
DrawObject();
glPopMatrix();
translate
是一组模拟相机移动的值。
修改
在Ike回答之后我修改了一些我的代码所以现在它看起来像这样:
glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();
因此,如果我正确地获得了Iko的解决方案,那么我现在最关心的是根据我正在观察的地方正确计算枢轴点。这是正确的思考吗?
答案 0 :(得分:1)
获得这种表示的一种方法是将枢轴转换为原点,然后旋转,然后向后退,远离枢轴。
有效地,您可以在枢轴的相反方向(负枢轴,有效地将其移动到原点)进行平移。然后旋转到所需的视角。然后“后退”(在右手坐标系中沿-Z平移)。
这样的事情:
mat4 modelview_matrix(float distance, const vec3& pivot, const vec3& rotation_xyz)
{
mat4 distance_mat = tmat(0.0, 0.0, -distance);
mat4 rot_mat = rmat(rotation_xyz[0], rotation_xyz[1], rotation_xyz[2]);
mat4 pivot_mat = tmat(-pivot[0], -pivot[1], -pivot[2]);
return distance_mat * rot_mat * pivot_mat;
}
上面的 tmat
和rmat
基本上只是构建平移和旋转矩阵。
这使您可以围绕您选择的枢轴绕相机进行环绕。可以通过实际移动枢轴来实现平移,为您提供CAD样式的视口导航控件。
因此,如果我正确地获得Iko的解决方案,那么我最关心的是 根据我正在寻找的地方正确计算枢轴点 在。这是正确的思考吗?
相当多 - 可能稍微调整一下。这个支点始终是你所看到的 - 它将成为你的兴趣中心。例如,您可以将它放在场景边界框的中心,例如(一些3D软件这样做是为了适应/构建场景周围的视图)。之后,您可以根据自己喜欢的软件设计将枢轴点放在您喜欢的位置。相机总是会看着它。
修改强>
glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();
对于这种事情,你可能想要更像这样的东西:
glTranslatef(-pivot[0], -pivot[1], -pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(0, 0, -distance);
...在推送到转换堆栈和渲染单个对象之外(在调用堆栈的顶部执行此操作)。这就是为你提供类似于“相机控制”的东西。
然后,当渲染每个对象时,推送当前变换并为每个对象和子项执行必要的局部变换。这给你的东西类似于独立于相机在世界中移动和定向的物体,以及具有亲子关系的运动层次结构。