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

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.dtcms.com/a/355725.html

相关文章:

  • 9 从 “内存怎么存” 到 “指针怎么用”:计算机内存编址机制 + C 语言指针核心 + memory 模拟实现
  • “AI+制造”政策下,户外智能清洁如何跑出加速度?
  • 20250828-学习JumpServer开源堡垒机使用:统一访问入口 + 安全管控 + 操作审计
  • 复杂BI报表SQL
  • 集成电路学习:什么是TensorFlow
  • MCP Factory——专业 MCP Server 开发平台,正式发布,免费下载!
  • 一站式爬虫MCP服务器助力AI市场分析师
  • 微服务相关面试题
  • ComfyUI ControlNet 保姆级教程:开箱即用的示例工作流,精准控制AI图像生成
  • 记录git报错ssh: connect to host github.com port 22: Connection timed out,已解决
  • P3373 【模板】线段树 2
  • l六步完成麒麟操作系统挂载本地REPO源
  • 软考 系统架构设计师系列知识点之杂项集萃(134)
  • IPv6过渡技术IPv6 over IPv4
  • 【数据结构与算法】LeetCode 20.有效的括号
  • 跨网络通信:路由器如何实现全球互联
  • QT控件:【控件概述】【QWidget核心体系】【按钮类控件】【显示类控件】
  • 实战回忆录从webshell开始突破边界
  • 3D血管图像处理与连接系统
  • Odoo AI 智能查询系统
  • 【LeetCode每日一题】160.相交链表 206. 反转链表
  • AI智能供应链深度解析:从库存优化到风险预警,解锁企业降本提效新路径
  • 基于deepseek的Spring boot入门
  • Zabbix监控Dell R系列硬件(PowerEdge R740等)
  • git 小白入门教学
  • TypeScript:symbol类型
  • vscode自动格式化,取消保存时自动格式化也不好使
  • open webui源码分析11-四个特征之记忆
  • 【MySQL 为什么默认会给 id 建索引? MySQL 主键索引 = 聚簇索引?】
  • 数据结构:排序算法的评判标准(Criteria Used For Analysing Sorts)