查看: 3067|回复: 11

相机的观察矩阵只是由平移和旋转组成了吗?

[复制链接]

该用户从未签到

发表于 2012-7-11 09:27:53 | 显示全部楼层 |阅读模式
自定义了一个漫游器,使用KeySwitchMatrixManipulator来进行切换,但是切换到自定义的漫游器时,相机的位置和姿态发生了变化,这是为什么?????求解!!!
已经在自定义的漫游器中重写了setByMatrix,定义如下:
virtual void setByMatrix(const osg::Matrixd& matrix)
        {
               
                m_vPosition=matrix.getTrans();
                m_vRotation=matrix.getRotate().asVec3();
                //m_Matrix=matrix;
       
       
        }
其中平移、旋转矩阵定义如下:osg::Vec3 m_vPosition;osg::Vec3 m_vRotation;
getMatrix、getInverseMatrix重写如下:

virtual osg::Matrixd getMatrix(void)const
        {
                //return m_Matrix;
                osg::Matrixd mat;
                mat.makeRotate(m_vRotation._v[0],osg::Vec3f(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3f(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3f(0.0,0.0,1.0));
                return mat*osg::Matrixd::translate(m_vPosition);
        }
        virtual osg::Matrixd getInverseMatrix()const
        {
                /*return osg::Matrixd::inverse(m_Matrix);*/

                osg::Matrixd mat;
                mat.makeRotate(m_vRotation._v[0],osg::Vec3f(1.0,0.0,0.0),m_vRotation._v[1],osg::Vec3f(0.0,1.0,0.0),m_vRotation._v[2],osg::Vec3f(0.0,0.0,1.0));
                return osg::Matrixd::inverse(mat*osg::Matrixd::translate(m_vPosition));
        }




PS:测试了一下,如果直接使用矩阵的话,切换时相机的位置和姿态是一致的~~~~

该用户从未签到

发表于 2012-7-11 12:09:14 | 显示全部楼层
这个可以断点调试一下,KeySwitchMatrixManipulator()好像调用了Home()函数,进而调用了漫游器的Home()函数,这样可能会改变一些参数以及东西。
   直接使用矩阵,这句话的上下文是什么意思? 例如键盘触发,切换漫游器? 

该用户从未签到

 楼主| 发表于 2012-7-11 13:31:44 | 显示全部楼层
CWorld 发表于 2012-7-11 12:09
这个可以断点调试一下,KeySwitchMatrixManipulator()好像调用了Home()函数,进而调用了漫游器的Home()函数 ...

我在论坛上看帖子说是通过setByMatrix传递相机的视点,直接用矩阵的意思是,直接使用相机的观察矩阵,不用平移和旋转矩阵相乘得到相机的观察矩阵。

该用户从未签到

发表于 2012-7-13 09:42:50 | 显示全部楼层
  1. m_vRotation=matrix.getRotate().asVec3();
复制代码
您在这里是否把这个m_vRotation当成欧拉角度来用了?但是它绝不是欧拉角度,而是四元数的向量部分!这两者绝对不可混淆

额外提一点就是,从数学上,四元数也不可能直接转换到欧拉角,因为缺少旋转顺序的参数。

该用户从未签到

 楼主| 发表于 2012-7-16 17:07:55 | 显示全部楼层
array 发表于 2012-7-13 09:42
您在这里是否把这个m_vRotation当成欧拉角度来用了?但是它绝不是欧拉角度,而是四元数的向量部分!这两者绝 ...

是的,那么这么转换的方式可行吗?
virtual void setByMatrix(const osg::Matrixd& matrix)
{
double angle0,angle1,angle2;
osg:uat quat=matrix.getRotate();
quat.getRotate(angle0,osg::Vec3f(1.0,0.0,0.0));
quat.getRotate(angle1,osg::Vec3f(0.0,1.0,0.0));
quat.getRotate(angle2,osg::Vec3f(0.0,0.0,1.0));
m_vRotation[0]=osg:egreesToRadians(angle0);
m_vRotation[1]=osg::DegreesToRadians(angle1);
m_vRotation[2]=osg::DegreesToRadians(angle2);

m_vPosition=matrix.getTrans();       
}

该用户从未签到

 楼主| 发表于 2012-7-16 17:44:22 | 显示全部楼层
caoze1986 发表于 2012-7-16 17:07
是的,那么这么转换的方式可行吗?
virtual void setByMatrix(const osg::Matrixd& matrix)
{

已解决,将 osg::Vec3 m_vRotation换成osg:uat m_qRotation,后续代码做相应的改变~~谢谢~~

该用户从未签到

发表于 2012-7-18 09:22:35 | 显示全部楼层
  1. quat.getRotate(angle0,osg::Vec3f(1.0,0.0,0.0));
  2. quat.getRotate(angle1,osg::Vec3f(0.0,1.0,0.0));
  3. quat.getRotate(angle2,osg::Vec3f(0.0,0.0,1.0));
复制代码
这也是错误的,getRotate的两个参数都是作为输出使用的,也就是它会同时输出当前旋转的参考角度和参考轴。从数学上,四元数也不可能直接转换到欧拉角,因此如果不是立志在数学史上留下自己的大名的话,就不必在这一点上枉费心机了

该用户从未签到

发表于 2012-9-27 09:59:21 | 显示全部楼层
caoze1986 发表于 2012-7-16 17:44
已解决,将 osg::Vec3 m_vRotation换成osg:uat m_qRotation,后续代码做相应的改变~~谢谢~~

你好,我也遇到了同样的问题,想设置setmatrix(),你是怎样解决的?“将 osg::Vec3 m_vRotation换成osguat m_qRotation,后续代码做相应的改变”,后面怎样改啊,例如getmatrix中原来都是对osg::Vec3 m_vRotation的参数变化的,方便的话能不能把代码共享一下,或者发邮箱smengq@163.com,非常感谢!

该用户从未签到

发表于 2012-9-27 11:33:57 | 显示全部楼层
跟帖,学习中

该用户从未签到

发表于 2012-10-11 11:14:55 | 显示全部楼层
caoze1986 发表于 2012-7-16 17:44
已解决,将 osg::Vec3 m_vRotation换成osg:uat m_qRotation,后续代码做相应的改变~~谢谢~~

你好,我也遇到了同样的问题,想设置setmatrix(),你是怎样解决的?“将 osg::Vec3 m_vRotation换成osguat m_qRotation,后续代码做相应的改变”,后面怎样改啊,方便的话能不能把代码共享一下,或者发邮箱394688654@qq.com,非常感谢!

该用户从未签到

发表于 2012-10-12 08:39:48 | 显示全部楼层

该用户从未签到

 楼主| 发表于 2012-10-15 17:12:38 | 显示全部楼层
smengq 发表于 2012-9-27 09:59
你好,我也遇到了同样的问题,想设置setmatrix(),你是怎样解决的?“将 osg::Vec3 m_vRotation换成osg ...

virtual osg::Matrixd getMatrix(void)const
        {
                osg::Matrixd mat;
                return osg::Matrixd::rotate(m_qRotation)*osg::Matrixd::translate(m_vPosition);
}
下面旋转操作时候用下面方法得到角度
m_qRotation.getRotate(angle,osg::Vec3f(0.0,0.0,1.0));


但是这种方法在后面的旋转操作时候出现问题

可以参考osgTerrainManipulator漫游器的参数_center,_rotation以及_distance来改写~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表