|
实现这样一个功能:飞机在盘旋,按下键盘左键,飞机释放小飞机,给小飞机一个路径,垂直向下,当小飞机碰到地面后,消失。
问题是:1。碰撞检测从开始释放小飞机,iv.hits()的返回值就为true,就是一直都是碰撞状态,明明离地面200多,不知道什么原因。
2. 如何得到碰撞到地面的位置?
代码如下:
- osg::ref_ptr<osg::AnimationPath> createAnimationPath(osg::Vec3& center,float radius,float looptime)
- {
- //创建一个path对象
- osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();
- //设置动画模式为循环(LOOP)。LOOP:循环,SWING:单摆,NO_LOOPING:不循环
- animationPath->setLoopMode(osg::AnimationPath::LOOP);
- //关键点数
- int numPoint = 60;
- //每次偏移角度
- float yaw = 0.0f;
- float yaw_delta = 2.0f*osg::PI/((float)(numPoint-1.0f));
- //倾斜角度
- float roll = osg::inDegrees(45.0f);
- //时间偏移
- float time = 0.0f;
- float time_delta = looptime/((float)numPoint);
- for(int i = 0;i<numPoint;i++)
- {
- //关键点位置
- osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));
- //关键点角度
- osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));
- //插入path,把关键点与时间压入形成path
- animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
- yaw += yaw_delta;
- time += time_delta;
- }
- return animationPath.get();
- }
- osg::ref_ptr<osg::AnimationPath> createAnimationPath1(osg::Vec3& pos)
- {
- osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();
- animationPath->setLoopMode(osg::AnimationPath::LOOP);
- int numPoint = 60;
- float yaw = 0.0f;
- float yaw_delta = 2.0f;
- float roll = osg::inDegrees(45.0f);
- float time = 0.0f;
- float time_delta = 0.5f;
- for(int i=0;i<numPoint;i++)
- {
- osg::Vec3 position(pos+osg::Vec3(0.0f,0.0f,-yaw));
- osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0)));
- animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));
- yaw += yaw_delta;
- time += time_delta;
- }
- return animationPath.get();
- }
- class CheckPengEventHandler : public osg::NodeCallback
- {
- public:
- CheckPengEventHandler()
- {
-
- }
- virtual void operator()(osg::Node* node,osg::NodeVisitor* nv)
- {
- osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>(node);
- osgUtil::IntersectVisitor iv;
- osg::ref_ptr<osg::LineSegment> lineZ = new osg::LineSegment(pat->getPosition()+osg::Vec3(0.0f,0.0f,2.0f),pat->getPosition()+osg::Vec3(0.0f,0.0f,-2.0f));
- iv.addLineSegment(lineZ.get());
- if(iv.hits())
- {
- node->setNodeMask(0);
- }
- }
- };
- class UseEventHandler:public osgGA::GUIEventHandler
- {
- public:
- UseEventHandler(osg::ref_ptr<osg::PositionAttitudeTransform> pat,osg::ref_ptr<osg::AnimationPath> animationPath
- ,osg::ref_ptr<osg::PositionAttitudeTransform> pat1)
- :pat(pat),animationPath(animationPath),pat1(pat1)
- {
-
- }
- virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
- {
- osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&aa);
- if(!viewer) return false;
- osg::ref_ptr<osg::Group> group = dynamic_cast<osg::Group*>(viewer->getSceneData());
- switch(ea.getEventType())
- {
- case osgGA::GUIEventAdapter::KEYDOWN:
- {
- if(ea.getKey()==0xFF51)
- {
- pat->setUpdateCallback(new osg::AnimationPathCallback(animationPath.get(),0.0f,1.0f));
- }
- if(ea.getKey() == 0xFF53)
- {
- osg::Vec3 position = pat->getPosition();
- group->addChild(pat1.get());
- group->getChild(0)->asGroup()->removeChild(pat1);
- pat1->setNodeMask(1);
- osg::ref_ptr<osg::AnimationPath> animationPath1 = new osg::AnimationPath();
- animationPath1 = createAnimationPath1(position);
- pat1->addUpdateCallback(new osg::AnimationPathCallback(animationPath1.get(),0.0f,1.0f));
- pat1->addUpdateCallback(new CheckPengEventHandler());
- }
- }
- break;
- default:
- break;
- }
- return false;
- }
- private:
- osg::ref_ptr<osg::PositionAttitudeTransform> pat,pat1;
- osg::ref_ptr<osg::AnimationPath> animationPath;
- };
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
- osg::ref_ptr<osg::Group> root = new osg::Group();
- osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile("cessna.osg");
- osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("lz.osg");
- osg::ref_ptr<osg::Node> glider = osgDB::readNodeFile("glider.osg");
- //得到包围盒,来确定动画旋转中心
- const osg::BoundingSphere& bs = cessna->getBound();
- osg::Vec3 position = bs.center() + osg::Vec3(0.0f,0.0f,200.0f);
- //缩放
- float size = 100.0f/bs.radius()*0.3f;
- //创建路径
- osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath();
- animationPath = createAnimationPath(position,200.0f,30.0f);
- osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
- osg::ref_ptr<osg::MatrixTransform> mt1 = new osg::MatrixTransform();
- osg::ref_ptr<osg::MatrixTransform> mtTerr = new osg::MatrixTransform();
- //OSG确保只有STATIC数据可以进行图形渲染
- mt->setDataVariance(osg::Object::STATIC);
- mt1->setDataVariance(osg::Object::STATIC);
- //进行适当的变换
- mtTerr->setMatrix(osg::Matrix::translate(0.0f,0.0f,0.0f));
- mtTerr->addChild(node.get());
- mt->setMatrix(osg::Matrix::translate(bs.center())*
- osg::Matrix::scale(size,size,size));
- mt->addChild(cessna.get());
- mt1->setMatrix(osg::Matrix::scale(0.2,0.2,0.2)*osg::Matrix::rotate(osg::inDegrees(90.0f),1.0f,0.0f,0.0f));
- mt1->addChild(glider.get());
- osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
- osg::ref_ptr<osg::PositionAttitudeTransform> pat1 = new osg::PositionAttitudeTransform();
- pat->addChild(mt.get());
- pat1->addChild(mt1.get());
- pat1->setNodeMask(0);
- pat->addChild(pat1.get());
- root->addChild(pat.get());
- root->addChild(mtTerr.get());
- osgUtil::Optimizer optimizer;
- optimizer.optimize(root.get());
- viewer->setSceneData(root.get());
- viewer->addEventHandler(new UseEventHandler(pat,animationPath,pat1));
- viewer->realize();
- viewer->run();
- return 0;
- }
复制代码 |
|