osg 路径 动画 效果

来源:互联网 发布:js小游戏 编辑:程序博客网 时间:2024/06/04 13:40
#include <osg/Group>#include <osg/ShapeDrawable>#include <osgViewer/ViewerEventHandlers>#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osgUtil/LineSegmentIntersector>#include <osgGA/GUIEventHandler>#include <osgGA/AnimationPathManipulator>#include <iostream>using namespace std;class PickEventHandle :public osgGA::GUIEventHandler{public:  PickEventHandle(){    _points=new osg::Vec3Array;  }  virtual ~PickEventHandle(){  }  osg::Geode*createBox(osg::Vec3 center){    osg::ref_ptr<osg::Geode>geode=new osg::Geode;    geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);    osg::ref_ptr<osg::ShapeDrawable>sd=new osg::ShapeDrawable(new osg::Box(center,5,5,5));    sd->setColor(osg::Vec4(1,0,0,1));    geode->addDrawable(sd);    return geode.release();  }  float getRunTime(osg::Vec3 res,osg::Vec3 des){    float xx=(res.x()-des.x())*(res.x()-des.x());    float yy=(res.y()-des.y())*(res.y()-des.y());    float zz=(res.z()-des.z())*(res.z()-des.z());    float distant=sqrt(xx+yy+zz);    return distant*0.1;  }  osg::AnimationPath*createPath(){    osg::ref_ptr<osg::AnimationPath>anim=new osg::AnimationPath;    anim->setLoopMode(osg::AnimationPath::LOOP);    float time=0.0;    float angle=0.0;    float roll=1.57;//osg::inDegrees(90);    if(_points.valid()){      osg::Vec3Array::iterator iter=_points->begin();      for(;;){        osg::Vec3 pos(*iter);        iter++;        if(iter!=_points->end()) {          if(iter->x() > pos.x())          {            angle=1.57-atan((iter->y()-pos.y())/(iter->x()-pos.x()));            if(angle<0)              angle+=1.57;          }          else {            angle=-(1.57+atan((iter->y()-pos.y())/(iter->x()-pos.x())));            if(angle>0){              angle=-(1.57-angle);            }          }          osg::Quat rotate (osg::Quat(roll,osg::Vec3(1.0,0,0))*osg::Quat(-angle,osg::Vec3(0,0,1)));          anim->insert(time,osg::AnimationPath::ControlPoint(pos,rotate));          time+=getRunTime(pos, *iter);        }        else {          break;        }      }          }    ofstream out("/root/a.path");//把信息保存    anim->write(out);    out.close();    return anim.release();  }   bool handle(const osgGA::GUIEventAdapter &ea   ,osgGA::GUIActionAdapter &aa)    {      osgViewer::Viewer *viewer=dynamic_cast<osgViewer::Viewer*>(&aa);      if(!viewer)        return false;      switch (ea.getEventType()){        case osgGA::GUIEventAdapter::PUSH://寻找关键点        {          osgUtil::LineSegmentIntersector::Intersections inters;          if(viewer->computeIntersections(ea.getX(),ea.getY(),inters)){            osgUtil::LineSegmentIntersector::Intersections::iterator iter=inters.begin();            osg::Vec3d pos=iter->getWorldIntersectPoint();            cout<<pos.x()<<" "<<pos.y()<<" "<<pos.z()<<endl;            _points->push_back(osg::Vec3(pos.x(),pos.y(),3));            viewer->getSceneData()->asGroup()->addChild(createBox(pos));          }        }        case osgGA::GUIEventAdapter::KEYDOWN:{          if(ea.getKey()=='f' || ea.getKey()=='F'){//启动漫游(可以在这保存下操纵器,漫游完毕可以返回原来状态            if(viewer)            {              osg::ref_ptr<osgGA::AnimationPathManipulator>apm=new osgGA::AnimationPathManipulator;              apm->setAnimationPath(createPath());              viewer->setCameraManipulator(apm);            }          }          if(ea.getKey()=='g' || ea.getKey()=='G'){//用已经保存的文件里的信息            osg::ref_ptr<osgGA::AnimationPathManipulator>apm=new osgGA::AnimationPathManipulator("/root/a.path");            viewer->setCameraManipulator(apm);           }        }          break;      }        return false;  }private:  osg::ref_ptr<osg::Vec3Array> _points;};int main(int argc, char *argv[]){  osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer;  viewer->setSceneData(osgDB::readNodeFile("ceep.ive"));  viewer->addEventHandler(new PickEventHandle());  viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);  viewer->run();}


原创粉丝点击