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

  

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

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

    基础知识 (一)动画:是快速播放一系列图像(其中每个图像与下一个图像略微不同)给人造成的一种幻觉 (二)动画类型:两类    (1)From/To/By动画:在起始值和结束值之间进行动画处理.     ...

  2. Core Animation中的关键帧动画

    键帧动画就是在动画控制过程中开发者指定主要的动画状态,至于各个状态间动画如何进行则由系统自动运算补充(每两个关键帧之间系统形成的动画称为“补间动画”),这种动画的好处就是开发者不用逐个控制每个动画帧, ...

  3. ios基础动画、关键帧动画、动画组、转场动画等

    概览 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌.在这里你可以看到iOS中如何使用图层精简非交互式绘图,如何通过核心动画创建基础动画.关键帧动画 ...

  4. 【WPF学习】第五十四章 关键帧动画

    到目前为止,看到的所有动画都使用线性插值从起点到终点.但如果需要创建具有多个分段的动画和不规则移动的动画.例如,可能希望创建一个动画,快速地将一个元素滑入到视图中,然后慢慢地将它移到正确位置.可通过创 ...

  5. 关键帧动画:@keyframes

    关键帧动画:@keyframes: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...

  6. 通过SQL Server自定义数据类型实现导入数据

    写在前面 在看同事写的代码时看到了SQL Server中可以自定义数据类型,而且定义的是DataTable类型的数据类型. 后我想起了以前我们导入数据时要么是循环insert写入,要么是SqlBulk ...

  7. 背水一战 Windows 10 (14) - 动画: 线性动画, 关键帧动画

    [源码下载] 背水一战 Windows 10 (14) - 动画: 线性动画, 关键帧动画 作者:webabcd 介绍背水一战 Windows 10 之 动画 线性动画 - ColorAnimatio ...

  8. iOS开发UI篇—核心动画(关键帧动画)

    转自:http://www.cnblogs.com/wendingding/p/3801330.html iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimatio ...

  9. Swift - 使用CAKeyframeAnimation实现关键帧动画

    1,CAKeyframeAnimation介绍 CAKeyframeAnimation可以实现关键帧动画,这个类可以实现某一属性按照一串的数值进行动画,就像是一帧一帧的制作出来一样.   2,使用样例 ...

随机推荐

  1. Solr入门之(2)快速启动:第一个例子

    Solr作为一个web应用来启动,因此需要JDK支持,需要WEB容器,本文环境如下: JDK6.0或以上(环境变量设置等不再赘述) Tomcat-6.0.35或以上(自行下载) apache-solr ...

  2. Oracle优化的几个简单步骤

    数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据库配置等等.还有的人认为要抓出执行最慢的语句来进行优化.但实际情况 ...

  3. 最长公共子序列(LCS)和最长递增子序列(LIS)的求解

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

  4. [QCon] Scrum阅读随想

    最近从群里面下载到几篇文章,看到QCon出来的相关文章,觉得都写的很不错,都是一些个大公司的非常好的方法   QCon:是为团队领导者.架构师.项目经理和高级软件开发人员量身打造的企业软件开发大会,其 ...

  5. Http 请求处理流程

    引言 我查阅过不少Asp.Net的书籍,发现大多数作者都是站在一个比较高的层次上讲解Asp.Net.他们耐心.细致地告诉你如何一步步拖放控件.设置控件属性.编写CodeBehind代码,以实现某个特定 ...

  6. Fragment 操作原理

      fragment 本质 fragment 本质上是 view 的容器和控制器,fragment 是 activity 的碎片. activity 是什么呢?activity 是四大组件之一,因为 ...

  7. Linux学习笔记(20) Linux系统管理

    1.进程管理 进程是正在执行的一个程序或命令,每一个进程都是一个运行的实体,都有自己的地址空间,并占用一定的系统资源. 进程管理的作用有判断服务器健康状态.查看系统中所有进程及杀死进程.一般都可以采用 ...

  8. C# Stream 和 byte[] 之间的转换(文件流的应用)

    一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = ; Image img = Image.FromStream( ...

  9. 利用myeclipse配置数据库连接池

    作为一个习惯使用myeclipse的人来说,即使是数据库连接池也肯定是用ide配置了. 下面说一下用数据库连接池的配置. 1 创建工程.不多说了. 2 添加数据库连接程序驱动包.直接放到lib目录下即 ...

  10. 廖雪峰js教程笔记5 Arrow Function(箭头函数)

    为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 箭头函数 阅读: ...