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菜单 菜单是游戏必不 ...
随机推荐
- 问题 H: 小k的简单问题
问题 H: 小k的简单问题 时间限制: 1 Sec 内存限制: 128 MB提交: 107 解决: 57[提交] [状态] [命题人:jsu_admin] 题目描述 地图上有n个村庄,小k每个月需 ...
- 第一个javascript脚本
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux查看当前目录下所有文件中包含map的行记录
find yaochi_e.prm |xargs grep -ri "map" grep -n "map" *.prm|grep -v "\-\-ma ...
- c# ASP.NET MVC easyui-filebox 图片上传和显示
原文:https://www.cnblogs.com/huatao/p/4727398.html https://www.cnblogs.com/weiweithe/p/4363458.html 表单 ...
- jquery点击按钮弹出图片
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 行人重识别(ReID) ——基于Person_reID_baseline_pytorch修改业务流程
下载Person_reID_baseline_pytorch地址:https://github.com/layumi/Person_reID_baseline_pytorch/tree/master/ ...
- 基于 SwiftUI 创建一个可删除、可添加列表项的列表
执行环境 macOS Mojave: 10.14.5 xcode: Version 11.0 beta 6 (11M392q) 预览效果 完整代码 import SwiftUI class Item: ...
- runtime 理解笔记
runtime 简称运行时,是系统运行的一种机制,在oc中通过c语言编写一个运行系统库.考进行一些非常底层的操作(oc无法完成的). 1.利用runtime,在程序运行过程中,动态创建一个类(比如KV ...
- Petrozavodsk Winter-2018. AtCoder Contest. Problem I. ADD, DIV, MAX 吉司机线段树
题意:给你一个序列,需要支持以下操作:1:区间内的所有数加上某个值.2:区间内的所有数除以某个数(向下取整).3:询问某个区间内的最大值. 思路(从未见过的套路):维护区间最大值和区间最小值,执行2操 ...
- ThreadPoolExecutor线程池原理
参考: https://www.cnblogs.com/liuzhihu/p/8177371.html