致谢
感谢网友提出这个问题。大家有问题也可以在评论区提出,有问必有答。如果涉及商业需求,需要较完整/详尽的工程,可以联系作者133-2459-8743。
问题描述
网友提出要做一个基于osgearth的导弹按轨迹飞行的程序,并放置一些地面站。我准备基于最新的oe版本3.1,分几个步骤把这个功能给做出来。节号命名为18.1, 18.2以示连贯。oe当前最新版本是3.1,说老实话不是很稳定。其提供的效果图如下:
image.png
本节资源
本文集包括本节所有资源包括模型代码都在此下载,按节的序号有文件或文件夹:
注意:务必使用浏览器打开:
链接:https://pan.baidu.com/s/13gwJLwo_LbRnN3Bl2NXXXw
提取码:xrf5
本节功能
本节功能特别简单,就是让操作器跟踪我们上一节做的移动的导弹。这个功能在以前的osgEarth版本中,只需要setTetherNode就可以,但是OE3.1对这个功能进行了优化,让其可设置的东西更多,灵活性更大,但是可能是因为设计的原因,让其用起来有些注意事项。
具体实现
1.OE3.1将要跟踪的实体放在了Viewpoint当中,使用setViewpoint即可。比如我们要跟踪节点tet,其代码如下:
osgEarth::Util::EarthManipulator* _emr = new osgEarth::Util::EarthManipulator;
osgEarth::Viewpoint vp = _emr->getViewpoint();
vp.setNode(tet);
vp.range()->set(250000.0, osgEarth::Units::METERS);
vp.pitch()->set(-45.0, osgEarth::Units::DEGREES);
_emr->setViewpoint(vp, 1.0);
注意事项:,这个功能的难用就在于其注意事项,有两点:
1. _emr->setViewpoint(vp, 1.0);的设置必须要在viewer.setSceneData之后,在之前设置因为其没有初始化,不起作用。也就是在setSceneData中会调用操作器的初始化。
2.这个就更坑了,其所绑定的结点的父结点必须只有一个,我看了看,其计算localtoworld会向上寻找该绑定结点的nodepath,默认是使用nodepath[0],假如你有多个父结点,他就不知道该往哪条路线上了,默认从0就有可能上错。因此我们一般是将要绑定的结点上面硬加一个group,来保证父亲的唯一性:
osg::Group* attachPoint = new osg::Group;
attachPoint->addChild(tet);
mtAp->addChild(attachPoint);
注意这个attachPoint 啥用也没有,就是专门加上去为了操作器的。其它参数类似:
vp.range()->set(250000.0, osgEarth::Units::METERS);
vp.pitch()->set(-45.0, osgEarth::Units::DEGREES);
自己看就知道是什么作用了。
网友评论