【CesiumJS入门】(4)加载3D Tiles并获取tileset

前言

本次,我们将写一个函数来加载3D Tiles数据,

3D Tiles数据的文档:CesiumGS/3d-tiles: Specification for streaming massive heterogeneous 3D geospatial datasets (github.com)

同时我们将获取加载成功后的tileset数据集(有了tileset后续就可以方便得进行模型相关的操作了),下图为加载模型后的效果。
在这里插入图片描述

实现

写法一

该写法配合Promise,通过实例化一个Cesium3DTileset后通过readyPromise返回tileset,但是这种写法将在CesiumJS 1.107 版本后弃用!!

/**
 * @function addThreeDTiles
 * @param {String} url - 模型切瓦后的瓦片索引文件URL或者Cesium Resource
 * @param {Object} [option] - 选项对象(可选) https://cesium.com/learn/cesiumjs/ref-doc/Cesium3DTileset.html#.ConstructorOptions
 */
 
export function addThreeDTiles(url, option) {
  // 开启地形深度检测:
  // 控制在渲染场景时,相机是否进行深度测试以避免将被遮挡的物体绘制在前景
  // true: 相机会根据地形高度信息进行深度测试,避免将低于地面的物体绘制在地面之上
  viewer.scene.globe.depthTestAgainstTerrain = true

  // ! 写法一:将在 1.107 版本后不支持,options.url和Cesium3DTileset.readyPromise将被移除
  return new Promise(resolve => {
    const tileset = new Cesium.Cesium3DTileset({
      url // 模型切瓦后的瓦片索引文件地址或者Cesium Resource
    })
    tileset.readyPromise.then(() => {
      viewer.scene.primitives.add(tileset)
    })
    resolve(tileset) // 返回模型对象
  })
}

调用:

const modelPromise = addThreeDTiles('/model/Tileset/示例建筑/tileset.json')  // 模型切瓦后的瓦片索引文件URL
const modelPromise2 = addThreeDTiles(Cesium.IonResource.fromAssetId(75343)) // Cesium Ion Resource

modelPromise.then(tileset=> {
  console.log('tileset: ', tileset)
})

推荐:写法二:

配合 async/awaitCesium3DTileset.fromUrlfromIonAssetId来实现:

export async function addThreeDTiles(url, option) {

  viewer.scene.globe.depthTestAgainstTerrain = true
  
  // ! 写法二:
  let tileset = {}
  if (typeof url == 'number') {
    tileset = await Cesium.Cesium3DTileset.fromIonAssetId(url, option);
  } else {
    tileset = await Cesium.Cesium3DTileset.fromUrl(url, option);
  }
  
  viewer.scene.primitives.add(tileset);

  return tileset // 返回模型对象
}

调用方法类似:

const modelPromise = addThreeDTiles('/model/Tileset/示例建筑/tileset.json')  // 模型切瓦后的瓦片索引文件URL
const modelPromise2 = addThreeDTiles(69380) // Cesium Ion Resource

modelPromise.then(tileset=> {
  console.log('tileset: ', tileset)
})

Options

通过上述封装的函数在加载3D Tiles 瓦片集时,可以传入option,option则为初始化Cesium3DTileset时的配置项对象,参考中文文档: Cesium3DTileset - Cesium Documentation

移除tileset

viewer.scene.primitives.remove(tileset);

代码

代码提交参考:
feat: 新增添加3D Tiles · c3759ef · ReBeX/cesium-tyro-blog - Gitee.com
fix: 优化3D Tiles加载方法 · ff20c46 · ReBeX/cesium-tyro-blog - Gitee.com

/*
 * @Date: 2023-05-23 10:45:33
 * @LastEditors: ReBeX  420659880@qq.com
 * @LastEditTime: 2023-06-14 23:24:54
 * @FilePath: \cesium-tyro-blog\src\utils\ThreeDTiles\loadTileset.js
 * @Description:  从给定 URL 加载 3D 模型,添加到场景中,并自动定位到模型所在位置
 * import { addThreeDTiles } from '@/utils/ThreeDTiles/loadTileset.js'
 * const modelPromise = addThreeDTiles('/model/Tileset/示例建筑/tileset.json')
 * const modelPromise = addThreeDTiles(69380)
 * modelPromise.then(model => {
 *   console.log('tileset: ', model)
 * })
 */
