OSG模型简单控制

转自:http://milkcu.sintune.net/blog/archives/1392673560.html

结点基本操作

添加结点

OSG中使用osg::Nodeosg::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模型简单控制的更多相关文章

  1. 关于OGRE与OSG的简单比较【转】

    关于OGRE与OSG的简单比较 林乃养 lnychina{at}gmail.com 浙江大学CAD&CG实验室 2010年3月27日 1 前言 我曾经细致阅读过OGRE和OSG官方提供的文档, ...

  2. 关于 OGRE 与 OSG 的简单比较 (转)

    关于 OGRE 与 OSG 的简单比较 1   前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(man ...

  3. 图像切割之(五)活动轮廓模型之Snake模型简单介绍

    图像切割之(五)活动轮廓模型之Snake模型简单介绍 zouxy09@qq.com http://blog.csdn.net/zouxy09 在"图像切割之(一)概述"中咱们简单了 ...

  4. Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!

    Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!

  5. Neo4j属性图模型简单介绍

    本文主要是对Neo4j属性图模型简单的介绍. Neo4j是什么? Neo4j是一款是由java语言实现的图数据库,图形数据库将数据以图的数据结构进行存储和管理,并且能够以高度可问的方式优雅地表示任何种 ...

  6. 转:关于 OGRE 与 OSG 的简单比较

    1   前言 我曾经细致阅读过 OGRE 和 OSG 官方提供的文档,有<Pro OGRE 3D Programming>.OGRE自带手册(manual).王锐老师等翻译的<Ope ...

  7. Unity模拟龙之谷人物行走简单控制

    我个人挺喜欢龙之谷(DN)的人物控制的(不是广告哈....),就是人物太萌了一点,动作.打击感都挺好的. 今天用Unity简单模仿了一下DN的人物控制,当然,游戏里面动作非常多,我这里仅仅做了简单的w ...

  8. [原]osg模型动画|骨骼动画

    参考源码:osg的官方例子:osganimationviewer 首先制作一个带骨骼动画的模型  demo.FBX 这里面我们做了两个骨骼动画:1.open   2.close 下面开始在osg中使用 ...

  9. SharePoint2010 -- ECMAScript客户端模型简单示例

    ECMAScript客户端模型,是SharePoint2010推出的三种客户端模型".NET托管"."ECMAScript"."Sliverlight ...

随机推荐

  1. WebRTC代码走读(八):代码目录结构

    转载注明出处http://blog.csdn.net/wanghorse ├── ./base //基础平台库,包括线程.锁.socket等 ├── ./build //编译脚本,gyp ├── ./ ...

  2. Linux系统启动流程及安装命令行版本

    Debian安装 之前也安装过很多次linux不同版本的系统,但安装后都是直接带有桌面开发环境的版本,直接可以使用,正好最近项目不是很忙,想一直了解下Linux的整个启动流程,以及如何从命令行模式系统 ...

  3. C语言判断文件是否存在(转)

    int   access(const   char   *filename,   int   amode); amode参数为0时表示检查文件的存在性,如果文件存在,返回0,不存在,返回-1. 这个函 ...

  4. 以管理身份运行cmd

    搜索出cmd程序,然后右键-以管理员身份运行

  5. T-SQL 高级查询

    基本常用查询 --select select * from student; --all 查询所有 select all sex from student; --distinct 过滤重复 selec ...

  6. LoadRunner如何监控Tomcat性能

    使用LoadRunner做性能测试,一般的直觉是LR只能完成脚本录制和编写模拟用户的请求行为,但是在某些情况下,要监控一些中间件或web服务器的性能时,就不能通过录制脚本来完成了,那么就需要手工来编写 ...

  7. LoadRunner检查点

    web_reg_find("Text=ABC", "SaveCount=abc_count", LAST);51Testing软件测试网V?2Rs.J Gmdw ...

  8. Angular.js 以及个人学习网站

    Angular.js  教程 http://www.360doc.com/content/14/0414/15/14416931_368816305.shtml web前端学习: 慕课网:http:/ ...

  9. mongodb学习03 操作详解

    插入文档 db.test.insert({"name":"jinks"}); 批量插入 db.test.insert([{}, {}, {}]); 一次批量插入 ...

  10. NHibernate中多表(对象)间的查询

    一个比较简单的查询代码如下:   IList userList=session.Find (" from testMSSql.student as student where student ...