zoukankan      html  css  js  c++  java
  • Learning OSG programing---osgClip

    OSG Clip例程剖析

    首先是创建剪切节点的函数代码:

     1 osg::ref_ptr<osg::Node> decorate_with_clip_node(const osg::ref_ptr<osg::Node>& subgraph)
     2 {
     3     osg::ref_ptr<osg::Group> rootnode = new osg::Group;
     4 
     5     // create wireframe view of the model so the user can see
     6     // what parts are being culled away.
     7     osg::StateSet* stateset = new osg::StateSet;
     8     //osg::Material* material = new osg::Material;
     9     osg::PolygonMode* polymode = new osg::PolygonMode;
    10     polymode->setMode(osg::PolygonMode::FRONT_AND_BACK,osg::PolygonMode::LINE);
    11     stateset->setAttributeAndModes(polymode,osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
    12 
    13     osg::Group* wireframe_subgraph = new osg::Group;
    14     wireframe_subgraph->setStateSet(stateset);
    15     wireframe_subgraph->addChild(subgraph);
    16     rootnode->addChild(wireframe_subgraph);
    17 
    18     // more complex approach to managing ClipNode, allowing
    19     // ClipNode node to be transformed independently from the subgraph
    20     // that it is clipping.
    21 
    22     osg::MatrixTransform* transform= new osg::MatrixTransform;
    23 
    24     osg::NodeCallback* nc = new osg::AnimationPathCallback(subgraph->getBound().center(),osg::Vec3(0.0f,1.0f,1.0f),osg::inDegrees(45.0f));
    25     transform->setUpdateCallback(nc);
    26 
    27     osg::ClipNode* clipnode = new osg::ClipNode;
    28     osg::BoundingSphere bs = subgraph->getBound();
    29     bs.radius()*= 0.4f;
    30 
    31     osg::BoundingBox bb;
    32     bb.expandBy(bs);
    33 
    34     clipnode->createClipBox(bb);
    35     clipnode->setCullingActive(false);
    36 
    37     transform->addChild(clipnode);
    38     rootnode->addChild(transform);
    39 
    40 
    41     // create clipped part.
    42     osg::Group* clipped_subgraph = new osg::Group;
    43 
    44     clipped_subgraph->setStateSet(clipnode->getStateSet());
    45     clipped_subgraph->addChild(subgraph);
    46     rootnode->addChild(clipped_subgraph);
    47 
    48     return rootnode;
    49 }

      经过梳理发现这段代码主要有两大部分组成:根节点下包含线框子图wireframe_subgraph和裁剪子图clipped_subgraph两部分。他们分别负责绘制线框模型和裁剪模型。

    通过将线框子图的状态集设置为osg::PolygonMode::LINE,并将函数的参数osg::Node& subgraph加入到其下作为子节点。

      声明转换矩阵transform,并设置其模拟路径回调函数。声明裁剪节点clipnode,并创建其边界盒(边界正方体),设置边界盒的边长为函数的参数osg::Node& subgraph的边界球半径的0.4倍。将裁剪节点clipnode作为转换矩阵transform的字节点,以使其按照模拟回调函数不断地进行旋转裁剪,显示动态裁剪效果。

      最后将已裁剪的节点clipped_subgraph的状态集设置为裁剪节点clipnode的状态集。并将其加入到根节点。

      利用绘图工具对以上函数的对象关系进行梳理分析如下:

      注意在上图中,裁剪节点并没有包含函数参数subgraph作为其子节点。它仅仅是一个旋转的裁剪盒子。

      下一个函数是简单裁剪函数,与以上函数不同的是,它没有显示模型的线框模式,而是对模型直接进行裁剪。其函数代码如下:

     1 osg::ref_ptr<osg::Node> simple_decorate_with_clip_node(const osg::ref_ptr<osg::Node>& subgraph)
     2 {
     3     osg::ref_ptr<osg::Group> rootnode = new osg::Group;
     4 
     5 
     6     // more complex approach to managing ClipNode, allowing
     7     // ClipNode node to be transformed independently from the subgraph
     8     // that it is clipping.
     9 
    10     osg::MatrixTransform* transform= new osg::MatrixTransform;
    11 
    12     osg::NodeCallback* nc = new osg::AnimationPathCallback(subgraph->getBound().center(),osg::Vec3(0.0f,0.0f,1.0f),osg::inDegrees(45.0f));
    13     transform->setUpdateCallback(nc);
    14 
    15     osg::ClipNode* clipnode = new osg::ClipNode;
    16     osg::BoundingSphere bs = subgraph->getBound();
    17     bs.radius()*= 0.4f;
    18 
    19     osg::BoundingBox bb;
    20     bb.expandBy(bs);
    21 
    22     clipnode->createClipBox(bb);
    23     clipnode->setCullingActive(false);
    24 
    25     transform->addChild(clipnode);
    26     rootnode->addChild(transform);
    27 
    28 
    29     // create clipped part.
    30     osg::Group* clipped_subgraph = new osg::Group;
    31 
    32     clipped_subgraph->setStateSet(clipnode->getStateSet());
    33     clipped_subgraph->addChild(subgraph);
    34     rootnode->addChild(clipped_subgraph);
    35 
    36     return rootnode;
    37 }

      可以看到,简单裁剪函数去掉了第一个函数中5~16行创建线框模型的代码。分别用正常和简单模式运行程序,结果如下:

    普通模式

    简单模式

    总结:

      程序通过函数参数subgraph获得其边界球,并取其边界球半径的0.4倍建立边界盒。将上述边界盒设为裁剪节点clipnode的裁剪盒。建立转换矩阵transform,设置其模拟路径(动态旋转效果),并将clipnode作为其子节点。将裁剪节点clipnode的状态集设置为裁剪后的子图clipped_subgraph的状态集,以完成对子图参数subgrpah的动态裁剪。最后将转换矩阵transform,裁剪后的子图clipped_subgraph,线框模型添加到根节点中,实现最终的裁剪效果。通过设置转换矩阵transform的模拟回调路径,或修改裁剪节点clipnode的大小和形状,可修改动态裁剪的效果。

  • 相关阅读:
    PHP中使用CURL实现Get和Post请求方法
    编码规范
    session跨域共享问题解决方案
    第二十七节 新增语义标签
    第二十六节 屏幕适配之rem单位
    第二十五节 屏幕适配之em单位
    第二十四节 屏幕适配之响应式布局
    第二十三节 屏幕适配之流体布局
    第二十二节 屏幕适配之适配布局类型
    第二十一节 屏幕适配之背景图尺寸的设置
  • 原文地址:https://www.cnblogs.com/SupremeGIS-Developer/p/10615924.html
Copyright © 2011-2022 走看看