import { viewer } from '@/utils/createCesium.js' // 引入地图对象
import * as Cesium from 'cesium'

/**
 * @function addThreeDTiles
 * @param {String} url - 模型切瓦后的瓦片索引文件URL或者Cesium Resource
 * @param {Object} [option] - 选项对象(可选) https://cesium.com/learn/cesiumjs/ref-doc/Cesium3DTileset.html#.ConstructorOptions
 */
const tilesetOption = {
  skipLevelOfDetail: true,
  baseScreenSpaceError: 1024,
  skipScreenSpaceErrorFactor: 16,
  skipLevels: 1,
  immediatelyLoadDesiredLevelOfDetail: false,
  loadSiblings: false,
  cullWithChildrenBounds: true
}
export async function addThreeDTiles(url, option) {
  // 开启地形深度检测:
  // 控制在渲染场景时,相机是否进行深度测试以避免将被遮挡的物体绘制在前景
  // true: 相机会根据地形高度信息进行深度测试,避免将低于地面的物体绘制在地面之上
  viewer.scene.globe.depthTestAgainstTerrain = true

  /*
  // ! 写法一:将在 1.107 版本后不支持,options.url和Cesium3DTileset.readyPromise将被移除
  return new Promise(resolve => { // 返回 Promise 对象
    const tileset = new Cesium.Cesium3DTileset({
      url // 模型切瓦后的瓦片索引文件地址或者Cesium Resource: Cesium.IonResource.fromAssetId(75343)
    })
    tileset.readyPromise.then(() => {
      viewer.scene.primitives.add(tileset)
    })
    resolve(tileset) // 返回模型对象
  })
  */

  // ! 写法二:
  let tileset = {}
  if (typeof url == 'number') {
    tileset = await Cesium.Cesium3DTileset.fromIonAssetId(url, option);
  } else {
    tileset = await Cesium.Cesium3DTileset.fromUrl(url, option);
  }

  viewer.scene.primitives.add(tileset);
  // 定位到模型
  viewer.zoomTo(
    tileset,
    new Cesium.HeadingPitchRange(
      0.0,
      -0.5,
      tileset.boundingSphere.radius * 2.0 // 模型的包围球半径的2倍
    )
  )
  return tileset // 返回模型对象
}
  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,针对你的问题,我可以给你一些指导。首先,你需要明确加载3D Tiles的目的是什么。如果你只需要显示一个小范围的地理区域,那么局部加载就是一个非常好的选择,它可以帮助你提高应用程序的性能。 在Cesium中,你可以使用Tileset类加载3D TilesTileset类提供了一些方法,能够帮助你控制加载和显示3D Tiles的细节。下面是一个示例代码,演示如何加载并调整3D Tiles: ```javascript var viewer = new Cesium.Viewer('cesiumContainer'); var tileset = new Cesium.Cesium3DTileset({ url : 'path/to/your/tileset' }); viewer.scene.primitives.add(tileset); // 通过设置Tileset的transform属性,调整3D Tiles的位置和方向 tileset.readyPromise.then(function(tileset) { var boundingSphere = tileset.boundingSphere; var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center); var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0); var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 10.0); var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3()); tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation); }); // 通过设置Tileset的maximumScreenSpaceError属性,控制3D Tiles的细节级别 tileset.maximumScreenSpaceError = 8; ``` 在这个示例中,我们首先创建了一个Cesium的Viewer实例,并将其作为容器显示在HTML页面中。然后,我们创建了一个Tileset实例,并将其添加到场景中。接下来,我们设置了Tileset的transform属性,将3D Tiles调整到我们想要的位置和方向。最后,我们设置了Tileset的maximumScreenSpaceError属性,控制3D Tiles的细节级别。 希望这个示例能够帮助你加载并调整3D Tiles。如果你还有其他的问题,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值