查看: 1512|回复: 9

再问有关节点回调中的异常

[复制链接]

该用户从未签到

发表于 2012-9-20 12:55:41 | 显示全部楼层 |阅读模式
本帖最后由 mxl12315 于 2012-10-5 23:25 编辑

   之前提问过有关节点回调的问题,后来对自己的代码给了下,但还是获取的节点实时位置为0,以下是代码解释和代码,希望各位高手调试后指点我一下~谢谢
   代码思路:包括节点回调和动画回调两部分,动画回调是将导入的动画文件(.path)加载到场景中,spaceship这个模型按轨迹运动;节点回调是获取模型运动时的实时位置。
   问题:模型运动的实时位置总是0,我尝试过全局变量等方法,但还是这样,希望大家帮忙看一下

问题截图
111111.bmp

该用户从未签到

发表于 2012-9-24 17:10:27 | 显示全部楼层
  1. m=osg::computeWorldToLocal(nv->getNodePath());
复制代码
您不认为自己这一句写反了么?

该用户从未签到

 楼主| 发表于 2012-9-25 09:12:12 | 显示全部楼层
array 发表于 2012-9-24 17:10
您不认为自己这一句写反了么?

大神来了!哈哈,您之前提到的
                           “ osg::ref_ptr <osg::MatrixTransform> matrix=new osg::MatrixTransform;
                                              osg::Matrix m=osg::computeWorldToLocal(nv->getNodePath());”
                      当中MatrixTransform与小车节点无关联,我仔细改了下,发现还是获取不了小车实时的位置,还都是0.之所以用MatrixTransform,因为之前一些高手建议用它当中的getTrans(),比如getTrans().x()可以得到位移中x变化的值。。您看我这代码如何修改才能将节点遍历不是0呢?我觉得遍历的对象混乱,小车还是动画得不明确。。而且,我确实想不出还能有什么方法可以得到小车运动中的实时位移。。希望您指点下~拜托了

该用户从未签到

发表于 2012-9-27 09:29:55 | 显示全部楼层
computeWorldToLocal得到的是从世界坐标变换到局部坐标的矩阵,那么此时对于一个世界坐标P,要得到它在局部坐标系的位置就是Pl = P * m。我不认为您这里的逻辑是正确的。
此外您每帧新建一个节点,这一步有什么意义?您并没有去尝试获取原来的小车节点的位置,那么当然不会得到值
如果能得到正确的空间变换矩阵,那么之后getTrans()当然是可以的,不过您现在的逻辑恐怕还有问题呢

该用户从未签到

 楼主| 发表于 2012-9-27 09:48:34 | 显示全部楼层
array 发表于 2012-9-27 09:29
computeWorldToLocal得到的是从世界坐标变换到局部坐标的矩阵,那么此时对于一个世界坐标P,要得到它在局部 ...

这个指点详细透彻~一针见血哈,我去试试哈~太感谢了。。。

该用户从未签到

 楼主| 发表于 2012-9-29 10:44:16 | 显示全部楼层
自顶一个~希望破解!找寻帮手调试代码,但均无效果~

该用户从未签到

发表于 2012-9-29 18:37:12 | 显示全部楼层
本帖最后由 buaahc 于 2012-9-29 19:12 编辑

你不是就是想得到运动小车的位置么 为什么要这么麻烦。。。
怎么还添加了路径动画控制事件。。。
第一我不知道 你为什么要 定义mtcow并且 mtCow->setMatrix(m);这句话有什么用。。。
virtual void operator()(osg::Node* node ,osg::NodeVisitor* nv)
        {
                osg::ref_ptr<osg::MatrixTransform> mtCow = dynamic_cast<osg::MatrixTransform*>(node);

                if (mtCow.valid())
                {
                        m=osg::computeLocalToWorld(nv->getNodePath());

                        mtCow->setMatrix(m);
                }

                traverse( node, nv );
        }

直接

class CarCallback :public osg::NodeCallback
{
public:
        CarCallback()
        {
        }
        virtual void operator()(osg::Node* node ,osg::NodeVisitor* nv)
        {   
                {
                        m=osg::computeLocalToWorld(nv->getNodePath());
                }
                traverse( node, nv );
        }
        osg::Matrixd& getMatrixd()   //自定义一个方法,每次回调获取的m值
        {
                return m;
        }
public:
        osg::Matrixd m;
};
就ok!

然后我不知道osg::ref_ptr<osg::AnimationPathCallback> animationPathCallback = new osg::AnimationPathCallback() ;你要做什么,你所写的事件处理函数
          virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
          {

                  //创建动画更新回调对象---------------------------------------------------------------------------------------
                  osg::ref_ptr<osg::AnimationPathCallback> animationPathCallback = new osg::AnimationPathCallback() ;//没看懂你定义这个animationPathCallback 做什么
                  osg::ref_ptr< osg::Group> group = dynamic_cast<osg::Group*>(viewer.getSceneData()) ;//这句话你无非想要得到main()中的根节点点罢了,直接传进来不就行了

                  //取得节点的动画属性
                  animationPathCallback = dynamic_cast<osg::AnimationPathCallback*>(group->getChild(0)->getUpdateCallback());//这句话我完全不明白你要干什么。

                  //节点回调!!!
                  s_carcallback =new CarCallback();
                  group->getChild(0)->addUpdateCallback(s_carcallback);  //这句话就是进行节点的不断更新回调得到Matrix
。。。。
}


直接这样
class AnimationEventHandler : public osgGA::GUIEventHandler
{
public:
        AnimationEventHandler(osg::ref_ptr<osg::group>pMoot)://直接将main函数中的根节点传进来
          {
               this-> pGroup = pMoot;                          
               this-> pNode = pGroup->getChild(n);//接收group的第n个节点
               this-> s_carcallback = new CarCallback();//创建回调节点,不断得出世界坐标
               this-> pNode->setUpdateCallback(s_carcallback);//使用第n个节点进行不断地更新回调 ,得到第n个节点的坐标
          }
          //ok了

          void getDistance()     //获取小车回调类中的m值
          {
                  this->m1=s_carcallback->getMatrixd();
                  cout<<m1.getTrans().y()<<endl;
          }

          //事件处理
          virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
          {      
              switch(ea.getEventType())
              {
                 case (osgGA::GUIEventAdapter::FRAME):
                 {
                        getDistance();
                        return false;
                 }
           default :       
               return false;
             }  
        }
private:
osg::ref_ptr<osg::group>pGroup;//接收main()函数中的根节点
osg::ref_ptr<CarCallback >s_carcallback ;
osg::ref_pfr<osg::Node>pNode;
osg::Matrix m1;

}
你试一下  有问题再说~

该用户从未签到

 楼主| 发表于 2012-10-5 16:28:12 | 显示全部楼层
buaahc 发表于 2012-9-29 18:37
你不是就是想得到运动小车的位置么 为什么要这么麻烦。。。
怎么还添加了路径动画控制事件。。。
第一我不 ...

您好,您的讲解很详细~大致我改了下,现在就是在main函数的根结点传入问题上异常,给您的空间留言了哈,希望您看一下~

该用户从未签到

 楼主| 发表于 2012-10-5 23:24:24 | 显示全部楼层
buaahc 发表于 2012-9-29 18:37
你不是就是想得到运动小车的位置么 为什么要这么麻烦。。。
怎么还添加了路径动画控制事件。。。
第一我不 ...

我找到我的问题了,果然如您所说,多了几句没必要的话,让它给我绕进去了~

该用户从未签到

发表于 2012-10-8 08:20:29 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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