OSG 场景节点添加,删除,隐藏 ,开关

时间:2022-12-26 16:11:12


添加节点


我们通过osg::ref_ptr<osg::Group> root = new osg::Group();申请场景根节点

通过osg::ref_ptr<osg::Node> node = new osg::Node();可以申请多个节点,从而达到在场景中添加多个场景


如:

osg::ref_ptr<osg::Group> root = new osg::Group();

osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");

root->addChild(osgDB::readNodeFile("glider.osg"));

root->addChild(node.get());


删除节点


因某种需要,现需要删除某些节点。可以通过removeChild删除个别节点,也可以通过removeChildren删除多个节点,里面的参数有些需要索引值

如:root->removeChild(node1);


如果要删除一个节点,那么该节点下的所有节点都会被删除,如果一个节点被加入到一个组中两次,那么这两次就分别存在,删除一次还有另一次。

在内存映像中,如果一个模型被读取一次,而用了多次,那么所占用的空间是不会改变的。


假设:

osg::ref_ptr<osg::Group>类型结点root,root下加三个孩子osg::ref_ptr<osg::Node>类型结点node1node2node3,

程序会按加的顺序记录索引,此时root会记录node1node2node3分别为孩子012node1node2node3也都会记录root为它们的父亲0

若:node1下还有一些孩子节点,即其为一树, 使用root->removeChild(node1); ///移除root下的node1结点,node1的树关系不会变 ,只是解除root与node1的父子关系

这时root会自动将noee2变为root孩子0node3变为root孩子1。对于node1变为无父亲节点。只要没有对node1指针清零,这个节点的数据还是存在的,还可以再次利用。


若:定义类型osg::ref_ptf<osg::MatrixTransform>transform变化结点。

操作 root->replaceChild(node1, transform) ///把node1节点换成transform节点,此时在root下node20孩子,node31孩子,transform2孩子。

操作 tansform->addChild(node1); ///node1的父亲0transform,假设node1还有其他父节点,那么结果就是tansform是其最后一个父亲了。

经常使用这两段代码对场景根下的某个结点进行位置变换,所以,使用孩子取代函数replaceChild并不是对被取代结点和取代结点进行简单的替换,而是每进行一次这样的操作会把取代结点transform作为root根节点的最后一个孩子索引,被取代节点node1也是把取代结点作为最后一个父亲。


隐藏模型


隐藏模式,只是将模型隐藏,模型仍在渲染中,损耗并未减少。

可以通过:node->setNodeMask(0X0) 设置隐藏

可以通过:node->setNodeMask(1) 设置显示


节点开关


在关闭节点时,这些节点占用的内存会被释放掉


osgViewer::Viewer viewer;
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("robot.osg");
osg::ref_ptr<osg::Switch> sw = new osg::Switch();
root->addChild(osgDB::readNodeFile("glider.osg"));

       //开关节点
sw->addChild(node,false);   //false参数显示关,可通过设置为ture显示为开
root->addChild(sw);
viewer.setSceneData(root);
viewer.realize();
return viewer.run();