Cesium入门笔记(使用大疆智模)

备注: 以下写法为vue3 ts Cesium1.132.0

1. 初始化Cesium

var viewer = new Cesium.Viewer('cesiumContainer', {
      // 去掉对话框警告
      infoBox: false,
      // 是否显示查询按钮
      geocoder: false,
      // 不显示home按钮
      homeButton: true,
      // 控制查看器的显示模式(3D、2.5D、2D是否显示)
      sceneModePicker: true,
      // 是否显示图层选择
      baseLayerPicker: true,
      // 是否显示帮助按钮
      navigationHelpButton: false,
      // 是否显示播放动画、计时
      animation: false,
      // 是否显示时间轴
      timeline: false,
      // 是否显示全屏按钮
      fullscreenButton: true,
      // 使用具有 tile availability 的全球地形,供 sampleTerrainMostDetailed 使用
      terrain: Cesium.Terrain.fromWorldTerrain(),
    })

terrain: Cesium.Terrain.fromWorldTerrain()配置后地图会出现高度,可以适配3D模型.
2. 引入3D模型

// 创建3D Tileset
    const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
      heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
      // 性能优化参数
      maximumScreenSpaceError: 1, // 最大屏幕空间误差(越小越精细)
      // LOD 控制
      skipLevelOfDetail: true, // 是否跳过细节层次
      baseScreenSpaceError: 1024, // 基础屏幕空间误差
      skipScreenSpaceErrorFactor: 16, // 跳过屏幕空间误差因子
      skipLevels: 1, // 跳过的层级数
      immediatelyLoadDesiredLevelOfDetail: false, // 是否立即加载所需LOD
      loadSiblings: false, // 是否加载兄弟节点
      // 动态屏幕空间误差
      dynamicScreenSpaceError: true, // 启用动态屏幕空间误差
      dynamicScreenSpaceErrorDensity: 0.00278,
      dynamicScreenSpaceErrorFactor: 4.0,
      dynamicScreenSpaceErrorHeightFalloff: 0.25,
      // 渲染选项
      progressiveResolutionHeightFraction: 0.3, // 渐进式分辨率高度分数
      foveatedScreenSpaceError: true, // 中心视野优化
      foveatedConeSize: 0.1, // 视野锥体大小
      foveatedMinimumScreenSpaceErrorRelaxation: 0.0, // 最小屏幕误差松弛
    })

url为3D资源的路径  格式为:"....../tileset.json"
maximumScreenSpaceError的配置是重点  为3D模型的渲染精细化程度 数字越小模型越清晰精细相对应的性能消耗越大.

3. 调整3D模型的高度
由于3D模型会出现偏移,远离地图的情况,所以需要调整高度(z轴),贴近地面


方法一 :  terrain未配置Cesium.Terrain.fromWorldTerrain()

  // 创建 ENU 到 ECEF 的变换矩阵
  const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center)

  // 创建平移矩阵
  const translation = new Cesium.Cartesian3(offsetEast, offsetNorth, offsetHeight)
  const translationMatrix = Cesium.Matrix4.fromTranslation(translation)

  // 合成变换矩阵
  const transform = new Cesium.Matrix4()
  Cesium.Matrix4.multiply(enuMatrix, translationMatrix, transform)
  Cesium.Matrix4.multiply(
    transform,
    Cesium.Matrix4.inverse(enuMatrix, new Cesium.Matrix4()),
    transform,
  )

  // 应用变换
  tileset.modelMatrix = Cesium.Matrix4.multiply(
    tileset.modelMatrix,
    transform,
    new Cesium.Matrix4(),
  )

地图为3D球,且terrain未配置Cesium.Terrain.fromWorldTerrain()地图无高度起伏,无法是完美适配3D模型,必须创建变换矩阵,否则会出现X,Y,Z三个轴不同程度偏移.且此方法最好手动调整offsetHeight.

方法二 : terrain配置Cesium.Terrain.fromWorldTerrain()

  // 获取 tileset 中心点
  const center = tileset.boundingSphere.center

  // 获取该点的地形高度
  const cartographic = Cesium.Cartographic.fromCartesian(center)
  let terrainHeight = cartographic.height
  try {
    const updated = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [cartographic])
    terrainHeight = updated && updated[0] ? updated[0].height : cartographic.height
  } catch (err) {
    console.warn('sampleTerrainMostDetailed not available; using original height.', err)
  }
  // 计算需要的调整高度
  const heightOffset = terrainHeight - cartographic.height

  const enuMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center)
  const offset = new Cesium.Cartesian3(0, 0, heightOffset)
  const worldOffset = new Cesium.Cartesian3()
  Cesium.Matrix4.multiplyByPointAsVector(enuMatrix, offset, worldOffset)
  const transform = Cesium.Matrix4.fromTranslation(worldOffset)

  tileset.modelMatrix = Cesium.Matrix4.multiply(
    tileset.modelMatrix,
    transform,
    new Cesium.Matrix4(),
  )

此方法动态设置了需要调整的高度,但由于3D地图高度有起伏,模型贴近地面会有轻微穿模情况.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值