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

  1. osg::Matrix mt = osg::Matrix::scale( osg::Vex3(sx, sy, sz) ) *
  2. osg::Matrix::rotate( osg::Quat(angle, axis) ) *
  3. osg::Matrix::translate( osg::Vec3(tx, ty, tz) ) ;
osg::MatrixTransform, osg::PositionAttitudeTransform, osg::AutoTransform 示例:
  1. 代码
  2. #include <osg/Node>
  3. #include <osg/AutoTransform>
  4. #include <osg/MatrixTransform>
  5. #include <osg/PositionAttitudeTransform>
  6. #include <osgDB/ReadFile>
  7. #include <osgViewer/Viewer>
  8.  
  9. //library for OSG
  10. #pragma comment(lib, "osgd.lib")
  11. #pragma comment(lib, "osgDBd.lib")
  12. #pragma comment(lib, "osgViewerd.lib")
  13.  
  14. osg::Transform* createAutoTransform(double posX, osg::Node* node)
  15. {
  16. osg::ref_ptr<osg::AutoTransform> at = new osg::AutoTransform();
  17. at->setAutoRotateMode( osg::AutoTransform::ROTATE_TO_SCREEN );
  18. at->setPosition( osg::Vec3(posX, , ) );
  19. at->addChild( node );
  20.  
  21. return at.release();
  22. }
  23.  
  24. osg::Transform* createMatrixTransform(double posX, double rotateZ, osg::Node* node)
  25. {
  26. osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
  27. mt->setMatrix( osg::Matrix::rotate( rotateZ, osg::Z_AXIS) *
  28. osg::Matrix::translate( posX, , ) );
  29. mt->addChild( node );
  30.  
  31. return mt.release();
  32. }
  33.  
  34. osg::Transform* createPositionAttitudeTransform(double posX, double rotateZ, osg::Node* node)
  35. {
  36. osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
  37. pat->setAttitude( osg::Quat(rotateZ, osg::Z_AXIS) );
  38. pat->setPosition( osg::Vec3(posX, , ) );
  39. pat->addChild(node);
  40.  
  41. return pat.release();
  42. }
  43.  
  44. int main(int argc, char** argv)
  45. {
  46. osg::ArgumentParser argument(&argc, argv);
  47. osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles(argument);
  48. if( !node.get() ) node = osgDB::readNodeFile( "cow.osg" );
  49.  
  50. osg::ref_ptr<osg::Group> root = new osg::Group();
  51. root->addChild( createAutoTransform(0.0, node) );
  52. root->addChild( createMatrixTransform(-15.0, osg::PI_4, node) );
  53. root->addChild( createPositionAttitudeTransform(15.0, -osg::PI_4, node) );
  54.  
  55. osgViewer::Viewer viewer;
  56. viewer.setSceneData( root.get() );
  57. return viewer.run();
  58. }

二. 开关节点(osg::Switch)
开关节点Switch的作用是,在场景中某时刻,它的某些子节点被隐藏和忽略,而列外一些节点正常显示并完成相应功能。示例中利用开关节点的更新回调实现子节点的切换:

  1. 代码
  2. #include <osg/Switch>
  3. #include <osg/NodeCallback>
  4. #include <osgDB/ReadFile>
  5. #include <osgDB/WriteFile>
  6. #include <osgViewer/Viewer>
  7.  
  8. #pragma comment(lib, "osgd.lib")
  9. #pragma comment(lib, "osgDBd.lib")
  10. #pragma comment(lib, "osgViewerd.lib")
  11.  
  12. class CessnaCallback: public osg::NodeCallback
  13. {
  14. public:
  15. virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
  16. {
  17. osg::Switch* sw = dynamic_cast<osg::Switch*>(node);
  18. if(sw && nv)
  19. {
  20. const osg::FrameStamp* fs = nv->getFrameStamp();
  21. if( fs )
  22. {
  23. if( _fireStartFrame < fs->getFrameNumber() )
  24. {
  25. sw->setValue(, false);
  26. sw->setValue(, true);
  27. }
  28. }
  29. }
  30. traverse(node, nv);
  31. }
  32.  
  33. private:
  34. ;
  35. };
  36.  
  37. int main(int argc, char** argv)
  38. {
  39. osg::ref_ptr<osg::Switch> root = new osg::Switch();
  40. root->addChild( osgDB::readNodeFile("cessna.osg"), true );
  41. root->addChild( osgDB::readNodeFile("cessnafire.osg"), false );
  42. root->addUpdateCallback(new CessnaCallback() );
  43.  
  44. osgDB::writeNodeFile( *(root.get()), "Switch.osg" );
  45. osgViewer::Viewer viewer;
  46. viewer.setSceneData( root.get() );
  47. return viewer.run();
  48. }

