本来打算用现成的路径点漫游器,发现很不好用,限制也多,干脆自己写一个得了。
一,派生于osgGA::CameraManipulator
class TravelManipulator : public osgGA::CameraManipulator
二,设置位置和朝向
//视点
osg::Vec3 m_vPosition;
//朝向
osg::Vec3 m_vRotation;
把初始位置可以放在原点,也可以任意一点。实际上,应该放在路径点的第0个位置。
m_vPosition = osg::Vec3(0, 0, 0);
值得注意的是,朝向要绕X轴转90度,才能和默认漫游器一样,look方向指向Y轴正向,即
m_vRotation = osg::Vec3(osg::PI_2, 0, 0);
这里用到了路径点,从X轴正向开始,所以再减去90度,使look方向的初始方向为X轴正向,便于计算。
即
m_vRotation = osg::Vec3(osg::PI_2, 0, -osg::PI_2);
三,设置漫游器的矩阵和逆矩阵,这个是固定的。没有它,就不能正确看到场景了。
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByMatrix(const osg::Matrixd& matrix);
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
virtual void setByInverseMatrix(const osg::Matrixd& matrix) ;
/** get the position of the manipulator as 4x4 Matrix.*/
virtual osg::Matrixd getMatrix() const;
/** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
virtual osg::Matrixd getInverseMatrix() const;
void TravelManipulator::setByMatrix(const osg::Matrixd& matrix)
{
}
void TravelManipulator::setByInverseMatrix(const osg::Matrixd& matrix)
{
}
osg::Matrixd TravelManipulator::getMatrix() const
{
osg::Matrixd mat1;
mat1.makeTranslate(m_vPosition);
osg::Matrixd mat2;
mat2.makeRotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1], osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS);
return mat2 * mat1;
}
osg::Matrixd TravelManipulator::getInverseMatrix() const
{
osg::Matrixd mat1;
mat1.makeTranslate(m_vPosition);
osg::Matrixd mat2;
mat2.makeRotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1], osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS);
return osg::Matrixd::inverse(mat2 * mat1);
}
四,在handle()中,使用frame,这样就可以自由漫游了
即在virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
五,漫游器的朝向,不是坐标系的XYZ轴,而是PItch,r

文章介绍了如何派生自osgGA::CameraManipulator类来创建一个自定义的漫游器。通过设置位置、朝向、矩阵和逆矩阵,实现了对视点的控制。在handle函数中处理帧更新,以实现自由漫游。同时,文章详细讨论了坐标转换和插值方法,特别是从球面坐标到XYZ坐标的转换,以及根据路径点进行朝向计算。
最低0.47元/天 解锁文章

809

被折叠的 条评论
为什么被折叠?



