Learning OSG programing---osgAnimation(2)
osg::Node* createBase(const osg::Vec3& center,float radius)
{ int numTilesX = ;
int numTilesY = ; float width = *radius;
float height = *radius; osg::Vec3 v000(center - osg::Vec3(width*0.5f,height*0.5f,0.0f));
osg::Vec3 dx(osg::Vec3(width/((float)numTilesX),0.0,0.0f));
osg::Vec3 dy(osg::Vec3(0.0f,height/((float)numTilesY),0.0f)); // fill in vertices for grid, note numTilesX+1 * numTilesY+1...
osg::Vec3Array* coords = new osg::Vec3Array;
int iy;
for(iy=;iy<=numTilesY;++iy)
{
for(int ix=;ix<=numTilesX;++ix)
{
coords->push_back(v000+dx*(float)ix+dy*(float)iy);
}
} //Just two colours - black and white.
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // white
colors->push_back(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black osg::ref_ptr<osg::DrawElementsUShort> whitePrimitives = new osg::DrawElementsUShort(GL_QUADS);
osg::ref_ptr<osg::DrawElementsUShort> blackPrimitives = new osg::DrawElementsUShort(GL_QUADS); int numIndicesPerRow=numTilesX+;
for(iy=;iy<numTilesY;++iy)
{
for(int ix=;ix<numTilesX;++ix)
{
osg::DrawElementsUShort* primitives = ((iy+ix)%==) ? whitePrimitives.get() : blackPrimitives.get();
primitives->push_back(ix +(iy+)*numIndicesPerRow);
primitives->push_back(ix +iy*numIndicesPerRow);
primitives->push_back((ix+)+iy*numIndicesPerRow);
primitives->push_back((ix+)+(iy+)*numIndicesPerRow);
}
} // set up a single normal
osg::Vec3Array* normals = new osg::Vec3Array;
normals->push_back(osg::Vec3(0.0f,0.0f,1.0f)); osg::Geometry* geom = new osg::Geometry;
geom->setVertexArray(coords); geom->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET); geom->setNormalArray(normals, osg::Array::BIND_OVERALL); geom->addPrimitiveSet(whitePrimitives.get());
geom->addPrimitiveSet(blackPrimitives.get()); osg::Geode* geode = new osg::Geode;
geode->addDrawable(geom); return geode;
}
createBase函数用于建立模型模拟时的地板,作为飞机飞行的参照。
23行中,循环向变量coords中添加坐标点,作为地板的控制点。
36-46行中,交替取出白色面元和黑色面元,并向其中每次添加四个顶点(索引值),指示面元的角点坐标(按照索引值从coords数组中取出)。
随后设置所有面元的法向量,并将黑白面元分别添加进绘制几何节点中,并将绘制几何节点添加到集合节点中,由函数返回。
接下来分析第三个函数:
osg::Node* createMovingModel(const osg::Vec3& center, float radius)
{
float animationLength = 10.0f; osg::AnimationPath* animationPath = createAnimationPath(center,radius,animationLength); osg::ref_ptr<osg::Group> model = new osg::Group; osg::ref_ptr<osg::Node> glider = osgDB::readRefNodeFile("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::ref_ptr<osg::Node> cessna = osgDB::readRefNodeFile("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::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform;
xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath,0.0f,2.0));
xform->addChild(positioned); model->addChild(xform);
} #ifndef OSG_GLES2_AVAILABLE
model->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON);
#endif return model.release();
}
这个函数的作用是创建运动模型。
首先利用上一节介绍的createAnimationPath 函数创建模拟路径,并以此为基础加载模型,并控制模型的运动。
动态更新的核心就是设置数据变度属性DataVariance,它决定了OSG在多线程渲染的过程中的执行策略:只有所有DYNAMIC属性的对象被渲染 完毕之后,OSG才会开始执行下一帧的用户更新操作;这样有效地可以避免数据的过快更新造成当前的渲染动作出错,以致系统崩溃。
将模型进行平移,缩放,并绕z轴旋转180度。创建转换函数,并设置其更新回调函数。AnimationPathCallback的构造函数为:
osg::AnimationPathCallback::AnimationPathCallback ( AnimationPath * ap,
double timeOffset = 0.0,
double timeMultiplier = 1.0
)
该函数的第三个参数决定了节点旋转的速度。因此cessna模型的旋转速度是glider的二倍。这两个模型的加载和回调更新函数的设定过程相同,只是参数有所不同。
Learning OSG programing---osgAnimation(2)的更多相关文章
- Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现(转)
Deep Learning论文笔记之(四)CNN卷积神经网络推导和实现 zouxy09@qq.com http://blog.csdn.net/zouxy09 自己平时看了一些论文, ...
- Deep Learning论文笔记之(八)Deep Learning最新综述
Deep Learning论文笔记之(八)Deep Learning最新综述 zouxy09@qq.com http://blog.csdn.net/zouxy09 自己平时看了一些论文,但老感觉看完 ...
- Deep Learning论文笔记之(六)Multi-Stage多级架构分析
Deep Learning论文笔记之(六)Multi-Stage多级架构分析 zouxy09@qq.com http://blog.csdn.net/zouxy09 自己平时看了一些 ...
- Learning Cocos2d-x for WP8(2)——深入刨析Hello World
原文:Learning Cocos2d-x for WP8(2)--深入刨析Hello World cocos2d-x框架 在兄弟篇Learning Cocos2d-x for XNA(1)——小窥c ...
- Learning Cocos2d-x for WP8(1)——创建首个项目
原文:Learning Cocos2d-x for WP8(1)--创建首个项目 Cocos2d-x for WP8开发语言是C++,系列文章将参考兄弟篇Learning Cocos2d-x for ...
- Learning Cocos2d-x for WP8(9)——Sprite到哪,我做主
原文:Learning Cocos2d-x for WP8(9)--Sprite到哪,我做主 工程文件TouchesTest.h和TouchesTest.cpp 相关素材文件 事件驱动同样适用于coc ...
- Learning Cocos2d-x for WP8(8)——动作Action
原文:Learning Cocos2d-x for WP8(8)--动作Action 游戏很大程度上是由动作画面支撑起来的. 动作分为两大类:瞬间动作和延时动作. 瞬间动作基本等同于设置节点的属性,延 ...
- Learning Cocos2d-x for WP8(7)——让Sprite动起来
原文:Learning Cocos2d-x for WP8(7)--让Sprite动起来 C#(wp7)兄弟篇Learning Cocos2d-x for XNA(7)——让Sprite动起来 本讲将 ...
- Learning Cocos2d-x for WP8(6)——场景切换和场景过渡效果
原文:Learning Cocos2d-x for WP8(6)--场景切换和场景过渡效果 C#(wp7)兄弟篇 Learning Cocos2d-x for XNA(6)——场景切换和场景过渡效果 ...
- Learning Cocos2d-x for WP8(5)——详解Menu菜单
原文:Learning Cocos2d-x for WP8(5)--详解Menu菜单 C#(wp7)兄弟篇Learning Cocos2d-x for XNA(5)——详解Menu菜单 菜单是游戏必不 ...
随机推荐
- .net core jessetalk资料合集
资料推荐集合贴 By Jesse • 2018-01-10 • 5064次浏览 流程图在线预览地址:https://9o90oe.axshare.com/#g=1&p=home OAuth2 ...
- Dubbo源码学习总结系列七---注册中心
Dubbo注册中心是框架的核心模块,提供了服务注册发现(包括服务提供者.消费者.路由策略.覆盖规则)的功能,该功能集中体现了服务治理的特性.该模块结合Cluster模块实现了集群服务.Dubbo管理控 ...
- ubuntu移动分区,修改目录挂在点
由于/tmp目录空间有点小,导致安装一个大软件的时候提示/tmp空间不足,最后通过创建新分区,并将新分区挂在到/tmp下,把/tmp空间扩大. 安装gparted 输入如下命令: sudo apt-g ...
- Express 中配置使用 art-template模板引擎
art-template 官网 https://aui.github.io/art-template/ 安装: npm install --save art-template npm install ...
- 使用vue-resource请求数据的步骤
1.需要安装 vue-resource模块 注意加上--save npm install vue-resource --save 2.main.js 引入vue-resource import Vue ...
- python面向对象--类的内置方法
#isinstance(obj,cls)判断obj是否是类cls的实例 #issubclass(cls,cls1)判断cls是否是cls1的子类或派生类 class Foo: pass class B ...
- css 鼠标经过图片缓慢切换图片、鼠标离开缓慢还原
https://blog.csdn.net/qq_26780317/article/details/80486766 一.控制背景图片在一个圆形div内切换 .header .logo { width ...
- flask之数据库的交互
一:关系型数据库 mysql Flask-SQLAlchemy管理关系型数据库. mysql数据库引擎:url : mysql://username:passowrd@hostname/databas ...
- java int整数相乘溢出
int整数相乘溢出 我们计算一天中的微秒数: * * * * ;// 正确结果应为:86400000000 System.out.println(microsPerDay);// 实际上为:50065 ...
- mysql和haproxy高可用
这片文章主要介绍mysql+haproxy+keepalived的高可用使用. 有两种模式: 第一种:数据库宕机触发VIP漂移的高可用使用. 第二种:haproxy宕机出发VIP漂移的高可用. 这两种 ...