查看: 2431|回复: 19

路径漫游的问题!每次启动漫游,初始位置都不一样!路径是max中导出来的

[复制链接]

该用户从未签到

发表于 2012-11-19 13:36:39 | 显示全部楼层 |阅读模式
如题:
我用max做了一个漫游路径,导成了.path文件。通过自己写的界面的按钮可以随时启动AnimationPathManipulator来漫游整个场景,也可以随时切换操纵器到主相机的操纵器视角。但是感觉AnimationPathManipulator有记忆功能一样,每次从主相机的操纵器切换到场景漫游的AnimationPathManipulator时,漫游的起始位置总是接着上一次漫游停止时的位置。这个是为什么呢?能不能每次启动漫游时,都是从这个漫游路径的起始位置开始然后到结束呢?
部分代码:
//初始化漫游
bool FlybyEventHandler::intialFlybypath(osg::ref_ptr<osg::AnimationPath> _pCourseAnimationPath)
{
       
        m_pCoursePath = _pCourseAnimationPath;
        m_pAniPathManipulator = new osgGA::AnimationPathManipulator(m_pCoursePath);
        m_dPathOffsetTime = 0.0;
        m_dPathLastTime = m_pCoursePath->getPeriod();
        return true;

}
//界面按钮调用这个函数启动漫游器
bool FlybyEventHandler::startFlyby()
{
        m_PathFistframe_tick=osg::Timer::instance()->tick();

        m_pViewer->setCameraManipulator(m_pAniPathManipulator.get());

        return true;
}
//这个函数可以切换到主相机的操纵器,并且停止漫游
bool FlybyEventHandler::stopFlyby()
{
           m_pViewer->setCameraManipulator(m_pMainCamera);
        m_pMainCamera->m_pHostViewer =m_pViewer;

        return true;
}
//FlybyEventHandler是GUI事件回调,这个函数里边可以自动停止漫游功能
bool FlybyEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
{

        m_PathCurrentframe_tick=osg::Timer::instance()->tick();
        m_dPathTotalTime=osg::Timer::instance()->delta_s(m_PathFistframe_tick,m_PathCurrentframe_tick);
        //计算启动漫游的时间跟当前时间,并与漫游路径的周期比较,以自动结束漫游功能
        if (m_dPathTotalTime>=m_pCoursePath->getPeriod())
                //  if (m_pViewer->getCameraManipulator()!=m_pMainCamera)
        {
                m_pViewer->setCameraManipulator(m_pMainCamera);

                m_pMainCamera->m_pHostViewer =m_pViewer;

                FlybyEventHandler::bFlyby=false;

        }

        return true;
}

可是,目前奇怪的是,每次执行startFlyby()时,漫游的位置都不一样。都不是漫游路径中的起始的位置。如果点击界面的stop按钮执行stopflyby()函数,下次启动startFlyby时,漫游路径的起始位置则是上次点击stopflyby()函数时漫游相机的位置,感觉操纵器自己有记忆功能。这个是什么原因呢?感谢大家不吝指教,论坛之前有相关帖子,可是最后都不了了之了。

该用户从未签到

发表于 2012-11-19 16:22:31 | 显示全部楼层
可以直接执行home()回到漫游器原点

该用户从未签到

 楼主| 发表于 2012-11-19 19:32:14 | 显示全部楼层
array 发表于 2012-11-19 16:22
可以直接执行home()回到漫游器原点

array大哥,那个home函数我试过,我传入了各种时间,基本上没有什么反应,还是一样的,那个home函数应该是让timeoffset变成0才对,可是设置了也不行。

该用户从未签到

发表于 2012-11-19 20:04:06 | 显示全部楼层
buptronin 发表于 2012-11-19 19:32
array大哥,那个home函数我试过,我传入了各种时间,基本上没有什么反应,还是一样的,那个home函数应该是 ...

好像是要重载下AnimationPathManipulator类才行,个人觉得这个类写的很不友好,连外部的控制接口都没有。

该用户从未签到

 楼主| 发表于 2012-11-19 20:25:25 | 显示全部楼层
smash 发表于 2012-11-19 20:04
好像是要重载下AnimationPathManipulator类才行,个人觉得这个类写的很不友好,连外部的控制接口都没有。

重载的话,handle函数里边能控制么?我今天试了下,好像里边很多的东西都用不了。其实我主要是想执行AnimationPathManipulator中的handle函数里边的空格响应的代码,但是,很多的成员变量都是私有的,所以没法像源码那样控制。还得研究下才可以。

该用户从未签到

发表于 2012-11-20 14:38:24 | 显示全部楼层
buptronin 发表于 2012-11-19 20:25
重载的话,handle函数里边能控制么?我今天试了下,好像里边很多的东西都用不了。其实我主要是想执行Anim ...

都是protect变量,重载一下不就都可以用了啊。

该用户从未签到

发表于 2012-12-3 01:49:13 | 显示全部楼层
buptronin 发表于 2012-11-19 20:25
重载的话,handle函数里边能控制么?我今天试了下,好像里边很多的东西都用不了。其实我主要是想执行Anim ...

