查看: 3044|回复: 18

求包围球的问题

[复制链接]

该用户从未签到

发表于 2010-3-10 09:50:15 | 显示全部楼层 |阅读模式
我加载了一个IVE文件,部分节点信息如下:
  一期10号楼单体(MatrixTransform)
     一期10号楼单体(Group)
       1楼(Group)
          楼1-煤气(MatrixTransform)
             *DRQD1001(MatrixTransform)
                 (MatrixTransform)
                      (Geode)
              *DRQD1002(MatrixTransform)
                 (MatrixTransform)
                      (Geode)
求包围球:

osg::NodePath np = m_node->getParentalNodePaths()[0];
(m_node为要求包围球的节点)
osg::Matrix matrixWorld = osg::computeLocalToWorld(np);
//创建矩阵变换节点
osg::ref_ptr<osg::MatrixTransform> matrixTransform=new osg::MatrixTransform();
matrixTransform->setMatrix(matrixWorld);
matrixTransform->addChild(m_node);
osg::BoundingSphere bs = matrixTransform->computeBound();
m_centerx=bs.center().x();
m_centery=bs.center().y();
m_centerz=bs.center().z();

从节点“一期10号楼单体”到“楼1-煤气”要这种办法都是正确的,但是计算“楼1-煤气”的子节点*DRQD1001与*DRQD1002都不正确。

该用户从未签到

发表于 2010-3-10 11:24:56 | 显示全部楼层
如果您的意图是求取包围体的世界坐标,那么ComputeBoundsVisitor是最简单的;自己计算得到节点路径NodePath并使用osg::computeLocalToWorld得到变换矩阵也是不错的选择。相比起来您的做法似乎颇为诡异……

该用户从未签到

 楼主| 发表于 2010-3-10 15:55:18 | 显示全部楼层
osg::ComputeBoundsVisitor *ss = new osg::ComputeBoundsVisitor;
    ss->apply(*m_node);
        ss->setTraversalMode( osg::NodeVisitor::TraversalMode::TRAVERSE_ALL_CHILDREN);
osg::BoundingBox bx = ss->getBoundingBox();
m_centerx = bx.center().x();

结果还是不正确, 请问是什么问题?

该用户从未签到

发表于 2010-3-10 16:13:25 | 显示全部楼层
您需要给出更多有关您场景的信息,以及您对于“不正确”的界定和分析;否则别人没办法进行判断。此外setTraversalMode的执行必须在apply之前,否则起不到效果

该用户从未签到

 楼主| 发表于 2010-3-10 16:19:47 | 显示全部楼层
上传3d模型: 单体.rar (383.74 KB, 下载次数: 132)

该用户从未签到

 楼主| 发表于 2010-3-10 16:29:09 | 显示全部楼层
位置相差了很多,我计算了一个有"*"的节点,正确的x位置1万多,现在是4百多

该用户从未签到

发表于 2010-3-10 17:13:23 | 显示全部楼层
  1. _node->getBound().center() * osg::computeLocalToWorld(_node->getParentalNodePaths()[0]);
复制代码
对于您的问题,我想只需要这一行就可以了

该用户从未签到

 楼主| 发表于 2010-3-10 20:00:46 | 显示全部楼层
这个计算方法与第一个计算结果一样,可以用设置相机来检测结果是否正确,(m_centerx -10,m_centery-10,
m_centerz) (m_centerx,m_centery,m_centerz),(0,0,1)

该用户从未签到

发表于 2010-3-10 22:43:15 | 显示全部楼层
我计算了名为*D……这个节点的包围体中心,结果是您所说的“x位置1万多”,我不知道您得到的结果是什么

该用户从未签到

 楼主| 发表于 2010-3-11 08:56:15 | 显示全部楼层
*DRQGX10101 用pick的方式大约是 x = 11577.286,y = 10692.467, z=1.398, 用求包围球计算的结果是x = 12025.9307, y = 10848.9414, z = -2.001461

该用户从未签到

发表于 2010-3-11 09:15:22 | 显示全部楼层
那么请阐述您认为结果不正确的原因。有可能只是您的应用方式不恰当,而使用变换矩阵的计算结果本身已经可以认为是无误的了

该用户从未签到

 楼主| 发表于 2010-3-11 13:21:15 | 显示全部楼层
但是如果我把Geode修改一下
  一期10号楼单体(MatrixTransform)
     一期10号楼单体(Group)
       1楼(Group)
          楼1-煤气(MatrixTransform)
             DRQD1001(MatrixTransform)
                 (MatrixTransform)
                     *DRQD1001 (Geode)
              DRQD1002(MatrixTransform)
                 (MatrixTransform)
                    *DRQD1002  (Geode)
用上面的计算方法就正确了

该用户从未签到

 楼主| 发表于 2010-3-11 14:03:32 | 显示全部楼层
请问不要修改节点的名称就可以得到Geode的包围球计算方法?

该用户从未签到

发表于 2010-3-11 14:45:27 | 显示全部楼层
节点的包围球都是getBound(),没有别的方法
要取得包围球中心的世界坐标,就是我上面给出的方法~~方法本身不会有问题

该用户从未签到

 楼主| 发表于 2010-3-11 15:21:31 | 显示全部楼层
非常感谢array的帮助!!

该用户从未签到

发表于 2011-7-27 09:52:34 | 显示全部楼层
请问下,我求出了包围球之后,想将包围球以网格线的形式显示出来,应该怎么做。

  1.         osg::BoundingSphere bs = pNode->getBound();
  2.         osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  3.         osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
  4.         osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(osg::Vec3(0.0f, 0.0f, 0.0f), bs.radius());
  5.         osg::ref_ptr<osg::ShapeDrawable> sd = new osg::ShapeDrawable(sphere, hints);
  6.         sd->setColor(color);
  7.         geode->addDrawable(sd.get());
复制代码
这样得到的是实体球,应该如何设置呢?

该用户从未签到

发表于 2011-7-28 08:20:34 | 显示全部楼层
设置PolygonMode

该用户从未签到

发表于 2011-7-28 08:33:40 | 显示全部楼层
回复 17# array


    好的,谢谢,我试试。

该用户从未签到

发表于 2011-7-29 09:11:17 | 显示全部楼层
mark xue xi
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表