AnimationPath路径动画实现详解:

一、关联类图展示

二、实现详解

  • 首先我们通过调用createAnimationPath方法来创建动画路径,即:通过起点、终点以及之间的时间步长来进行插值来保证动画的一个流畅度,然后将这些时间和点保存到一个map容器中(_timeControlPointMap)。

osg::AnimationPath* createAnimationPath(const osg::Vec3& center,float radius,double looptime)
{// set up the animation path osg::AnimationPath* animationPath = new osg::AnimationPath;animationPath->setLoopMode(osg::AnimationPath::LOOP);int numSamples = 40;float yaw = 0.0f;float yaw_delta = 2.0f*osg::PI/((float)numSamples-1.0f);float roll = osg::inDegrees(30.0f);double time=0.0f;double time_delta = looptime/(double)numSamples;for(int i=0;i<numSamples;++i){osg::Vec3 position(center+osg::Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0f));osg::Quat rotation(osg::Quat(roll,osg::Vec3(0.0,1.0,0.0))*osg::Quat(-(yaw+osg::inDegrees(90.0f)),osg::Vec3(0.0,0.0,1.0)));animationPath->insert(time,osg::AnimationPath::ControlPoint(position,rotation));yaw += yaw_delta;time += time_delta;}return animationPath;
}
  • 然后创建一个模型节点,即:要让它跟着我们指定的路径变化的节点。学过opengl或者游戏开发的都清楚,要想让一个点从一个位置变化到另一个位置,最好是通过矩阵来改变它的位置,所以我们需要把这个模型节点添加到矩阵中来动态更新它的位置,这样才能有一个连续的动画效果。

osg::Node* createMovingModel(const osg::Vec3& center, float radius)
{float animationLength = 10.0f;osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength);osg::Group* model = new osg::Group;/// 通过读取模型来创建节点osg::Node* glider = osgDB::readNodeFile("glider.osgt");if (glider){const osg::BoundingSphere& bs = glider->getBound();float size = radius/bs.radius()*0.3f;osg::MatrixTransform* positioned = new osg::MatrixTransform;positioned->setDataVariance(osg::Object::STATIC);positioned->setMatrix(osg::Matrix::translate(-bs.center())*osg::Matrix::scale(size,size,size)*osg::Matrix::rotate(osg::inDegrees(-90.0f),0.0f,0.0f,1.0f));positioned->addChild(glider);osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;    xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));xform->addChild(positioned);model->addChild(xform);}/// 通过读取模型来创建节点osg::Node* cessna = osgDB::readNodeFile("cessna.osgt");if (cessna){const osg::BoundingSphere& bs = cessna->getBound();float size = radius/bs.radius()*0.3f;osg::MatrixTransform* positioned = new osg::MatrixTransform;positioned->setDataVariance(osg::Object::STATIC);positioned->setMatrix(osg::Matrix::translate(-bs.center())*osg::Matrix::scale(size,size,size)*osg::Matrix::rotate(osg::inDegrees(180.0f),0.0f,0.0f,1.0f));positioned->addChild(cessna);osg::MatrixTransform* xform = new osg::MatrixTransform;xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));xform->addChild(positioned);model->addChild(xform);}return model;
}
  • 其次创建矩阵来改变模型节点的位置、旋转角度和缩放比。即:可以创建用于给变位置和旋转角的PositionAttitudeTransform对象,也可以创建MatrixTransform对象来对模型节点做更多的变换操作,最后将这些矩阵都添加到Group中来统一管理。

/// 创建位置属性变换对象,通过设置更新回调来动态改变节点的位置和旋转角osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;    xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));xform->addChild(positioned);model->addChild(xform);/// 创建变换矩阵对象,通过设置更新回调来动态改变节点的位置和旋转角osg::MatrixTransform* xform = new osg::MatrixTransform;xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));xform->addChild(positioned);model->addChild(xform);}
  • 最后创建更新回调(AnimationPathCallback),通过为矩阵设置更新回调来动态更新节点变化,至于更新回调怎么调用这就需要大家看看渲染一帧到底做了什么操作,推介大家看(OSG_王锐《最长的一帧》)。AnimationPathCallback类中有两个方法需要注意:operator()和update(in node:Node&)方法,在updata方法中通过AnimationPathCallbackVisitor访问器来改变节点的矩阵。

    /// 创建位置属性变换对象,通过设置更新回调来动态改变节点的位置和旋转角osg::PositionAttitudeTransform* xform = new osg::PositionAttitudeTransform;  /// 设置路径动画更新回调xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0,1.0));xform->addChild(positioned);model->addChild(xform);/// 创建变换矩阵对象,通过设置更新回调来动态改变节点的位置和旋转角osg::MatrixTransform* xform = new osg::MatrixTransform;/// 设置路径动画更新回调xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));xform->addChild(positioned);model->addChild(xform);

三、效果图展示

