当前位置: 首页 > backend >正文

vsgCs显示谷歌全球倾斜模型-节点

   前言

       本章将在上章json解析与vsg场景图根节点创建的基础上,继续深入vsgCs中的节点,包含vsgCs::WorldNode和vsgCs::TilesetNode,深入两者与Cesium3DTilesSelection::Tileset的结合,并进一步剖析场景图的更新过程。


目录

  • 1 vsgCs节点与CesiumNative的结合
  • 2 场景图更新

1 vsgCs节点与CesiumNative的结合

       上章深入讲解了vsgCs中节点vsgCs::WorldNode与vsg::TilesetNode通过解析json字符串的创建过程,其中vsgCs::WorldNode可包含多个vsgCs::TilesetNode节点,其中vsgCs::TilesetNode是对Cesium3DTilesSelection::Tileset的封装,此处为vsgCs与CesiumNative的结合处。Cesium3DTilesSelection::Tileset的创建通过”ionAssetID"、"ionAccessToken',针对谷歌全球倾斜模型不涉及overlays,创建过程如下:

 _tileset= std::make_unique<Cesium3DTilesSelection::Tileset>
(*externals,source.ionAssetID.value(),source.ionAccessToken.value(),options);

        其中变量externals类型为Cesium3DTilesSelection::TilesetExternals,依赖关系如下:

       其中CesiumAsync::IAssetAccessor为资产访问器,向服务器发起HTTP/HTTPS请求,获取所需要的瓦片数据;Cesium3DTilesSelection::IPrepareRendererResources 为渲染资源准备器,将加载好的数据转换为渲染引擎可用的资源,vsgCs中会将加载好的数据转换为vsg节点;CesiumUtility::CreditSystem为信用系统,如可通过CesiumUtility::CreditSystem获取google的logo在视口左下角显示;spdlog::logger用于CesiumNative日志的输出。

       接着Cesium3DTilesSelection::Tileset载入元数据,示例代码如下:

        // ExplorationtilesetNode->getTileset()->loadMetadata().thenInMainThread([source](const Cesium3DTilesSelection::TilesetMetadata* metadata){std::string tilesetName;if (source.url){tilesetName = *source.url;}else if (source.ionAssetID){tilesetName = "ion asset " + std::to_string(*source.ionAssetID);}if (metadata){vsg::debug(tilesetName + " has metadata.");if (metadata->schema){vsg::debug(tilesetName + " has schema.");}if (metadata->schemaUri){vsg::debug(tilesetName + " schema uri: " + *metadata->schemaUri);}}else{vsg::debug("Tileset has no metadata?");}}).catchInMainThread([](std::exception&&){vsg::warn("exception getting metadata");});

        上述代码不会阻塞主线程,可将上述代码修改为如下实现同步:、

bool loaded = false;tilesetNode->getTileset()->loadMetadata().thenInMainThread([source,&loaded](const Cesium3DTilesSelection::TilesetMetadata* metadata){std::string tilesetName;if (source.url){tilesetName = *source.url;}else if (source.ionAssetID){tilesetName = "ion asset " + std::to_string(*source.ionAssetID);}if (metadata){OSG_DEBUG << tilesetName <<" has metadata."<<std::endl;if (metadata->schema){OSG_DEBUG << tilesetName << " has schema." << std::endl;}if (metadata->schemaUri){OSG_DEBUG << tilesetName << " schema uri: " << *metadata->schemaUri << std::endl;}loaded = true;}else{OSG_DEBUG << "Tileset has no metadata?" << std::endl;}}).catchInMainThread([](std::exception&&){OSG_WARN << "exception getting metadata" << std::endl;});while (!loaded){osgCs::Context::instance()->_asyncSystem.dispatchMainThreadTasks();std::this_thread::sleep_for(std::chrono::milliseconds(10));}

        通过添加while循环,实现同步。

2 场景图更新

bool TilesetNode::initialize(const vsg::ref_ptr<vsg::Viewer>& viewer)
{updateViews(viewer);// Making a ref_ptr from this is gross. If the caller doesn't hold a ref, then this will be// deleted at the end of the function! We could do unref_nodelete, but UpdateTileset holds// observer_ptrs... Anyway, keeping this "alive" for the whole function avoids a compiler /// clang-tidy error.vsg::ref_ptr<TilesetNode> ref(this);viewer->addUpdateOperation(UpdateTileset::create(ref, viewer), vsg::UpdateOperations::ALL_FRAMES);return true;
}

        上述代码为通过给vsg视景器添加更新操作,实现场景图的更新。

         更新回调UpdateTileset的具体实现如下:


void TilesetNode::UpdateTileset::run()
{vsg::ref_ptr<vsg::Viewer> ref_viewer = viewer;vsg::ref_ptr<TilesetNode> ref_tileset = tilesetNode;if (!ref_viewer || !ref_tileset || !ref_tileset->_tileset){return;}auto& tileset = *ref_tileset->_tileset;VSGCS_ZONESCOPEDN("update view");float deltaTime = 0.0f;vsg::ref_ptr<vsg::FrameStamp> currentFrameStamp(ref_viewer->getFrameStamp());if (ref_tileset->_lastFrameStamp){std::chrono::duration<float> diff = currentFrameStamp->time - ref_tileset->_lastFrameStamp->time;deltaTime = diff.count();}std::vector<Cesium3DTilesSelection::ViewState> viewStates;for_each_view(viewer,[&viewStates](const vsg::ref_ptr<vsg::View>& view, const vsg::ref_ptr<vsg::RenderGraph>& rg){if (auto viewState = createViewState(view, rg)){viewStates.push_back(viewState.value());}});ref_tileset->_viewUpdateResult = &tileset.updateViewGroup(tileset.getDefaultViewGroup(), viewStates, deltaTime);for (const auto& tile : ref_tileset->_viewUpdateResult->tilesToRenderThisFrame){fadeTile(tile, false);}for (const auto& tile : ref_tileset->_viewUpdateResult->tilesFadingOut){fadeTile(tile, true);}tileset.loadTiles();ref_tileset->_lastFrameStamp = currentFrameStamp;
}

         将vsg的视口信息传递给Cesium3DTilesSelection::Tileset,并调用器updateViewGroup方法,更新CesiumNative的场景图,并将CesiumNative的场景图当前要绘制的节点在vsg中进行绘制,当然CesiumNative的场景图准备好的数据需要转换为vsg节点数据,这个过程在vsgResourcePreparer中完成,下章将会详细分析这个转换过程。

文末:本章重点介绍了vsgCs中的关键节点vsgCs::WorldNode与vsgCs::TilesetNode,并深入分析了vsgCs::TilesetNode与CesiumNative的集成机制,以及vsg场景图的更新流程。具体而言,该流程通过将vsg视口信息传递至Cesium3DTilesSelection::Tileset,实现对CesiumNative场景图的更新,并确定当前帧中需要在vsg中绘制的节点。下一章将进一步探讨CesiumNative数据转换为vsg节点的具体实现过程。

http://www.xdnf.cn/news/18914.html

相关文章:

  • 第八章:《性能优化技巧》——深入讲解预分配容量、移动语义、避免频繁拼接等优化策略,以及C++17的`string_view`如何减少拷贝开
  • vxetable数据导出
  • UGUI源码剖析(13):交互的基石——Selectable状态机与Button事件
  • Kafka 4.0 五大 API 选型指南、依赖坐标、上手示例与最佳实践
  • 项目实战4:TrinityCore框架学习
  • 科技守护古树魂:古树制茶行业的数字化转型之路
  • 把llamafacoty微调后的模型导出ollama模型文件
  • 【前端教程】JavaScript入门核心:使用方式、执行机制与核心语法全解析
  • Oracle 数据库权限管理的艺术:从入门到精通
  • 目标检测领域基本概念
  • 第6篇:链路追踪系统 - 分布式环境下的请求跟踪
  • JSP程序设计之JSP指令
  • 【Python】QT(PySide2、PyQt5):Qt Designer,VS Code使用designer,可能的报错
  • Java学习笔记之——通过分页查询样例感受JDBC、Mybatis以及MybatisPlus(一)
  • 上海控安:汽车API安全-风险与防护策略解析
  • Java 实现HTML转Word:从HTML文件与字符串到可编辑Word文档
  • Nginx + Certbot配置 HTTPS / SSL 证书(简化版已测试)
  • 机器视觉学习-day07-图像镜像旋转
  • 【Deepseek】Windows MFC/Win32 常用核心 API 汇总
  • 【PyTorch】基于YOLO的多目标检测项目(一)
  • 【Redis】数据分片机制和集群机制
  • 【Java SE】基于多态与接口实现图书管理系统:从设计到编码全解析
  • C/C++---前缀和(Prefix Sum)
  • 微服务的编程测评系统17-判题功能-代码沙箱
  • MQTT broker 安装与基础配置实战指南(一)
  • 题目—移除元素
  • PyTorch中的激活函数
  • AI需求优先级:数据价值密度×算法成熟度
  • HSA35NV001美光固态闪存NQ482NQ470
  • 达可替尼-