问题已解决,你把
  1. _animationPathManipulator->setTimeOffset(timeOffset);
复制代码
插入到设置漫游器后就行了

该用户从未签到

 楼主| 发表于 2012-12-3 09:08:08 | 显示全部楼层
sy2178668 发表于 2012-12-3 01:49
问题已解决,你把插入到设置漫游器后就行了

嗯,谢谢!我用另外一种方式解决了!跟你的差不太多!刚开始我也是把home函数放在了设置操纵器前边,然后啥反应都没有!后来换了下位置就差不多了,只是不完美!最后又修改了下时间值,就可以了!个人感觉源码里边也处理的不是太好,呵呵,个人感觉!对了,你的那个timeoffset是给的多少啊????

该用户从未签到

发表于 2012-12-3 13:43:17 | 显示全部楼层
buptronin 发表于 2012-12-3 09:08
嗯,谢谢!我用另外一种方式解决了!跟你的差不太多!刚开始我也是把home函数放在了设置操纵器前边,然后 ...

看了源码,其实都是对timeoffset进行设置。timeoffset值是AnimationPath开始的时间减去现在的时间

该用户从未签到

发表于 2013-2-26 15:35:17 | 显示全部楼层
请问如何能够从 max 中直接导出相机的路径,得到 .path 文件啊?

该用户从未签到

 楼主| 发表于 2013-2-26 17:26:04 | 显示全部楼层
frank_y 发表于 2013-2-26 15:35
请问如何能够从 max 中直接导出相机的路径,得到 .path 文件啊?

不好意思,这个我也不知道,我不懂建模!一般搞建模的美工都知道!应该是很简单的一个操作吧!

该用户从未签到

发表于 2013-3-4 11:12:53 | 显示全部楼层
你并没有停止自动路径的播放,只是暂停了;
     你地START函数不对, 并没有重新设定还原路径, 只是继续播放
试着添加:
   m_pAniPathManipulator = new osgGA::AnimationPathManipulator(m_pCoursePath);

         

该用户从未签到

 楼主| 发表于 2013-3-4 19:44:07 | 显示全部楼层
VR_user_happy 发表于 2013-3-4 11:12
你并没有停止自动路径的播放,只是暂停了;
     你地START函数不对, 并没有重新设定还原路径, 只是继续 ...

这种方法试过,但是从编程的角度来说不是很科学!相当于重新实例化一个操纵器!我后来自己写了一个操纵器就OK了!

该用户从未签到

发表于 2013-5-5 00:20:22 | 显示全部楼层
sy2178668 发表于 2012-12-3 13:43
看了源码,其实都是对timeoffset进行设置。timeoffset值是AnimationPath开始的时间减去现在的时间

请问,现在的时间怎么获得呢?

该用户从未签到

发表于 2013-5-5 12:22:53 | 显示全部楼层
wanghan19911117 发表于 2013-5-5 00:20
请问,现在的时间怎么获得呢?

系统有个函数,好像是getTick什么的,具体的我忘了,你可以查下

该用户从未签到

发表于 2013-5-6 17:29:12 | 显示全部楼层
Timer::tick()得到的时间不一定适用,建议还是从viewer或者nodevisitor中得到FrameStamp然后取它的SimulationTime,或者如果您是在EventHandler中,那么可以直接取得ea.getTime()

该用户从未签到

发表于 2013-5-23 12:54:48 | 显示全部楼层
array 发表于 2013-5-6 17:29
Timer::tick()得到的时间不一定适用,建议还是从viewer或者nodevisitor中得到FrameStamp然后取它的Simulati ...

好的,学习了

该用户从未签到

发表于 2013-5-23 13:06:18 | 显示全部楼层
1.
新建一个动画路径控制器,并设定动画路径:
animationPathManipulator->setAnimationPath(pCurrentPath.get());
pViewer->setCameraManipulator(m_curntManipulator);
2.重新调用路径时,只需要初始化化动画路径控制器:
animationPathManipulator->init(ea,aa);
如果需要设有偏移,还可以把偏移归零
animationPathManipulator->setTimeOffset(0.0);

该用户从未签到

发表于 2013-6-22 11:40:20 | 显示全部楼层

1.
新建一个动画路径控制器,并设定动画路径:
animationPathManipulator->setAnimationPath(pCurrentPath.get());
pViewer->setCameraManipulator(m_curntManipulator);
2.重新调用路径时,只需要初始化化动画路径控制器:
animationPathManipulator->init(ea,aa);
如果需要设有偏移,还可以把偏移归零
animationPathManipulator->setTimeOffset(0.0);

-------------------------------------------------------------------------------------
请问:animationPathManipulator->init(ea,aa)——这里的ea、aa是如何得到的?

该用户从未签到

发表于 2013-6-22 13:21:41 | 显示全部楼层
::handle(const osgGA::GUIEventAdapter&ea,osgGA::GUIActionAdapter& aa)
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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