/* 1.创建一个AnimManager 一般继承于osg::NodeCallback 2.在AnimManager中创建一个采样器sampler(例如Vec3LinearSampler,OSG提供了各种sammpler) 3.sammpler 配置了各种Interpolator(插值器,如Vec3LinearInterpolator) 4.sampler 中有KeyframeContainer(关键帧容器,如Vec3KeyframeContainer) 5.向keyframeContainer中插入对应的关键帧(如Vec3Keyframe 关键帧中包含时间戳和对应的数据类型(如Vec3)); 6.取值 sampler->getValueAt(time t,p1) t 为时间,p1为对应的数据类型如Vec3,当传进的时间超出sampler的结束时间,则取值p1永远是最后一帧数据。 7.取出的p1 用到你想用的地方。 */ #include <iostream> #include <osg/io_utils> #include <osg/Geometry> #include <osg/Shape> #include <osg/ShapeDrawable> #include <osg/Material> #include <osg/MatrixTransform> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osgGA/TrackballManipulator> #include <osgAnimation/Sampler> class AnimManager : public osg::NodeCallback { public: AnimManager() { _sampler = new osgAnimation::Vec3LinearSampler; _playing = false; _lastUpdate = 0; } virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { if(nv->getVisitorType() == osg::NodeVisitor::UPDATE_VISITOR && nv->getFrameStamp() && nv->getFrameStamp()->getFrameNumber() != _lastUpdate) { _lastUpdate = nv->getFrameStamp()->getFrameNumber(); _currentTime = osg::Timer::instance()->tick(); if (_playing && _sampler.get() && _sampler->getKeyframeContainer()) { osg::MatrixTransform* transform = dynamic_cast<osg::MatrixTransform*>(node); if (transform) { osg::Vec3 result; float t = osg::Timer::instance()->delta_s(_startTime, _currentTime); //float duration = _sampler->getEndTime() - _sampler->getStartTime(); //t = fmod(t, duration);//循环 if(t> _sampler->getEndTime()) { stop(); } _sampler->getValueAt(t, result); std::cout<<"result "<<result.x()<<" "<<result.y()<<" "<<result.z()<<std::endl; transform->setMatrix(osg::Matrix::translate(result)); } } } traverse(node,nv); } void start() { _startTime = osg::Timer::instance()->tick(); _currentTime = _startTime; _playing = true;} void stop() { _currentTime = _startTime; _playing = false;} osg::ref_ptr<osgAnimation::Vec3LinearSampler> _sampler; osg::Timer_t _startTime; osg::Timer_t _currentTime; bool _playing; unsigned int _lastUpdate; }; osg::MatrixTransform* createAnimtkNode() { osg::MatrixTransform* node = new osg::MatrixTransform(); osg::Geode* geode = new osg::Geode(); geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), 2))); node->addChild(geode); AnimManager* callback = new AnimManager(); osgAnimation::Vec3KeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer(); keys->push_back( osgAnimation::Vec3Keyframe(0.0,osg::Vec3(1,0,0))); keys->push_back( osgAnimation::Vec3Keyframe(1.0,osg::Vec3(5,0,9))); keys->push_back( osgAnimation::Vec3Keyframe(2.0,osg::Vec3(1,8,0))); keys->push_back( osgAnimation::Vec3Keyframe(6.0,osg::Vec3(1,8,-5))); callback->start(); node->setUpdateCallback(callback); return node; } int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc, argv); osgViewer::Viewer viewer(arguments); osgGA::TrackballManipulator* tbm = new osgGA::TrackballManipulator(); viewer.setCameraManipulator(tbm); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); osg::Group* root = new osg::Group(); root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,20), 50)); root->addChild(createAnimtkNode()); viewer.setSceneData(root); return viewer.run(); }