zoukankan      html  css  js  c++  java
  • OSG-简单模型控制

    本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html

    作者写的比较好,再次收藏,希望更多的人可以看到这个文章

    互联网是是一个相互分形并学习的平台,我希望我每个人可以将我们认为有价值的东西,在不损害他人利益的情况下分享给更多的人。

     

     

    添加模型

     

    在OSG当中模型是使用osg::Group和osg::Node来装载在一起的,比如同时需要加入两个模型,模型A了模型B,AB各自是一个NODE,那么可以使用以下语句来做到,首先使用一个Group,然后Group->addChild(A),同样,之后要Group->addChild(B)。然后再把Group添加到viewer当中就可以了。如图3.1所示AB之间的关系。在这里要申明的是NODE是Group的父类,在类中都有相应的方法可以转到对方,故Node与Group
    是通用的,Node也可以被当作Group来用。

     

    简单实例代码

     

    #include<osgDB/ReadFile>
    
    #include<osgViewer/Viewer>
    
    #include<osg/Node>
    
     void main()
    
    {
    
    osgViewer::Viewer viewer;
    
    osg::Group * root=new osg::Group();
    
    root->addChild(osgDB::readNodeFile("glider.osg"));
    
    root->addChild(osgDB::readNodeFile("osgcool.osg"));
    
    viewer.setSceneData(root);
    
    viewer.realize();
    
    viewer.run();
    
    }


    运行结果

     

    删除结点

     

    如果我们不需要某个结点了,比如上图我们看那个小飞机很不爽,我们想把它从场景中删除掉。不知道于某种目的,反正现在要删除掉,可能是开始想看见它现在不想看见它了。可以通过removeChild方法,除多个孩子也可以通过removeChildren方法,里面的参数有些需要索引值,有些需要结点本身的指针,读者可以自己尝试。这里要注意的是,如果要删除一个结点,那么该结点下的所有结点都会被删除。如果一个结点被加入到一个组中两次,那么这两次是分别存在的,删除一次还有另一次。删除操作不能说不是个危险的操作,有些时候,尤其在有移动结点等等混在一起时,删除操作有时候会发生一些比较奇怪的现象。在内存映象当中,如果一个模型被读取一次,而用了多次,那么所占用的空间是不会改变的。

     

    隐藏模型与结点开关

     

    Ø 隐藏模型
       隐藏模型其实模型仍在渲染当中,因此损耗并未减少,只不过隐藏了而已,隐藏的确不是个什么好操作,但是有时候对小模型确实也很实用。node->setNodeMask可以设置隐藏与显示。
    Ø 节点开关
    在OSG当中,专门有一个类来负责打开与关闭结点,该类名为osg::Switch,里面有相应的方法来控制它所管理的结点的打开与关闭。
    两个方法都能控制模型的显示和隐藏,区别在于隐藏模型方法不会让模型在内存中消失,这样对于小的物体频繁的调用会节省一些时间,而对于有些大的模块在用一次以后可能很久再用第二次,这个时候用节点开关可以将模型销毁,再次使用再调入内存,以防止占用更多的资源。

     

    超级指针

     

    超级指针的机制,其实就是引用一个计数器,这个计数器会计算这个箱子被引用的次数,被别人引用一次这个计数器增加一,别人不用一次,即:释放一次,则计数器减一。当减至0时,内存放掉不用。
    们来看使用一个Node的三种方法,对比一下:
    Ø //方法一,最好的方法,十分安全,也是OSG中最常用的方法,多少版本它都没变
    osg::ref_ptr<osg::Node>aNode(new osg::Node());
    group->addChild(aNode.get());
    Ø //方法二,也是非常好的方法,有时候不适用,但也十分安全
    group->addChild(new osg::Node());
    Ø //方法三,非常危险,但是令许多人无故铤而走险的方法
    osg::Node*anotherNode=new osg::Node();
    group->addChild(anotherNode);
    方法一:在new::Node()时申请了一个Node的资源,这时在堆内引用该Node的计算器会被置1。在group->addChild(aNode.get())时又引用了一次,会再加1。在这两次引用都结束时,Node的资源就会被释放。
    方法二:这个方法也是很实用的,但是无法引出Node的指针,也许在别处可以用到,事实上会经常用到。如果已经这样做了,得到Node指针也不是不可以的,可以使用NodeVisitor来得到Node的指针,也可以使用findChild方法来做这件事。
    方法三:这个应该是最常用,但是最烂的方法了,原因在于如果在osg::Node*antherode=new osg::Node()之后发生了错误,抛出了异常,谁来释放Node所占用的资源呢。而这个异常在后面被捕获,程序正常的走下去,而内存却没有被正常的放掉。


    移动/旋转/缩放模型

    移动/旋转/缩放其实都是对矩阵进行操作,在OSG当中,矩阵可以当作一个特殊的结点加入到root当中,而矩阵下也可以另入结点,而加入的结点就会被这个矩阵处理过,比如移动过/旋转过/缩放过。在OSG中控制矩阵的类为osg::MatrixTransform。
    Ø 移动
    osg::Matrix::translate
    Ø 旋转
    osg::Matrix::rotate
    Ø 缩放
    osg::Matrix::scale

     

     

     

     

  • 相关阅读:
    向net core 3.0进击——多平台项目发布与部署
    Linux配置部署_新手向(五)——Docker的安装与使用
    Ubuntu 18.04使用OpenSSL自签证书(证书支持多IP及多域名,谷歌浏览器无警告)
    学习makefile的一个工程示例
    Centos7下设置ceph 12.2.1 (luminous)dashboard UI监控功能
    一个小例子学习makefile
    Centos7下部署ceph 12.2.1 (luminous)集群及RBD使用
    VMware Centos7 桥接 DHCP无法获得IP
    VMware Centos7 NAT 无法上网的解决方法
    jerasure 2.0译文
  • 原文地址:https://www.cnblogs.com/DreamDog/p/9160013.html
Copyright © 2011-2022 走看看