三. 细节层次节点(osg::LOD)

LOD节点,其基本实现功能是在不影响渲染效果的条件下 ,根据场景对象与观察者的距离,从多个预置方案中选择一种合适的来表达要渲染的物体,从而减轻系统的负担,模型越靠近观察者越精细,而远处只需要较少的多边形类表达。示例如下:

  1. 代码
  2. #include <osg/LOD>
  3. #include <osgDB/ReadFile>
  4. #include <osgViewer/Viewer>
  5. #include <osg/Notify>
  6.  
  7. #pragma comment(lib, "osgd.lib")
  8. #pragma comment(lib, "osgDBd.lib")
  9. #pragma comment(lib, "osgViewerd.lib")
  10.  
  11. int main(int argc, char** argv)
  12. {
  13. osg::ref_ptr<osg::Node> node = osgDB::readNodeFile( "bunny-high.ive" );
  14.  
  15. if(!node)
  16. {
  17. osg::notify(osg::NotifySeverity::ALWAYS) << "Cannot open the model bunny!\n" ;
  18. ;
  19. }
  20.  
  21. float r = node->getBound().radius();
  22.  
  23. osg::ref_ptr<osg::LOD> lod = new osg::LOD();
  24. lod->addChild(node. );
  25. lod->addChild( osgDB::readNodeFile(, r* );
  26. lod->addChild( osgDB::readNodeFile(, FLT_MAX );
  27.  
  28. osgViewer::Viewer viewer;
  29. viewer.setSceneData( lod.get() );
  30. viewer.run();
  31. }

四. 代理节点(ProxyNode)
ProxyNode代理节点是一种用于动态加载其他模型节点的节点类型。这些节点不会立即被解析和加入场景,而是在场景运行过程中逐步载入。示例:

  1. 代码
  2. #include <osg/ProxyNode>
  3. #include <osgDB/ReadFile>
  4. #include <osg/ArgumentParser>
  5. #include <osgViewer/Viewer>
  6. #include <osg/Notify>
  7. #include <iostream>
  8.  
  9. #pragma comment(lib, "osgd.lib")
  10. #pragma comment(lib, "osgDBd.lib")
  11. #pragma comment(lib, "osgViewerd.lib")
  12.  
  13. int main(int argc, char** argv)
  14. {
  15. osg::ArgumentParser argument(&argc, argv);
  16. osg::ref_ptr<osg::ProxyNode> pn = new osg::ProxyNode();
  17. unsigned ;
  18.  
  19. ; i < argument.argc(); i++)
  20. {
  21. if( argument.isString(i) )
  22. {
  23. std::cout << num << ": " << argument[i] << "\n" ;
  24. pn->setFileName( num++, argument[i] );
  25. }
  26. }
  27. if( !pn->getNumFileNames() )
  28. pn->setFileName(, "cow.osg" );
  29.  
  30. osgViewer::Viewer viewer;
  31. viewer.setSceneData( pn.get() );
  32. return viewer.run();
  33. }

OpenSceneGraph几个重要功能节点练习的更多相关文章

  1. 多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址

    Nevron Diagram for .NET是一个功能强大,世界上顶级的.NET图表控件.可扩展的图形报表构架,可以帮您创建功能丰富的Winforms及Webforms图表解决方案.这个产品构建于N ...

  2. Lua BehaviourTree 各节点说明

    项目说明 本行为树的代码使用Lua编写,所有的内容也建立的Lua的基础语法之上 因为公司项目需求,需要一套Lua的行为树代码,所以尝试从饥荒中抽离了行为树相关的代码.绝大多数节点行为与饥荒中相同,不过 ...

  3. zigbee 路由节点丢失后清除 该节点的残余网络信息

    清除脱离网络的 路由节点(stale device)的 残留在各表中以AssociationDevList为例的残余信息. 如图所示拓扑结构中: 路由器1脱离网络后,通过协调器按键操作来  清除 协调 ...

  4. NC6开发配置流程

    1.功能注册 2.菜单注册 3.单据类型管理 4.单据模板初始化 5.查询模板初始化 6.功能节点默认模板设置 7.编码对象注册.编码规则定义

  5. MongoDB 聚合管道(Aggregation Pipeline)

    管道概念 POSIX多线程的使用方式中, 有一种很重要的方式-----流水线(亦称为"管道")方式,"数据元素"流串行地被一组线程按顺序执行.它的使用架构可参考 ...

  6. 分享在winform下实现模块化插件编程

    其实很早之前我就已经了解了在winform下实现插件编程,原理很简单,主要实现思路就是:先定一个插件接口作为插件样式及功能的约定,然后具体的插件就去实现这个插件接口,最后宿主(应用程序本身)就利用反射 ...

  7. 分享在winform下实现左右布局多窗口界面-续篇

    之前的这篇文章<分享在winform下实现左右布局多窗口界面>已经实现了左右布局多窗口界面,今天本来是研究基于winform的插件编程,没想到顺便又找到了另一种实现方案,这种实现方案更简单 ...

  8. HDFS Federation (读书笔记)

    HDFS Federation (读书笔记) HDFS的架构 HDFS包含两个层次:命名空间管理(Namespace) 和 块/存储管理(Block Storage). 命名空间管理(Namespac ...

  9. etc 安装及使用

    键值存储仓库,用于配置共享和服务发现. A highly-available key value store for shared configuration and service discover ...

随机推荐

  1. Base64笔记

    1. 昨天的<MIME笔记>中提到,MIME主要使用两种编码转换方式----Quoted-printable和Base64----将8位的非英语字符转化为7位的ASCII字符. 虽然这样的 ...

  2. Ubuntu Linux系统下的SVN客户端工具PySVN

    在Windows下面一直在用TortoiseSVN做为SVN客户端工具,但它居然没提供Linux版本,无视Linux用户的存在.它视我如空 气,偶视它如废土.开始探索尝试其他跨平台的SVN客户端,最后 ...

  3. linux下GBK->UTF-8文件编码批量转换脚本

    find default -type d -exec mkdir -p utf/{} \;find default -type f -exec iconv -f GBK -t UTF-8 {} -o ...

  4. GPRS管理与创建APN拨号连接(转)

    源:http://www.cnblogs.com/michael-zhangyu/archive/2009/07/04/1516797.html 本文主要介绍一些GPRS管理与创建APN拨号连接相关的 ...

  5. space 管理

    输入:表空间名字 输出:表空间下的一个文件即退出 /tmp/.sql select name from v$database; set serveroutput on; declare i1 varc ...

  6. css div11

    text-indent:30em;  缩进 font-family:"sans serif"文字的字体 border-width:1px; border-style:solid; ...

  7. POJ 2019 Cornfields(二维RMQ)

    相比以前的RMQ不同的是,这是一个二维的ST算法 #include<iostream> #include<cstring> #include<cstdio> #in ...

  8. 原创:LoadTest系列之Local.testtings之Web Test

    在录制脚本后,需要对脚本进行回放,而在Loal.testting的Web Test设置中,可以设置脚本运行的次数,以及是否考虑think time等,如下图所示: 1. 双击Solution Item ...

  9. docker rancher 体验 (未完待续.....)

    docker rancher 体验 官方 githubhttps://github.com/rancher/rancher 环境说明: 10.6.0.14010.6.0.18710.6.0.188 修 ...

  10. 解决cookie 跨iframe

    document.cookie = "name=caoyc;path=/"document.cookie = "age=13;path=/"//时间可以不要,但 ...