osg::NodePathList、osg::NodePath在osg的osg\Node头文件中定义如下:
可以看到NodePath 是以osg::Node为元素的vector容器,osg::NodePathList是以NodePath为元素的容器。具体说明如下:
- NodePath表示一条路径,其中的每个元素表示路径中的每个节点,就像从“西长安街--->故宫”,这里的“西长安街--->故宫”是一条路径,路径中的每个节点就相当于这条路径中的公交站,比如:从西长安街到故宫要经过“天安门西”、“天安门东”、“故宫”三个公交站,这里的“天安门西”、“天安门东”、“故宫”就是NodePath中的Node。
- osg::NodePathList表示从西长安街到故宫的所有路径的集合,因为从西长安街到故宫可以有很多条路可到,比如:从“西长安街--->府右街---->西安门-->北海北->故宫”。
类似的,从父节点(或祖宗节点)到当前节点可以有好多路径。OSG允许一个节点具有多个父节点,在osg::Node类中:
- getParent()方法返回一个osg::Group指针作为父节点。他需要一个表示父节点列表中索引的整数参数,因为某个节点可能有多个父。
- getNumParents()方法返回父节点的总数。如果节点只有一个父节点,该方法将会返回1,而此时只有getParent(0)是正确可用的。
- getParentalNodePaths()方法返回由场景的根节点到当前节点(包含当前节点)的所有可能路径。他返回一个osg::NodePath变量的列表。
- 场景视图的总根节点始终为场景视图下的相机节点。
如下图,假定我们有如下一个场景图:
从Root节点到Child4节点,共有两条路径。分别为:
- Root ---->L_Child1 ---->L_Child2 ---->L_Child3 ---->Child4
- 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讲解,应该能明白程序输出如下: