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

  

时间: 2024-10-09 05:20:11

OSG 自定义数据类型 关键帧动画的相关文章

Silverlight动画的基本知识、关键帧动画

基础知识 (一)动画:是快速播放一系列图像(其中每个图像与下一个图像略微不同)给人造成的一种幻觉 (二)动画类型:两类    (1)From/To/By动画:在起始值和结束值之间进行动画处理.      (2)关键帧动画:在使用关键帧对象指定的一系列值之间播放动画 (三) 动画是时间线:所有动画均继承自 Timeline 对象,因此所有动画都是专用类型的时间线.有以下重要属性: (1)TargetName:指定要进行动画处理的对象        (2)TargetProperty:指定要进行动画

iOS 自定义转场动画篇

前言: 自定义转场动画其实并不难, 关键在于能够明白思路, 也就是操作步骤. 本篇博客主要以present转场动画为例, 进行分析, 操作, 如有错误欢迎简信与我交流. 不进行修改的话, presentViewController:animated:completion:相信这个方法很多人都是用过, 称作模态推出界面, 默认都是从屏幕下方推出新的控制器. 自定义的目的就是为了修改固定的推出方式, 同时加上你想要的动画. 一个关键的概念: UIViewControllerAnimatedTrans

iOS:核心动画之关键帧动画CAKeyframeAnimation

CAKeyframeAnimation——关键帧动画 关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是: –CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值 – 属性说明: –values:上述的NSArray对象.里面的元素称为“关键帧”(keyframe).动画对象会在指定的时间(duration)内,依次显

iOS block-base 动画简单用法+关键帧动画设置线性变化速度的问题

本文转载至 http://www.tuicool.com/articles/aANBF3m 时间 2014-12-07 20:13:37  segmentfault-博客原文  http://segmentfault.com/blog/alan/1190000002411296 iOS的各种动画相漂亮,相信这是吸引很多人买iPhone的原因之一.不仅如此,这还是吸引我做iOS开发的一大原因,因为在iOS上给界面实现一些像样的动画实在是太轻松了! 这里就介绍一下iOS的block-based an

缓动函数与关键帧动画

缓动函数与关键帧动画 缓动函数指定动画效果在执行时的速度,使其看起来更加真实. 现实物体照着一定节奏移动,并不是一开始就移动很快的.当我们打开抽屉时,首先会让它加速,然后慢下来.当某个东西往下掉时,首先是越掉越快,撞到地上后回弹,最终才又碰触地板. http://easings.net/zh-cn 缓动函数能让动画效果看起来更加真实:). iOS开发中,能用到缓动函数的地方就属于关键帧动画了,以下是我用关键帧动画做出来的模拟真实时钟效果的动画,效果相当逼真哦,只是这个gif图片的效果不好而已.

关键帧动画:@keyframes

关键帧动画:@keyframes: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>关键帧动画</title> 6 <style type="text/css"> 7 .div1{ 8 width: 200px; 9 height: 200px; 10 background: yellow;

Oracle自定义数据类型 1

原文 oracle 自定义类型 type / create type 一 Oracle中的类型 类型有很多种,主要可以分为以下几类: 1.字符串类型.如:char.nchar.varchar2.nvarchar2.2.数值类型.如:int.number(p,s).integer.smallint.3.日期类型.如:date.interval.timestamp.4.PL/SQL类型.如:pls_integer.binary_integer.binary_double(10g).binary_fl

结合手机上网流量业务来说明Hadoop中的自定义数据类型(序列化、反序列化机制)

大家都知道,Hadoop中为Key的数据类型必须实现WritableComparable接口,而Value的数据类型只需要实现Writable接口即可:能做Key的一定可以做Value,能做Value的未必能做Key.但是具体应该怎么应用呢?--本篇文章将结合手机上网流量业务进行分析. 先介绍一下业务场景:统计每个用户的上行流量和,下行流量和,以及总流量和. 本次描述所用数据: 日志格式描述: 日志flowdata.txt中的具体数据: 接下来贴出详细代码,代码中含有详细注释,从代码中可以看出,

指纹解锁以及自定义转场动画

这两天工作不忙,就去研究了下指纹解锁以及转场动画,其实这里面的单单一个动画就可以说半天了,但是今天不去说动画.这个以后有时间在讲讲.. 指纹解锁,很简单,官方文档上说的很清楚,其实我们要做的几乎没有.. 1.导入 #import <LocalAuthentication/LocalAuthentication.h> 这个框架 2.导入下面那段代码,指纹解锁就完成了, so easy!!!!然后再实现自己大逻辑就可以了.. LAContext *myContext = [[LAContext a