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();}