查看: 2864|回复: 16

请教OSG矩阵问题

[复制链接]

该用户从未签到

发表于 2010-3-22 11:15:36 | 显示全部楼层 |阅读模式
//创建一个矩阵
osg::Matrix m2;
m2.makeScale(0.5f,0.5f,0.5f);
m2.makeTranslate(osg::Vec3(-20.f,0.0f,0.0f));
m2.makeRotate(-45.0f,1.0f,.0f,0.0f);
mt2->setMatrix(m2);
mt2->addChild(node.get());
我这代码运行的时候,只有m2.makeRotate(-45.0f,1.0f,.0f,0.0f);起作用。前面两句不起作用,是什么原因?我换了一下那三句代码的位置,反正只有最后面一句起作用。

该用户从未签到

发表于 2010-3-22 11:23:26 | 显示全部楼层
用makeRotate时的意思是根据传入的参数生成该旋转矩阵,每进行一次时都会先设置为单位矩阵,要实现你那种效果可以用m2.preMultTranslate(),m2.preMultRotate(),m2.preMultScale(),将会先移动、再旋转=、在缩放

该用户从未签到

发表于 2010-3-22 12:29:07 | 显示全部楼层
  1. makeScale
  2. postTranslate
  3. postRotate
复制代码
这样也是可以的

该用户从未签到

 楼主| 发表于 2010-3-22 14:32:48 | 显示全部楼层
谢谢指导!问题解决
mt2->setMatrix(osg::Matrix::scale(0.5f,0.5f,0.5f)*osg::Matrix::translate(-20.f,0.0f,0.0f)*osg::Matrix::rotate(-45.0f,1.0f,.0f,0.0f));
我用这个也解决了

该用户从未签到

 楼主| 发表于 2010-3-22 15:25:01 | 显示全部楼层
我用这个代码
mt2->setMatrix(osg::Matrix::scale(0.5f,0.5f,0.5f)*osg::Matrix::rotate(45.0f,1.0f,.0f,0.0f)*osg::Matrix::translate(20.f,0.0f,0.0f));
和这个代码得出的结果不同的
        m2.preMultScale(osg::Vec3(0.5f,0.5f,0.5f));
        m2.preMultRotate(osg:uat(45.0f,1.0f,0.0f,0.0f));
        m2.preMultTranslate(osg::Vec3(20.f,0.0f,0.0f));

该用户从未签到

发表于 2010-3-23 08:25:18 | 显示全部楼层
注意矩阵相乘的顺序问题:
  1. m2.preMultScale(osg::Vec3(0.5f,0.5f,0.5f));
  2.         m2.preMultRotate(osg::Quat(45.0f,1.0f,0.0f,0.0f));
  3.         m2.preMultTranslate(osg::Vec3(20.f,0.0f,0.0f));
复制代码
的结果是:scale左乘rotate,再左乘translate,即:
  1. translate * rotate * scale
复制代码
使用postScale,postRotate和postTranslate是可以的

该用户从未签到

 楼主| 发表于 2010-3-23 08:55:52 | 显示全部楼层
谢谢!
“使用postScale,postRotate和postTranslate是可以的”
是不是写错了,中间忘记了Mult??

该用户从未签到

发表于 2010-3-23 10:42:38 | 显示全部楼层
呵呵,我只是简单说明一下,您自己明白就可以了

该用户从未签到

 楼主| 发表于 2010-3-23 10:51:19 | 显示全部楼层
非常谢谢指导!!

该用户从未签到

发表于 2011-2-17 18:58:33 | 显示全部楼层
mt2->setMatrix(osg::Matrix::scale(0.5f,0.5f,0.5f)*osg::Matrix::rotate(45.0f,1.0f,.0f,0.0f)*osg::Matrix::translate(20.f,0.0f,0.0f));

mt2->setMatrix(osg::Matrix::scale(0.5f,0.5f,0.5f)*osg::Matrix::translate(20.f,0.0f,0.0f)*osg::Matrix::rotate(45.0f,1.0f,.0f,0.0f));
的运行结果貌似是一致的,请高手指点一下。

该用户从未签到

发表于 2011-2-18 10:41:28 | 显示全部楼层
这很正常:先绕X轴转动一个角度,然后沿X轴运动;以及先沿X轴运动,然后绕X轴转动——这两者的结果本来就是相同的

该用户从未签到

发表于 2011-2-19 09:21:01 | 显示全部楼层
这很正常:先绕X轴转动一个角度,然后沿X轴运动;以及先沿X轴运动,然后绕X轴转动——这两者的结果本来就是 ...
array 发表于 2011-2-18 10:41

操作的是局部坐标么?指点一下

该用户从未签到

发表于 2011-2-21 08:46:15 | 显示全部楼层
您要指点什么

该用户从未签到

发表于 2011-2-21 09:28:39 | 显示全部楼层
回复 13# array


    已经解决,谢谢

该用户从未签到

发表于 2011-3-26 21:09:34 | 显示全部楼层
本帖最后由 cyscsharp 于 2011-3-26 22:46 编辑
这很正常:先绕X轴转动一个角度,然后沿X轴运动;以及先沿X轴运动,然后绕X轴转动——这两者的结果本来就是 ...
array 发表于 2011-2-18 10:41




是的,您说的很对,“先绕X轴转动一个角度,然后沿X轴运动;以及先沿X轴运动,然后绕X轴转动”这是对的
下面的代码证明了您的说法是正确的

/***先平移再饶X轴转动90度**/
osg::Node* cow = osgDB::readNodeFile("cow.osg");
//创建姿态节点
osg::PositionAttitudeTransform* posCow = new osg::PositionAttitudeTransform;
root->addChild(posCow);
posCow->addChild(cow);
osg::Quat quat;
posCow->setPosition(osg::Vec3(10,0.0,0.0));
//旋转
quat.makeRotate(osg::PI_2,osg::Vec3(1.0,0.0,0.0));
posCow->setAttitude(quat);

/*****先饶X轴转动90度再平移10**/

osg::Quat quat1;
//创建变换节点
osg::MatrixTransform* matrixCow1  = new osg::MatrixTransform;
root->addChild(matrixCow1);
matrixCow1->addChild(cow);
//旋转
quat1.makeRotate(osg::PI_2,osg::Vec3(1.0,0.0,0.0));
//设置位置
matrixCow1->setMatrix(osg::Matrixd::translate(osg::Vec3(10.0,0.0,0.0))*osg::Matrixd::rotate(quat1));

结果两个牛重合了,所以说您的说法是正确的
如图:

1.JPG

可是当我把X轴改成Z轴,其它代码不变,为何两个牛就不重合了呢?为什么呢?按道理来说是一样的呀


2.JPG

该用户从未签到

发表于 2011-3-26 21:13:46 | 显示全部楼层
补充:
先绕X轴转动一个角度,然后沿X轴运动;以及先沿X轴运动,然后绕X轴转动——这两者的结果本来就是相同的

这种说法是对的
为何把X轴变成Z轴,两者结果就不同了呢?

该用户从未签到

发表于 2011-3-27 11:45:45 | 显示全部楼层
学习ing
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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