zoukankan      html  css  js  c++  java
  • OSG 自定义数据类型 关键帧动画

    OSG 自定义数据类型 关键帧动画

    转自:http://blog.csdn.net/zhuyingqingfen/article/details/12651017

    /*
    1.创建一个AnimManager一般继承于osg::NodeCallback
    2.在AnimManager中创建一个采样器sampler(例如Vec3LinearSampler,有各种sammpler)
    3. sammpler 配置了各种Interpolator(插值器,如Vec3LinearInterpolator)
    4.sampler 中有KeyframeContainer(关键帧容器,如Vec3KeyframeContainer)
    5.向keyframeContainer中插入对应的关键帧(如Vec3Keyframe 关键帧中包含时间戳和对应的数据类型(如Vec3));
    6.取值 sampler->getValueAt(time t,p1) t 为时间,p1为对应的数据类型如Vec3,当时间超出sampler的结束时间,或取值永远是最后一帧。
    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 MyNode
    {
    public:
    	MyNode(std::string f,float x,float y,float z) 
    	{
    		id = f;
    		_v = osg::Vec3(x,y,z);
    	}
    	MyNode(){ id = "";}
    	MyNode( const MyNode&no)
    	{
    		id = no.id;
    		_v = no._v;
     
    	}
    	MyNode & operator = (const MyNode&no)
    	{
    		id = no.id;
    		_v = no._v;
    	 
    		return *this;
    	}
    	const  MyNode    operator * (float  v) const //不能返回引用,因为no是临时对象
    	{
    		MyNode no;
    		no.id = id;
    		no._v = _v*v;
    		return  no;
    	}
    	inline float operator * (const MyNode  rhs) const
    	{
    		 return  _v*rhs._v;
    	}
    
    	inline MyNode operator + (const MyNode & rhs) const//不能返回引用,因为no是临时对象
    	{
    		 MyNode no;
    		 no.id = id;
    		 no._v = _v+rhs._v;
    		return no;
    	}
    	std::string id;
    	osg::Vec3 _v;
    };
    typedef osgAnimation::TemplateKeyframe<MyNode> MyNodeKeyframe;
    typedef osgAnimation::TemplateKeyframeContainer<MyNode> MyNodeKeyframeContainer;
    typedef osgAnimation::TemplateLinearInterpolator<MyNode, MyNode> MyNodeLinearInterpolator;
    typedef osgAnimation::TemplateSampler<MyNodeLinearInterpolator> MyNodeLinearSampler;
    
    
    class AnimManager : public osg::NodeCallback
    {
    public:
    
    	AnimManager() 
    	{
    		_sampler = new MyNodeLinearSampler;
    		_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();
    					}
    
    					MyNode no;
    
    					_sampler->getValueAt(t, no );
    					result = no._v;
    
    					std::cout<<no.id<<"  "<<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<MyNodeLinearSampler> _sampler;
    	osg::Timer_t _startTime;
    	osg::Timer_t _currentTime;
    	bool _playing;
    	unsigned int _lastUpdate;
    };
    osg::MatrixTransform* setupAnimtkNode(osg::Geode* staticGeode) 
    {
    	osg::MatrixTransform* node = new osg::MatrixTransform();
    
    	AnimManager* callback = new AnimManager();
    	MyNodeKeyframeContainer* keys = callback->_sampler->getOrCreateKeyframeContainer();
    
    	keys->push_back( MyNodeKeyframe(0.0,MyNode("A",1,0,0)));
    	keys->push_back( MyNodeKeyframe(1.0,MyNode("B",5,0,9)));
    	keys->push_back( MyNodeKeyframe(2.0,MyNode("C",1,8,0)));
    	keys->push_back( MyNodeKeyframe(3.0,MyNode("D",1,8,-5)));
    
    	callback->start();
    	node->setUpdateCallback(callback);
    
    	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);
    
    	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();
    	osg::Geode* geode = new osg::Geode();
    
    	root->setInitialBound(osg::BoundingSphere(osg::Vec3(10,0,20), 50));
    	root->addChild(setupAnimtkNode(geode));
    	root->addChild(geode);
    
    	viewer.setSceneData(root);
    	return viewer.run();
    }
    

      

  • 相关阅读:
    SEO网站优化之url友好设计
    mootools版本的lightbox实现(转载)
    利用ASP.NET2.0向导控件一步步建立与用户的交互基本概念
    ATLAS,一个越来越热的技术
    数据源控件与数据绑定控件的进一步简单讨论(1)
    ASP.NET2.0技术详解与应用实例源代码下载
    ASP.NET 2.0 Club Web Site Starter Kit 补丁
    ASP.NET 图片HTML元素的重载
    一个值得收藏的CSS站点网站
    ASP.NET2.0里的配置接口API
  • 原文地址:https://www.cnblogs.com/flylong0204/p/4560691.html
Copyright © 2011-2022 走看看