我要发帖 回复

高级会员

109

主题

1366

积分

0

专家分

OSG-VR-GIS

忠于职守杰出贡献

:

私信
发表时间 : 2007-12-9 19:05:18 | 浏览 : 1724    评论 : 0
Navy11.3 - 如何获取节点在世界坐标的位置

ARRAY翻译

获取某个节点的世界坐标(相对世界原点的位置),有一种方法是创建可以更新矩阵的回调函数。有关这一方法的示例可以参照前面的例子。但是这一方法的弊病在于必须使用更新回调。回调被触发之后,无论用户需要与否,每帧都会自动计算矩阵坐标。如果你不喜欢这种方式的话,可以尝试使用访问器。

使用节点访问器计算世界原点的相对位置
对于场景图形中的一个OSG节点,在它和根节点之间可能会有其它的一些变换节点存在。那么应该如何获取节点在世界的坐标呢?从技术上讲是很难的。节点的每一个父节点都有且只有自己的变换矩阵。通常情况下,这些矩阵中包含了相对坐标数据。如果要计算目标节点的世界坐标的话,则需要将根节点和目标节点之间所有的矩阵相乘。访问器模式的使用解决了这一问题。访问器(Visitor)可以跟踪记录场景图形中节点遍历的路径。OSG提供了相应的函数,用于获取节点路径nodePath并计算基于路径上各个矩阵的世界坐标。

创建从叶节点到根节点的访问器。
对于目标节点,启动访问器。
访问器将遍历整个场景图形,以得到正确的节点路径。
到达根节点之后,计算得到目标节点的世界坐标。
使用访问器的nodePath计算节点世界坐标。
C++格式的代码如下:
// 该访问器类用于返回某个节点的世界坐标。
// 它从起始节点开始向父节点遍历,并随时将历经的节点记录到nodePath中。
// 第一次到达根节点之后,它将记录起始节点的世界坐标。连结起始节点到根节点路径上的
// 所有矩阵之后,即可获得节点的世界坐标。
class getWorldCoordOfNodeVisitor : public osg::NodeVisitor {
public:
   getWorldCoordOfNodeVisitor():
      osg::NodeVisitor(NodeVisitor::TRAVERSE_PARENTS), done(false)
      {
         wcMatrix= new osg::Matrixd();
      }
      virtual void apply(osg::Node &node)
      {
         if (!done)
         {
            if ( 0 == node.getNumParents() ) // 到达根节点,此时节点路径也已记录完整
            {
               wcMatrix->set( osg::computeLocalToWorld(this->getNodePath()) );
               done = true;
            }
            traverse(node);
         }
      }
      osg::Matrixd* giveUpDaMat()
      {
         return wcMatrix;
      }
private:
   bool done;
   osg::Matrix* wcMatrix;
};

// 对于场景中的合法节点,返回osg::Matrix格式的世界坐标。
// 用户创建用于更新世界坐标矩阵的访问器之后,既可获取该矩阵。
// (此函数也可以作为节点派生类的成员函数。)
osg::Matrixd* getWorldCoords( osg::Node* node) {
   getWorldCoordOfNodeVisitor* ncv = new getWorldCoordOfNodeVisitor();
   if (node && ncv)
   {
      node->accept(*ncv);
      return ncv->giveUpDaMat();
   }
   else
   {
      return NULL;
   }
}

最近VR访客


OSG中国官方网站:http://www.osgChina.org
OSG中国官方讨论区:http://bbs.osgChina.org

OSG专业群-OSG地形研究者 49668412
      OSG地形专业研究 45763709

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-9-18 12:55 AM

返回顶部