AnimationPath路径动画实现详解相关推荐

  1. Unity动画系统详解10:子状态机是什么?

    摘要:除了使用Layer还有没有更好的组织状态的方式呢?感觉一个Layer里面状态多的时候,还是很显得很乱. 洪流学堂,让你快人几步.你好,我是跟着大智学Unity的萌新,我叫小新,这是复(yu)习( ...

  2. 最简单太阳系H5动画canvas详解 零基础可入

    最简单太阳系H5动画canvas详解 零基础可入 最终结果:(实际为动画效果,金星绕轨道转动) 页面准备/html 要使用canvas,需要首先在页面中要绘制的位置放入canvas标签元素,在后期的绘 ...

  3. Android Animator(动画)类 详解

    Android Animator动画类 详解 动画分为3种 ValueAnimator类 ObjectAnimator类 AnimatorSet类 Animator的addListener()方法(监 ...

  4. POPSpring动画参数详解

    POPSpring动画参数详解 效果 源码 https://github.com/YouXianMing/Animations // // POPSpringParameterController.m ...

  5. Android 动画框架详解,第 1 部分

    2019独角兽企业重金招聘Python工程师标准>>> Android 平台提供了一套完整的动画框架,使得开发者可以用它来开发各种动画效果,本文将向读者阐述 Android 的动画框 ...

  6. Unity动画系统详解9:Target Matching是什么?

    摘要:在游戏中,经常有这种情况:角色的手或者脚需要在特定时间放在特定的位置.比如角色需要用手撑着跳过一个石头或一堵墙,或者跳起抓住房梁.Target Match就是让动画的特定片段去匹配特定的位置. ...

  7. Unity动画系统详解5:BlendTree混合树是什么?

    摘要:"Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树." 洪流学堂,让你快人几步.你好,我是跟着大智 ...

  8. unity velocity_Unity动画系统详解5:BlendTree混合树是什么?

    摘要:"Animator中有一个功能,用来解决多个动画之间的混合,经常用于移动动画之间的混合,这个功能叫做BlendTree,混合树." 洪流学堂,让你快人几步.你好,我是跟着大智 ...

  9. T4M插件放入unity后怎么找不到_Unity动画系统详解4:如何用代码控制动画?

    摘要:通过上一篇咱们知道了播放动画需要使用Animator,那么如何用代码控制动画呢? 洪流学堂,让你快人几步.你好,我是跟着大智学Unity的萌新,我叫小新,这几周一起来复(yu)习(xi)动画系统 ...

最新文章

  1. 【MATLAB】三维图形绘制 ( 三维平面图 | 二维网格 | meshgrid 函数 | 绘制网格 | mesh 函授 | 绘制平面 | surf 函数 | 绘制等高线 | contour 函数 )
  2. 快速穷举TCP连接欺骗攻击-利用SYN Cookies
  3. 科大星云诗社动态20210204
  4. halcon python缺陷检测_Halcon学习笔记之缺陷检测(一)
  5. 不需要安装max或者xcode的object C开发环境
  6. python一百行代码多少钱_用86行Python代码模拟太阳系
  7. java自定义变量解析,Thymeleaf内置对象、定义变量、URL参数及标签自定义属性
  8. linux设备驱动模块引用和依赖
  9. G - A Bug‘s Life(并查集) acm寒假集训日记22/1/2
  10. 数据属性和访问器属性
  11. php更改tittle,phpcms V9修改默认title标签
  12. 程序员,过了 40 岁,连 107 岁的 IBM 都不要我们了!
  13. js格式化xml并高亮显示关键字
  14. android 英语论文,Android中Activity的生命周期英语论文+译文.doc
  15. Ubuntu 14.04 安装Octave
  16. excel中输入身份证号后三位变成0怎么办
  17. 100000以内的水仙花数C语言,找出1000000内的水仙花数
  18. html火焰字效果,ps怎样制作燃烧的火焰字 巧用图层样式给字体增加火焰特效教程...
  19. 论文笔记——TransPose
  20. 微信利用小号和大号的好友聊天(基于wxpy库)

热门文章

  1. FTP服务器软件 虚拟目录,用 FileZilla Server 别名设置虚拟目录
  2. 不留痕迹弄坏柴油机_玉柴柴油发电机组入门操作手册--新手用户必读
  3. 【游戏开发实战】Unity ShaderGraph 2D描边效果、不规则描边效果
  4. 即食燕窝有营养价值吗?值得购买吗?
  5. 第六章 Java数据结构和算法 之 容器类(一)
  6. 项目Cycle Time的一种确定方式
  7. 支线_电子产品_00
  8. 计算机网络ospf删除代码,思科OSPF网络通告问题-被network这个命令后面带的掩码搞混淆了 - 思科技术论坛 - 51CTO技术论坛_中国领先的IT技术社区...
  9. 网络安全学习笔记——第五天 防火墙功能特性
  10. 《武林外传》之(零) 管理演绎