baidu_27304211 2023-03-14 17:53 采纳率: 26.7%
浏览 128
已结题

请问osg pagelod如何使用

本人OSG刚学习,想用pagelod将四个不同分辨率、同一地区的OSGB数据加载进来并生成索引,利用到眼距离不同,分别加载不同分辨率数据,但运行结果不对,求各位指点


```c++
void createObliqueIndexes(std::string fileDir)
{
    //string dataDir = fileDir + "/Data";
    string dataDir = fileDir;

    osg::ref_ptr<osg::Group> group = new osg::Group();
    vector<string> subDirs;
    findDir(dataDir, subDirs);
        for (size_t i = 0; i < subDirs.size(); i++)
    {
        string name = DirOrPathGetName(subDirs[i]);

        string path = dataDir + "/" + subDirs[i];

        osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(path);

        osg::ref_ptr<osg::PagedLOD> lod = new osg::PagedLOD();

        auto bs = node->getBound();
        auto c = bs.center();    //中心
        auto r = bs.radius();    //半径
        lod->setCenter(c);
        lod->setRadius(r);
        lod->setRangeMode(osg::LOD::RangeMode::DISTANCE_FROM_EYE_POINT);    
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->getOrCreateStateSet();
        lod->addChild(geode.get());

        std::string relativeFilePath = subDirs[i];  //相对路径

        if (0 == i)
        {
            lod->setFileName(0, "");
            lod->setFileName(1, relativeFilePath);

            lod->setRange(0, 0, 1.0);            //第一层不可见
            lod->setRange(1, 100.0, 200.0);
        }

        if (1 == i)
        {
            //lod->setFileName(0, "");
            lod->setFileName(2, relativeFilePath);

            //lod->setRange(0, 0, 1.0);            //第一层不可见
            lod->setRange(2, 200.0, 300.0);
        }

        if (2 == i)
        {
            //lod->setFileName(0, "");
            lod->setFileName(3, relativeFilePath);

            //lod->setRange(0, 0, 1.0);            //第一层不可见
            lod->setRange(3, 300.0, 400.0);
        }

        if (3 == i)
        {
            //lod->setFileName(0, "");
            lod->setFileName(4, relativeFilePath);

            //lod->setRange(0, 0, 1.0);            //第一层不可见
            lod->setRange(4, 400.0, FLT_MAX);
        }

        lod->setDatabasePath("");

        group->addChild(lod);
    }
    std::string outputLodFile = fileDir + "/Data.osgb";
    osgDB::writeNodeFile(*group, outputLodFile);

}


```

  • 写回答

2条回答 默认 最新

  • 2301_77019097 2023-03-14 18:05
    关注

    osg::PagedLOD是一个OpenSceneGraph中的节点类型,在场景图中表示一个细节程度逐步增高的场景对象。需要注意的是,PagedLOD节点并不直接包含任何几何体或者几何体文件,它实际上是一个分层节点,内部包含一些细节更强的子节点,这些子节点决定了场景的细节程度。

    PagedLOD节点的使用通常有两种方式,一种是通过初始化函数 osg::PagedLOD::addRange() 来将不同级别的细节添加到节点中,另一种是通过调用 osgDB::Registry::instance()->readNodeFile() 来从磁盘上加载场景数据。以下是一个简单的例子:

    osg::ref_ptr pagedLOD = new osg::PagedLOD;
    pagedLOD->setFileName(0, "path-to-low-detail.osg");
    pagedLOD->setFileName(1, "path-to-medium-detail.osg");
    pagedLOD->setFileName(2, "path-to-high-detail.osg");
    pagedLOD->addRange(0, 1000.0f);
    pagedLOD->addRange(1000.0f, 2000.0f);
    pagedLOD->addRange(2000.0f, FLT_MAX);
    

    在上面的例子中,我们创建了一个PagedLOD节点,并通过设置文件名和范围,为它添加了三个子节点,分别代表场景的三个细节级别。其中,每一个子节点对应一个文件,因此可以通过这种方式将不同细节级别的场景数据存储在不同的文件中。而每个子节点在何时显示,是由节点的RangeList属性控制的。在上面的例子中,我们将前三个参数依次传入addRange()函数,表示在每个距离范围内显示对应的子节点。实际上,第一个参数表示显示该子节点的最小距离,第二个参数表示显示该子节点的最大距离。如果一个点距离场景中的PagedLOD节点小于所有子节点的最小距离,则显示0级子节点;如果距离场景的距离大于等于0级子节点的最小距离,但小于1级子节点的最小距离,则显示1级子节点,以此类推。

    除了通过添加RangeList属性来控制什么时候显示哪个子节点,还可以通过设置DelayLODReachedReadingPolicy属性来控制触发场景节点细节的渲染时机,例如在时间片段内、帧更新后等等。

    osg::PagedLOD节点使用时需要注意以下几点:

    1. 需要将PagedLOD节点插入正确的场景图节点树中,否则无法正常渲染。
    2. 需要设置节点的RangeList属性,否则无法控制什么时候显示哪个子节点。
    3. 需要将节点的子节点内容存储在正确的文件中,并且文件格式需要符合OpenSceneGraph约定。
    4. 需要在需要查看不同细节级别时调整触发细节渲染的DelayLODReachedReadingPolicy属性。
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 3月21日
  • 创建了问题 3月14日

悬赏问题

  • ¥15 r语言xlsx包下载后使用时出现了下列问题该如何解决
  • ¥15 Arcgis河网分级报错
  • ¥200 java+appium2.1+idea
  • ¥20 请帮我做一个EXE的去重TXT文本
  • ¥15 工价表引用工艺路线,应如何制作py和xml文件
  • ¥15 根据历史数据,推荐问题类型
  • ¥15 需要仿真图,简单的二阶系统实例
  • ¥15 stm32光控照明仿真
  • ¥15 使用人工智能的方法生成满足一定统计参数要求的随机数序列
  • ¥15 SENT协议中相关问题咨询