查看: 1280|回复: 7

请问关于漫游器的问题

[复制链接]

该用户从未签到

发表于 2010-4-20 09:28:35 | 显示全部楼层 |阅读模式
我在自定义漫游器handle()中有如下代码:
//抬头
osg::Matrixd curMatrix = getMatrix();
osg::Matrixd transformMat;
transformMat.makeRotate( 0.1 , osg::Vec3(1.0,0.0,0.0));
setByMatrix(transformMat*curMatrix);
//左转
osg::Matrixd curMatrix = getMatrix();
osg::Matrixd transformMat;
transformMat.makeRotate( 0.1 , osg::Vec3(0.0,1.0,0.0));
setByMatrix(transformMat*curMatrix);

问题:抬(或低)头后再左(或右)转时,相机就不在水平位置,我的目的是让相机不管抬头低头,都保持水平,该如何解决。对矩阵变换不熟悉。

该用户从未签到

发表于 2010-4-20 09:51:36 | 显示全部楼层
试试将矩阵乘的顺序换一下

该用户从未签到

 楼主| 发表于 2010-4-20 09:58:12 | 显示全部楼层
emhxj的意思是setByMatrix(curMatrix*transformMat)吗?
测试了,结果不对,水平时都不能左右转动了。

该用户从未签到

发表于 2010-4-20 10:56:15 | 显示全部楼层
不知道你代码中具体是怎么写的,如果你要始终保持水平,我觉得可以这样实现
osg::Matrixd curMatrix = getMatrix();  //当前矩阵
osg::Matrixd transformMatHead;        //抬头矩阵
osg::Matrixd transformMatLeft;          //左转矩阵
//抬头
transformMatHead.makeRotate( 0.1 , osg::Vec3(1.0,0.0,0.0));
//左转
transformMatLeft.makeRotate( 0.1 , osg::Vec3(0.0,1.0,0.0));
//最后变换
setByMatrix(transformMatHead*transformMatLeft*curMatrix);

该用户从未签到

 楼主| 发表于 2010-4-20 11:55:37 | 显示全部楼层
alessili:
我的代码是这样的:
.....(其他方向键)
else if(ea.getKey() == GUIEventAdapter::KEY_Right )//右转
{
       osg::Matrixd curMatrix = getMatrix();
       osg::Matrixd transformMat;
       transformMat.makeRotate( -0.1 , osg::Vec3(0.0,1.0,0.0));
       setByMatrix(curMatrix*transformMat);
}
else if( ea.getKey() == GUIEventAdapter::KEY_Up )//抬头
{
       osg::Matrixd curMatrix = getMatrix();
       osg::Matrixd transformMat;
       transformMat.makeRotate( 0.1 , osg::Vec3(1.0,0.0,0.0));
       setByMatrix(transformMat*curMatrix);
}
.....(其他方向键)
每次只是按下一个键。你的这个代码好像不适合

该用户从未签到

发表于 2010-4-20 12:34:16 | 显示全部楼层
我很好奇的是您为什么在自定义的漫游器里还要使用setByMatrix()?有的时候这并不能实现想要的效果,最典型的就是HPR旋转的实现,单纯用一个矩阵的反复变换是无法完全表达的。这种时候完全应该自己定义多个可操作的成员变量,然后在getMatrix和getInverseMatrix函数的实现中对它们进行组合,计算出正确的变换结果

否则的话,对您的情况就必须先计算出当前观察矩阵下的上方向(UpVector)和前方向(LookAt),然后叉积得到侧向量(sideVector)并以它为轴旋转,而不能简单地使用Vec3(1,0,0)

该用户从未签到

发表于 2010-4-20 12:53:44 | 显示全部楼层
.....................
osg::Matrixd curMatrix = getMatrix();  //当前矩阵
osg::Matrixd transformMatHead;        //抬头矩阵
osg::Matrixd transformMatLeft;          //左转矩阵
//。。。。其他矩阵
.....(其他方向键)
else if(ea.getKey() == GUIEventAdapter::KEY_Right )//右转
{
transformMatLeft.makeRotate( 0.1 , osg::Vec3(0.0,1.0,0.0));
}
else if( ea.getKey() == GUIEventAdapter::KEY_Up )//抬头
{
transformMatHead.makeRotate( 0.1 , osg::Vec3(1.0,0.0,0.0));
}
.....(其他方向键)
//最后变换
setByMatrix(transformMatHead*transformMatLeft*curMatrix);

该用户从未签到

 楼主| 发表于 2010-4-20 19:34:30 | 显示全部楼层
已经解决,诚如阿锐所说,没必要setByMatrix(),而是设定多个可操作的成员变量,在getMatrix和getInverseMatrix函数的实现中对它们进行组合,得到想要的结果。
还是对osg的一些基础的东西不熟悉,急于求成。参考了FlySky的代码,稍作修改就好了。谢谢楼上所有回答问题的兄弟们。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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