调整轴指示器的视图矩阵

时间:2013-11-04 16:28:39

标签: math 3d camera openscenegraph

我正在尝试为另一个视口的摄像机配置轴指示器的osg::Camera行为(在大多数CAD应用程序中,每个3D视口中都有一个代表每个世界空间轴的小模型)。 p>

我是通过拉动视口相机的视图矩阵来完成的:

// fCam is the 'owning' viewport's camera i.e. the followed camera.
Matrixd newMatrix = fCam->getViewMatrix();

然后我将其反转,以获取相机的变换矩阵并获取相机的反向视图矢量:

newMatrix.invert( newMatrix );

Vec3d eye, focus, up;
newMatrix.getLookAt( eye, focus, up );

eye = focus - eye;
eye.normalize();

我使用视图矢量将相机定位在离原点(轴模型所在的位置)的固定距离处,然后再次反转矩阵以获得最终的相机视图矩阵:

newMatrix.setTrans( eye * 4.0f );
newMatrix.invert( newMatrix );

viewCam->setViewMatrix( newMatrix );

这应该具有将轴指示器摄像机设置为遵循“拥有”视口的摄像机方向的效果,但保持与原点的固定距离并使原点始终位于视口的死点。

但它不起作用。方向显示正确,但位置似乎没有变化,导致轴模型在屏幕外移动。我正在使用OpenSceneGraph,并且View没有连接相机操纵器。所以我不明白为什么相机不会像我预期的那样移动 - 任何建议?

2 个答案:

答案 0 :(得分:0)

我通过使用内置*LookAt(..)方法获取设置解决了这个问题:

Vec3d eye, focus, up;
fCam->getViewMatrixAsLookAt( eye, focus, up );

eye = eye - focus;
eye.normalize();
viewCam->setViewMatrixAsLookAt( eye * 4.0, Vec3d(), up );

我看不出我的“手动”代码和这些便捷方法之间有什么区别。我以为OSG可能会在渲染管道中稍后执行一些额外的转换,但我找不到它的源代码。

答案 1 :(得分:-1)

<强>更新

我误解了数学要求,但在查找解决方案后发现了问题。

newMatrix.getLookAt( eye, focus, up );
在返回getLookAteye, focus之前,

up方法采用给定矩阵的逆。由于你提供倒置矩阵,你的原始代码会失败,所以它应该是这样的:

Matrixd newMatrix = fCam->getViewMatrix();

Vec3d eye, focus, up;
newMatrix.getLookAt( eye, focus, up );

eye = eye - focus;
eye.normalize();

newMatrix.invert( newMatrix );
newMatrix.setTrans( eye * 4.0f );
newMatrix.invert( newMatrix );

viewCam->setViewMatrix( newMatrix );

我认为问题来自:

newMatrix.setTrans( eye * 4.0f );

此方法相对于原点(0,0,0)设置位置。你应该使用类似的东西:

osg::Vec3 direction = focus - eye;
direction.normalize();

newMatrix.setTrans( eye + direction * 4.0f );