OSG模型简单控制
转自:http://milkcu.sintune.net/blog/archives/1392673560.html
结点基本操作
添加结点
OSG中使用osg::Node
和osg::Group
装载模型,Node是Group的父类。
可以通过下面代码再场景中显示多个模型:
- #include <osgDB/ReadFile>
- #include <osgViewer/Viewer>
- #include <osg/Node>
- int main(void)
- {
- osgViewer::Viewer viewer;
- osg::Group * root = new osg::Group();
- root->addChild(osgDB::readNodeFile("glider.osg"));
- root->addChild(osgDB::readNodeFile("osgcool.osgt"));
- viewer.setSceneData(root);
- viewer.realize();
- viewer.run();
- return ;
- }
默认时两节点是加在场景的中间。
那为什么飞机会在左边呢?
为什么牛会把其他模型覆盖掉呢?
组结点
如果想在原结点中添加点什么,就需要把原结点作为组结点。
可以使用下面代码再飞机结点中再添加一些东西。
删除结点
可以通过removeChild和removeChildren方法删除结点,需要的参数为索引值或结点本身的指针。
可以通过下面代码实现指定结点的删除:
- #include <osgDB/ReadFile>
- #include <osgViewer/Viewer>
- #include <osg/Node>
- int main(void)
- {
- osgViewer::Viewer viewer;
- osg::Group * root = new osg::Group();
- root->addChild(osgDB::readNodeFile("osgcool.osgt"));
- osg::Node * glider = osgDB::readNodeFile("glider.osg");
- root->addChild(glider);
- root->addChild(glider);
- root->removeChild(glider);
- root->removeChild(glider);
- viewer.setSceneData(root);
- viewer.realize();
- viewer.run();
- return ;
- }
如果删除一个结点,那么该结点下的所有结点都会被删除。
如果一个极点被加入到一组中多次,那么这两次是分别存在的,删除一次还有一次。
隐藏结点
隐藏的模型仍在渲染,不会从内存中消失,损耗并未减少,只不过隐藏了而已。
node->setNodeMask()
可以设置隐藏与显示,node->setNodeMask(0x0)
表示隐藏,node->setNodeMask(1)
表示显示。
可以通过下面代码实现隐藏指定模型:
- # include <osgDB/ReadFile>
- # include <osgViewer/Viewer>
- # include <osg/Node>
- int main(void)
- {
- osgViewer::Viewer viewer;
- osg::Group * root = new osg::Group();
- osg::Node * osgcool = osgDB::readNodeFile("osgcool.osgt");
- root->addChild(osgcool);
- root->addChild(osgDB::readNodeFile("glider.osg"));
- osgcool->setNodeMask(0x0);
- viewer.setSceneData(root);
- viewer.realize();
- viewer.run();
- return ;
- }
在运行程序时按空格键时会回到中心点,该中心点是面向包围球的圆心,如果不存在osgcool,那么按空格会把飞机置于场景中映,而有了osgcool飞机会被放置在左边。
结点开关
可以使用结点开关osg::Switch
打开或关闭结点,在关闭时结点所占用的内存将被释放掉。
可以通过下面代码实现结点打开与关闭:
- # include <osgDB/ReadFile>
- # include <osgViewer/Viewer>
- # include <osg/Node>
- # include <osg/Switch>
- void main()
- {
- osgViewer::Viewer viewer;
- osg::Group * root = new osg::Group();
- osg::Switch * sw = new osg::Switch();
- osg::Node * osgcool = osgDB::readNodeFile("osgcool.osgt");
- sw->addChild(osgcool, false);
- sw->addChild(osgDB::readNodeFile("glider.osg"));
- root->addChild(sw);
- viewer.setSceneData(root);
- viewer.realize();
- viewer.run();
- }
由于osgcool模型根本不存在,所以glider模型置于场景中间。
超级指针
超级指针机制,其实就是引用一个计数器。引用一次加一,释放一次减一。当减至0时,内存释放。
使用结点的三种方法:
方法一(超级指针):
- osg::ref_ptr<osg::Node> node = new osg::Node();
- group->addChild(node.get());
这是最好的方法,十分安全,也是OSG中最常用的方法。在new osg::Node()
时申请了一个Node的资源,这时在堆内引用该Node的计数器会被置1。在group->addChild(aNode.get())
时又引用了一次,会再加1。在这两次引用都结束时,Node的资源就会被释放。
方法二:
- group->addChild(new osg::Node());
这个方法也是很实用的,但是无法引出Node的指针,也许在别处可以用到,事实上会经常用到。如果已经这样做了,得到Node指针也不是不可以的,可以使用NodeVisitor来得到Node的指针,也可以使用findChild方法来做这件事。
方法三:
- osg::Node * node = new osg::Node();
- group->addChile(node);
这个应该是最常用,但是最烂的方法了,原因在于如果在osg::Node*node = new osg::Node()
之后发生了错误,抛出了异常,Node所占用的资源没有释放。
在有大量交互以及场景变换时,建议使用超级指针。
模型矩阵变换
模型的移动、旋转、缩放其实都是对矩阵进行操作,矩阵可以当作一个特殊的结点加入到组结点中。
通过osg::MatrixTransform
定义变换矩阵,
通过setMatrix(osg::Matrix::translate(x, y, z))
实现模型移动,
通过setMatrix(osg::Matrix::scale(x, y, z))
实现模型缩放,
通过setMatrix(osg::Matrix::rotate(x, y, z))
实现模型旋转。
可以通过下面的代码实现模型的移动、旋转、缩放:
- # include <osgDB/ReadFile>
- # include <osgViewer/Viewer>
- # include <osg/Node>
- # include <osg/MatrixTransform>
- int main(void)
- {
- osgViewer::Viewer viewer;
- osg::ref_ptr<osg::Group> root = new osg::Group;
- osg::ref_ptr<osg::Node> osgcool = osgDB::readNodeFile("osgcool.osgt");
- osg::ref_ptr<osg::MatrixTransform> trans = new osg::MatrixTransform;
- trans->setMatrix(osg::Matrix::translate(, , ));
- trans->addChild(osgcool.get());
- osg::ref_ptr<osg::MatrixTransform> scale = new osg::MatrixTransform;
- scale->setMatrix(osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(, , -));
- scale->addChild(osgcool.get());
- osg::ref_ptr<osg::MatrixTransform> rot = new osg::MatrixTransform;
- rot->setMatrix(osg::Matrix::rotate(osg::DegreesToRadians(45.0), , , ) * osg::Matrix::scale(0.5, 0.5, 0.5) * osg::Matrix::translate(, , -));
- rot->addChild(osgcool.get());
- root->addChild(osgcool.get());
- root->addChild(trans.get());
- root->addChild(scale.get());
- root->addChild(rot);
- viewer.setSceneData(root.get());
- viewer.realize();
- viewer.run();
- return ;
- }
在OSG中,坐标轴是可以设置的,默认向右的是X轴,向里的是Y轴,向上的是Z轴,与传统OPENGL坐标轴有所不同。
(全文完)
OSG模型简单控制的更多相关文章
- 关于OGRE与OSG的简单比较【转】
关于OGRE与OSG的简单比较 林乃养 lnychina{at}gmail.com 浙江大学CAD&CG实验室 2010年3月27日 1 前言 我曾经细致阅读过OGRE和OSG官方提供的文档, ...
- 关于 OGRE 与 OSG 的简单比较 (转)
关于 OGRE 与 OSG 的简单比较 1 前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(man ...
- 图像切割之(五)活动轮廓模型之Snake模型简单介绍
图像切割之(五)活动轮廓模型之Snake模型简单介绍 zouxy09@qq.com http://blog.csdn.net/zouxy09 在"图像切割之(一)概述"中咱们简单了 ...
- Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!
Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!
- Neo4j属性图模型简单介绍
本文主要是对Neo4j属性图模型简单的介绍. Neo4j是什么? Neo4j是一款是由java语言实现的图数据库,图形数据库将数据以图的数据结构进行存储和管理,并且能够以高度可问的方式优雅地表示任何种 ...
- 转:关于 OGRE 与 OSG 的简单比较
1 前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(manual).王锐老师等翻译的<Ope ...
- Unity模拟龙之谷人物行走简单控制
我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作.打击感都挺好的. 今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作非常多,我这里仅仅做了简单的w ...
- [原]osg模型动画|骨骼动画
参考源码:osg的官方例子:osganimationviewer 首先制作一个带骨骼动画的模型 demo.FBX 这里面我们做了两个骨骼动画:1.open 2.close 下面开始在osg中使用 ...
- SharePoint2010 -- ECMAScript客户端模型简单示例
ECMAScript客户端模型,是SharePoint2010推出的三种客户端模型".NET托管"."ECMAScript"."Sliverlight ...
随机推荐
- <转>删除文件夹下所有的.svn文件
当使用了svn版本控制系统后每个目录下都会有一个.svn目录存在,开发完当交付产品或者上传到服务器时一般要把这些目录删除,这里总结了一下在linux和win下的办法. 一.在linux下 删除这些目录 ...
- phpcms-v9系统搭建wap网站及单页面
如需要绑定域名为wap.domain.com,作下如操作: 一.把wap.domain.com域名绑定到你的这个网站主机上. 二.在网站后台——模块——手机门户域名里面填写“http://wap.do ...
- PMP 第十三章 项目干系人管理
1.识别干系人是干什么?早期就识别干系人的原因是什么?识别干系人的输入和工具有哪些?干系人分析的几种模型是哪些?干系人登记册的内容有哪些?bbs.mypm.net 2.干系人参与程度的分类是怎样的?干 ...
- [荐]js模版引擎handlebars.js
[官方介绍:http://handlebarsjs.com/] Handlebars provides the power necessary to let you build semantic te ...
- 湖南省第十二届大学生计算机程序设计竞赛 A 2016
1803: 2016 Description 给出正整数 n 和 m,统计满足以下条件的正整数对 (a,b) 的数量: 1. 1≤a≤n,1≤b≤m; 2. a×b 是 2016 的倍数. In ...
- HDU 3461 Code Lock(并查集)
很好的一个题,思想特别6 题意:给你小写字母个数n,每个字母可以向上翻动,例如:d->c,a->z.然后给你m对数(L,R)(L<=R),表示[L,R]之间可以同时向上翻动,且翻动后 ...
- SU Demos-06Selecting Traces
不足之处,欢迎批评指正 共3个脚本,先看readme 第1个脚本 运行结果 第2个脚本 运行结果 第3个脚本 运行结果
- 门店 车销 批发送货 商超 快销专用扫描打印开单手持PDA移动销售管理系统
门店 车销 批发送货 商超 快销专用扫描打印开单手持PDA移动销售管理系统的详细介绍 一. 以PDA等移动终端为媒介,随时随地掌握门店信息. 二. 后台集成了数据统计.多指标分析.销售.库存.会员管理 ...
- AngularJS 包含HTML文件
类似于python tornado的include方法,同样是可以在一个html文件中加载另外一个html文件,这样可以不用重复的写一些几乎不改变的代码. 首先创建两个文件,然后代码如下: <! ...
- jquery(ajax)与js(ajax)的比较
原始js: function update_mess(){ var account_name = $("#account").val(); var xmlhttp; if(wind ...