OpenSceneGraph几个重要功能节点练习
OpenSceneGraph几个重要功能节点练习
一. 空间变换节点
空间变换中最重要的是坐标系和矩阵运算了。OSG坐标系中使用右手系,Z轴垂直向上,X轴水平向右,Y轴垂直屏幕向里,与OpenGL和DirectX都不同。
相关缩放、旋转和平移主要由osg::Matrix, osg::Vec3, osg::Quat几个类来完成。
局部坐标系向世界坐标系转换规则是:设在局部坐标系下顶点 V 转换成世界坐标系坐标 V':
V' = V * Mn* Mn-1*……* M3* M2* M1* M0
其中M0到Mn一次为各个矩阵变换。从世界坐标系坐标下顶点 V' 转换成局部坐标系 V:
V = V' * M0-1 * M1-1 * M2-1 * M3-1 *……* Mn-1-1 * Mn-1
对于空间变换而言,无论是OpenGL,DirectX还是OSG,一般都会遵守SRT(Scale/Rotate/Translate)的运算顺序来完成符合矩阵的构建:
其公式为:
M =Ms * Mr * Mt
osg::Matrix mt = osg::Matrix::scale( osg::Vex3(sx, sy, sz) ) * osg::Matrix::rotate( osg::Quat(angle, axis) ) * osg::Matrix::translate( osg::Vec3(tx, ty, tz) ) ;
代码 #include <osg/Node> #include <osg/AutoTransform> #include <osg/MatrixTransform> #include <osg/PositionAttitudeTransform> #include <osgDB/ReadFile> #include <osgViewer/Viewer> //library for OSG #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgViewerd.lib") osg::Transform* createAutoTransform(double posX, osg::Node* node) { osg::ref_ptr<osg::AutoTransform> at = new osg::AutoTransform(); at->setAutoRotateMode( osg::AutoTransform::ROTATE_TO_SCREEN ); at->setPosition( osg::Vec3(posX, , ) ); at->addChild( node ); return at.release(); } osg::Transform* createMatrixTransform(double posX, double rotateZ, osg::Node* node) { osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform(); mt->setMatrix( osg::Matrix::rotate( rotateZ, osg::Z_AXIS) * osg::Matrix::translate( posX, , ) ); mt->addChild( node ); return mt.release(); } osg::Transform* createPositionAttitudeTransform(double posX, double rotateZ, osg::Node* node) { osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform(); pat->setAttitude( osg::Quat(rotateZ, osg::Z_AXIS) ); pat->setPosition( osg::Vec3(posX, , ) ); pat->addChild(node); return pat.release(); } int main(int argc, char** argv) { osg::ArgumentParser argument(&argc, argv); osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles(argument); if( !node.get() ) node = osgDB::readNodeFile( "cow.osg" ); osg::ref_ptr<osg::Group> root = new osg::Group(); root->addChild( createAutoTransform(0.0, node) ); root->addChild( createMatrixTransform(-15.0, osg::PI_4, node) ); root->addChild( createPositionAttitudeTransform(15.0, -osg::PI_4, node) ); osgViewer::Viewer viewer; viewer.setSceneData( root.get() ); return viewer.run(); }
二. 开关节点(osg::Switch)
开关节点Switch的作用是,在场景中某时刻,它的某些子节点被隐藏和忽略,而列外一些节点正常显示并完成相应功能。示例中利用开关节点的更新回调实现子节点的切换:
代码 #include <osg/Switch> #include <osg/NodeCallback> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgViewer/Viewer> #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgViewerd.lib") class CessnaCallback: public osg::NodeCallback { public: virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) { osg::Switch* sw = dynamic_cast<osg::Switch*>(node); if(sw && nv) { const osg::FrameStamp* fs = nv->getFrameStamp(); if( fs ) { if( _fireStartFrame < fs->getFrameNumber() ) { sw->setValue(, false); sw->setValue(, true); } } } traverse(node, nv); } private: ; }; int main(int argc, char** argv) { osg::ref_ptr<osg::Switch> root = new osg::Switch(); root->addChild( osgDB::readNodeFile("cessna.osg"), true ); root->addChild( osgDB::readNodeFile("cessnafire.osg"), false ); root->addUpdateCallback(new CessnaCallback() ); osgDB::writeNodeFile( *(root.get()), "Switch.osg" ); osgViewer::Viewer viewer; viewer.setSceneData( root.get() ); return viewer.run(); }
三. 细节层次节点(osg::LOD)
LOD节点,其基本实现功能是在不影响渲染效果的条件下 ,根据场景对象与观察者的距离,从多个预置方案中选择一种合适的来表达要渲染的物体,从而减轻系统的负担,模型越靠近观察者越精细,而远处只需要较少的多边形类表达。示例如下:
代码 #include <osg/LOD> #include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osg/Notify> #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgViewerd.lib") int main(int argc, char** argv) { osg::ref_ptr<osg::Node> node = osgDB::readNodeFile( "bunny-high.ive" ); if(!node) { osg::notify(osg::NotifySeverity::ALWAYS) << "Cannot open the model bunny!\n" ; ; } float r = node->getBound().radius(); osg::ref_ptr<osg::LOD> lod = new osg::LOD(); lod->addChild(node. ); lod->addChild( osgDB::readNodeFile(, r* ); lod->addChild( osgDB::readNodeFile(, FLT_MAX ); osgViewer::Viewer viewer; viewer.setSceneData( lod.get() ); viewer.run(); }
四. 代理节点(ProxyNode)
ProxyNode代理节点是一种用于动态加载其他模型节点的节点类型。这些节点不会立即被解析和加入场景,而是在场景运行过程中逐步载入。示例:
代码 #include <osg/ProxyNode> #include <osgDB/ReadFile> #include <osg/ArgumentParser> #include <osgViewer/Viewer> #include <osg/Notify> #include <iostream> #pragma comment(lib, "osgd.lib") #pragma comment(lib, "osgDBd.lib") #pragma comment(lib, "osgViewerd.lib") int main(int argc, char** argv) { osg::ArgumentParser argument(&argc, argv); osg::ref_ptr<osg::ProxyNode> pn = new osg::ProxyNode(); unsigned ; ; i < argument.argc(); i++) { if( argument.isString(i) ) { std::cout << num << ": " << argument[i] << "\n" ; pn->setFileName( num++, argument[i] ); } } if( !pn->getNumFileNames() ) pn->setFileName(, "cow.osg" ); osgViewer::Viewer viewer; viewer.setSceneData( pn.get() ); return viewer.run(); }
OpenSceneGraph几个重要功能节点练习的更多相关文章
- 多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址
Nevron Diagram for .NET是一个功能强大,世界上顶级的.NET图表控件.可扩展的图形报表构架,可以帮您创建功能丰富的Winforms及Webforms图表解决方案.这个产品构建于N ...
- Lua BehaviourTree 各节点说明
项目说明 本行为树的代码使用Lua编写,所有的内容也建立的Lua的基础语法之上 因为公司项目需求,需要一套Lua的行为树代码,所以尝试从饥荒中抽离了行为树相关的代码.绝大多数节点行为与饥荒中相同,不过 ...
- zigbee 路由节点丢失后清除 该节点的残余网络信息
清除脱离网络的 路由节点(stale device)的 残留在各表中以AssociationDevList为例的残余信息. 如图所示拓扑结构中: 路由器1脱离网络后,通过协调器按键操作来 清除 协调 ...
- NC6开发配置流程
1.功能注册 2.菜单注册 3.单据类型管理 4.单据模板初始化 5.查询模板初始化 6.功能节点默认模板设置 7.编码对象注册.编码规则定义
- MongoDB 聚合管道(Aggregation Pipeline)
管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...
- 分享在winform下实现模块化插件编程
其实很早之前我就已经了解了在winform下实现插件编程,原理很简单,主要实现思路就是:先定一个插件接口作为插件样式及功能的约定,然后具体的插件就去实现这个插件接口,最后宿主(应用程序本身)就利用反射 ...
- 分享在winform下实现左右布局多窗口界面-续篇
之前的这篇文章<分享在winform下实现左右布局多窗口界面>已经实现了左右布局多窗口界面,今天本来是研究基于winform的插件编程,没想到顺便又找到了另一种实现方案,这种实现方案更简单 ...
- HDFS Federation (读书笔记)
HDFS Federation (读书笔记) HDFS的架构 HDFS包含两个层次:命名空间管理(Namespace) 和 块/存储管理(Block Storage). 命名空间管理(Namespac ...
- etc 安装及使用
键值存储仓库,用于配置共享和服务发现. A highly-available key value store for shared configuration and service discover ...
随机推荐
- bat脚本:自动压缩n天前的文件【转载】
原文如下: bat脚本:自动压缩n天前的文件-中原小伙-ChinaUnix博客http://blog.chinaunix.net/uid-24946452-id-1651762.html 磁盘 ...
- laravel提示Mcrypt PHP extension required
系统Ubuntu 安装Apache,php后发现laravel报 Mcrypt PHP extension required错误 解决办法: apt-get install php5-mcrypt c ...
- Android 手机应用开发经验 之 通过Socket(TCP/IP)与PC通讯
Android 是一个开源的手机操作系统平台,已经被非常多的开发者视作未来最有潜力的智能手机操作系统.而且,在很短的时间内就在Android Market上出现大量的第三方应用程序,供用户下载与使用, ...
- 别在int与float上栽跟头(转)
源:http://www.cnblogs.com/luguo3000/p/3719651.html int与float是我们每天编程都用的两种类型,但是我们真的足够了解它们吗.昨天在博客园看到一个比较 ...
- AngularJS中的$http.post与jQuery.post的区别
原文:http://my.oschina.net/tommyfok/blog/287748 很多时候我们需要用ajax提交post数据,angularjs与jq类似,也有封装好的post. 但是jQu ...
- Java中关于HashMap的使用和遍历(转)
Java中关于HashMap的使用和遍历 分类: 算法与数据结构2011-10-19 10:53 5345人阅读 评论(0) 收藏 举报 hashmapjavastringobjectiterator ...
- 读取cc2530节点的设备类型、协调器、路由器、终端。
建立网络.加入网络流程分析 协调器节点:在1-10 实验8 网络通信实验2 组播通信中 while(MSGpkt) { switch(MSGpkt->hdr.event) { case ZDO ...
- LoadRunner 录制cas 登陆脚本
关于CAS 的概念,见链接:http://www.360doc.com/content/15/0204/17/21706453_446251626.shtml 需要增加4个关联函数 //Correla ...
- 创建mysql数据库的时候指定编码
CREATE DATABASE xxx DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
- iOS图片缓存框架SDWebImage
本文转发至: http://blog.csdn.net/uxyheaven/article/details/7909373 http://www.cocoachina.com/ios/20141212 ...