osgkdtree例子

来源:互联网 发布:西安黑马程序员官网 编辑:程序博客网 时间:2024/06/05 06:41
本例子演示了KDTree,实际上没什么内容。我们就在这没内容的几行代码中挖一挖。
关于KDTree的介绍http://www.cnblogs.com/eyeszjwang/articles/2429382.html,在这里可以
看看。我们不研究算法,只研究代码和实现。
KDTree为场景的求交提供了一种更加有效率、更加精确的算法。
例子中只有一句和KDTree有关的osgDB::Registry::instance()->setBuildKdTreesHint
(osgDB::ReaderWriter::Options::BUILD_KDTREES);在Registry中注册构建KDTree。我们进入
Registry中,构造函数:
_buildKdTreesHint = Options::NO_PREFERENCE;
    _kdTreeBuilder = new 
osg::KdTreeBuilder;
    
    const char* kdtree_str = getenv("OSG_BUILD_KDTREES");

if (kdtree_str)
    {
        bool switchOff = (strcmp(kdtree_str, "off")==0 || 

strcmp(kdtree_str, "OFF")==0 || strcmp(kdtree_str, "Off")==0 );
        if 

(switchOff) _buildKdTreesHint = Options::DO_NOT_BUILD_KDTREES;
        else 
_buildKdTreesHint = Options::BUILD_KDTREES;
    }
从这里可以看出KdTreeBuilder是构建KDTree的地方,首先,KDTree没有指定,读取环境变量,
如果环境变量中没有off字样的就设置Options::BUILD_KDTREES;可见在osg默认是构建了KDTree
的。顺着这些信息看看,KDTree是在什么地方构建的?
在DatabasePager中我们可以看到如下的代码:
_kdTreeBuilder = osgDB::Registry::instance()->getKdTreeBuilder()->clone();
virtual void apply(osg::Geode& geode)
    {
        StateToCompile::apply(geode);

  if (_kdTreeBuilder.valid())
        {
            geode.accept(*_kdTreeBuilder);
   }
    }
他们都在FindCompileableGLObjectsVisitor这个类中,DatabasePager分页数据库,管理
PagedLOD和ProxyNode的,里面存放了数据请求列表、数据等待删除列表、数据等待编译列表、
数据等待融合场景列表、而这个类就是查找需要编译的数据。(具体内容看《最长的一帧》)
KDTree就是在这里构建的。
KdTreeBuilder是构建的关键类,不用说继承自NodeVisitor,要遍历场景的。里面只有void 
apply(osg::Geode& geode);因为它只对几何体感兴趣。
KDTree的构建把我们带到了KDTree这个类中,具体的算法不做分析了,KDTree的用法在上次求交
的例子中有了应用,求交更加精确。
Registry是一个单例,在程序的运行中只有一个对象,因此这个的程序中又有一个
KdTreeBuilder。
原创粉丝点击