getParentalNodePaths、osg::NodePathList、osg::NodePath详解

osg::NodePathList、osg::NodePath在osg的osg\Node头文件中定义如下:

可以看到NodePath 是以osg::Node为元素的vector容器,osg::NodePathList是以NodePath为元素的容器。具体说明如下:

  1. NodePath表示一条路径,其中的每个元素表示路径中的每个节点,就像从“西长安街--->故宫”,这里的“西长安街--->故宫”是一条路径,路径中的每个节点就相当于这条路径中的公交站,比如:从西长安街到故宫要经过“天安门西”、“天安门东”、“故宫”三个公交站,这里的“天安门西”、“天安门东”、“故宫”就是NodePath中的Node。
  2. osg::NodePathList表示从西长安街到故宫的所有路径的集合,因为从西长安街到故宫可以有很多条路可到,比如:从“西长安街--->府右街---->西安门-->北海北->故宫”。

类似的,从父节点(或祖宗节点)到当前节点可以有好多路径。OSG允许一个节点具有多个父节点,在osg::Node类中:

  1. getParent()方法返回一个osg::Group指针作为父节点。他需要一个表示父节点列表中索引的整数参数,因为某个节点可能有多个父。
  2. getNumParents()方法返回父节点的总数。如果节点只有一个父节点,该方法将会返回1,而此时只有getParent(0)是正确可用的。
  3. getParentalNodePaths()方法返回由场景的根节点到当前节点(包含当前节点)的所有可能路径。他返回一个osg::NodePath变量的列表。
  4. 场景视图的总根节点始终为场景视图下的相机节点。

如下图,假定我们有如下一个场景图:

从Root节点到Child4节点,共有两条路径。分别为:

  1. Root ---->L_Child1 ---->L_Child2 ---->L_Child3 ---->Child4 
  2. Root ---->R_Child1 ---->R_Child2 ---->R_Child3 ---->Child4 

上面的两条路径就是osg::NodePathList容器的元素,即osg::NodePathList[0]就是上面的条目1;osg::NodePathList[1]就是上面的条目2.

osg::NodePathList[0][0]、osg::NodePathList[0][1]、osg::NodePathList[0][2]、osg::NodePathList[0][3]、osg::NodePathList[0][4]对应上面条目1中的Root 、L_Child1、L_Child2 、L_Child3 、 Child4。

osg::NodePathList[1][0]、osg::NodePathList[1][1]、osg::NodePathList[1][2]、osg::NodePathList[1][3]、osg::NodePathList[1][4]对应上面条目1中的Root 、R_Child1、R_Child2 、R_Child3 、Child4 。

如下代码:

int main(int argc, char** argv)
{
	osg::ref_ptr<osgViewer::Viewer> spViewer = new osgViewer::Viewer();
	spViewer->setName("Viewer");

	osg::Camera* pCamera = spViewer->getCamera();
	pCamera->setName("Camera");
	
	osg::ref_ptr<osg::Group> spRoot = new osg::Group();
	spRoot->setName("Root");

	osg::ref_ptr<osg::Node>spNode = osgDB::readNodeFile("cow.osg");
	spNode->setName("Node");

	spRoot->addChild(spNode.get());

	spViewer->setSceneData(spRoot);
	osg::NodePathList lstPath = spNode->getParentalNodePaths();
	
	int m = lstPath.size();
	cout << "Path size:" << m << "\r\n";

	for (size_t iPathIndex = 0; iPathIndex < lstPath.size(); ++iPathIndex)
	{
		size_t iNodeSize = lstPath[iPathIndex].size();
		cout << iPathIndex << "----> size:" << iNodeSize << "\r\n";
		for (size_t iNodeIndex = 0; iNodeIndex < iNodeSize; ++iNodeIndex)
		{
			string strName = lstPath[iPathIndex][iNodeIndex]->getName();
			cout << "Node Name:" << strName << "\r\n";
		}
	}
	return spViewer->run();
}

按照上面画出父子关系图如下:

结合上面对osg::NodePathList、osg::NodePath、getParentalNodePaths讲解,应该能明白程序输出如下:

猜你喜欢

转载自blog.csdn.net/danshiming/article/details/113799503