一、结点基本操作
1.添加结点
//OSG中使用 osg::Node 和 osg::Group 装载模型,Node是Group的父类,可以通过以下代码添加多个模型。
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> root= new osg::Group;root->addChild(osgDB::readNodeFile("glider.osg"));root->addChild(osgDB::readNodeFile("osgcool.osgt"));viewer->setSceneData(root);//注意:模型的的默认位置在原点,也就是场景的中间。
2. 删除结点
//可以通过removeChild和removeChildren方法删除结点,需要的参数为索引值或结点本身的指针。
osg::ref_ptf<osg::Node> * glider = osgDB::readNodeFile("glider.osg");root->addChild(osgDB::readNodeFile("osgcool.osgt"));osg::Node * glider = osgDB::readNodeFile("glider.osg");root->addChild(glider);root->addChild(glider);root->removeChild(glider);root->removeChild(glider);注意:如果删除一个结点,那么该结点下的所有结点都会被删除。如果一个极点被加入到一组中多次,那么这两次是分别存在的,删除一次还有一次。
3. 隐藏结点
//隐藏的模型仍在渲染,不会从内存中消失,损耗并未减少,只不过隐藏了而已。node->setNodeMask() 可以设置隐藏与显示, node->setNodeMask(0x0) 表示隐藏, node->setNodeMask(1) 表示显示。 可以通过下面代码实现隐藏指定模型:
root->addChild(osgcool);
root->addChild(osgDB::readNodeFile("glider.osg"));
osgcool->setNodeMask(0x0);
4. 结点开关
//可以使用结点开关 osg::Switch
打开或关闭结点,在关闭时结点所占用的内存将被释放掉。
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Switch> sw = new osg::Switch();
osg::ref_ptr<osg::Node> osgcool = osgDB::readNodeFile("osgcool.osgt");
sw->addChild(osgcool, false);
sw->addChild(osgDB::readNodeFile("glider.osg"));
root->addChild(sw);
viewer.setSceneData(root);
5. 超级指针
超级指针机制,其实就是引用一个计数器。引用一次加一,释放一次减一。当减至0时,内存释放。
使用结点的三种方法:
方法一(超级指针):
osg::ref_ptr<osg::Node> node = new osg::Node();
group->addChild(node.get());
这是最好的方法,十分安全,也是OSG中最常用的方法。在 new osg::Node()
时申请了一个Node的资源,这时在堆内引用该Node的计数器会被置1。在 group->addChild(aNode.get())
时又引用了一次,会再加1。在这两次引用都结束时,Node的资源就会被释放。
方法二:
group->addChild(new osg::Node());
这个方法也是很实用的,但是无法引出Node的指针,也许在别处可以用到,事实上会经常用到。如果已经这样做了,得到Node指针也不是不可以的,可以使用NodeVisitor来得到Node的指针,也可以使用findChild方法来做这件事。
方法三:
osg::Node * node = new osg::Node();
group->addChile(node);
这个应该是最常用,但是最不好的方法,原因在于如果在 osg::Node*node = new osg::Node()
之后发生了错误,抛出了异常,Node所占用的资源没有释放。在有大量交互以及场景变换时,建议使用超级指针。
6. 模型矩阵变换
模型的移动、旋转、缩放其实都是对矩阵进行操作,矩阵可以当作一个特殊的结点加入到组结点中。
- 通过
osg::MatrixTransform
定义变换矩阵, - 通过
setMatrix(osg::Matrix::translate(x, y, z))
实现模型移动, - 通过
setMatrix(osg::Matrix::scale(x, y, z))
实现模型缩放, - 通过
setMatrix(osg::Matrix::rotate(x, y, z))
实现模型旋转。
详细的讲解在第5课时进行讲解。