局部修改3dtiles子模型的位置。

javascript 复制代码
  promise.then((result) => {
          result._root.children.forEach((item) => {
            if (item._contentHeader.uri === value.gateID) {
              submodel = item
            }
          })

添加好的模型 ,查找到对应的子模型的item 赋值为submodel

javascript 复制代码
 gamechange(submodel, height) {
      if (submodel) {
        // 获取当前子模型的初始变换矩阵
        let initialTransform = submodel.transform
        // 创建一个向上的平移向量,平移 10 个单位
        let translation = new Cesium.Cartesian3(0, 0, height)
        // 设置动画时间:1秒内完成
        let duration = 1 // 动画持续时间,单位:秒
        // 设置动画的起始时间和结束时间
        let startTime = this.ffCesium.viewer.clock.currentTime // 动画开始时刻
        // let endTime = Cesium.JulianDate.addSeconds(startTime, duration, new Cesium.JulianDate()) // 动画结束时刻
        // 使用 Cesium 的动画机制平滑地过渡变换矩阵
        let clock = this.ffCesium.viewer.clock
        // 创建一个定时更新的函数
        let donghua = function () {
          // 获取当前时间与动画结束时间之间的进度比例
          let elapsedTime = Cesium.JulianDate.secondsDifference(clock.currentTime, startTime)
          let progress = Math.min(elapsedTime / duration, 1.0) // 动画进度,限制最大值为 1
          // 根据进度计算平移量
          let currentTranslation = Cesium.Cartesian3.multiplyByScalar(translation, progress, new Cesium.Cartesian3())
          // 更新变换矩阵
          let newTransform = Cesium.Matrix4.fromTranslation(currentTranslation)
          // 将新的变换矩阵应用到子模型
          submodel.transform = Cesium.Matrix4.multiply(initialTransform, newTransform, new Cesium.Matrix4())
        }
        // 在每一帧时更新动画
        this.ffCesium.viewer.clock.onTick.addEventListener(donghua)
        setTimeout(() => {
          console.log('停止')
          this.ffCesium.viewer.clock.onTick.removeEventListener(donghua)
        }, 2000)
      } else {
        console.log('未找到子模型。')
      }
      //无动画
      // if (submodel) {
      //   // 获取当前子模型的变换矩阵
      //   let transform = submodel.transform
      //   // 创建一个向上的平移矩阵,平移 10 个单位
      //   let translationMatrix = Cesium.Matrix4.fromTranslation(new Cesium.Cartesian3(0, 0, 10))
      //   // 将平移矩阵应用到子模型的原始变换矩阵上
      //   let newTransform = Cesium.Matrix4.multiply(transform, translationMatrix, new Cesium.Matrix4())
      //   // 将更新后的变换矩阵应用到子模型
      //   submodel.transform = newTransform
      //   console.log('子模型的新变换矩阵已更新。')
      // } else {
      //   console.log('未找到 ID 为 3 的子模型。')
      // }
    },

即可动态的控制某个模型的位移。

这段代码使用 Cesium 来实现子模型的平移动画。具体来说,代码的目的是通过在指定的时间内平滑地将子模型沿 Z 轴(向上)平移一定的高度。下面是对该段代码的详细分析及解释:

代码功能概述:

  1. 初始化变量 :通过 submodel 获取当前子模型的初始变换矩阵。
  2. 设置平移量 :定义一个平移向量 translation,在 Z 轴方向上平移指定的高度(height)。
  3. 设置动画时间:设置动画的持续时间为 1 秒。
  4. 动画执行 :使用 Cesium 的时钟(viewer.clock)和 onTick 事件每帧更新动画,计算当前进度并更新变换矩阵,最终实现平移效果。
  5. 停止动画 :通过 setTimeout 在 2 秒后停止动画。

代码分析:

1. 检查 submodel 是否存在:
javascript 复制代码
if (submodel) {
    // 获取当前子模型的初始变换矩阵
    let initialTransform = submodel.transform;

首先,代码检查是否存在子模型 submodel。如果存在,则获取子模型的初始变换矩阵 submodel.transform

2. 创建平移向量和动画时长:
javascript 复制代码
let translation = new Cesium.Cartesian3(0, 0, height); // 平移向量
let duration = 1; // 动画持续时间,单位:秒
let startTime = this.ffCesium.viewer.clock.currentTime; // 动画开始时刻
  • 创建一个 Cesium.Cartesian3 向量表示沿 Z 轴的平移量。
  • 设置动画持续时间为 1 秒。
  • 获取当前时钟时间 startTime,用来标记动画开始的时间。
3. 创建定时更新的动画函数 donghua
javascript 复制代码
let donghua = function () {
    // 获取当前时间与动画结束时间之间的进度比例
    let elapsedTime = Cesium.JulianDate.secondsDifference(clock.currentTime, startTime);
    let progress = Math.min(elapsedTime / duration, 1.0); // 动画进度,限制最大值为 1
    // 根据进度计算平移量
    let currentTranslation = Cesium.Cartesian3.multiplyByScalar(translation, progress, new Cesium.Cartesian3());
    // 更新变换矩阵
    let newTransform = Cesium.Matrix4.fromTranslation(currentTranslation);
    // 将新的变换矩阵应用到子模型
    submodel.transform = Cesium.Matrix4.multiply(initialTransform, newTransform, new Cesium.Matrix4());
}

在每一帧中,donghua 函数会:

  • 计算当前已过去的时间 elapsedTime,并通过它计算动画进度 progress(最大值限制为 1)。
  • 使用 Cesium.Cartesian3.multiplyByScalar() 方法计算当前平移量。
  • 使用 Cesium.Matrix4.fromTranslation() 创建一个新的变换矩阵(基于当前平移量)。
  • 将新计算的变换矩阵应用到子模型 submodel.transform
4. 在时钟 onTick 上注册动画更新函数:
javascript 复制代码
this.ffCesium.viewer.clock.onTick.addEventListener(donghua);

每当时钟滴答一秒时(即每一帧更新),都会调用 donghua 函数,更新子模型的位置。

5. 设置动画停止机制:
javascript 复制代码
setTimeout(() => {
    console.log('停止');
    this.ffCesium.viewer.clock.onTick.removeEventListener(donghua); // 停止动画
}, 2000);

使用 setTimeout 延时 2 秒后,调用 removeEventListener() 移除时钟的 onTick 事件监听器,停止动画。由于动画持续 1 秒,并且设置了 2 秒的超时,这意味着动画将在 1 秒时完成,之后的 1 秒内会暂停。

6. 如果找不到 submodel,打印错误:
javascript 复制代码
} else {
    console.log('未找到子模型。');
}

如果没有找到 submodel,则输出错误信息。

相关推荐
dlnu201525062226 分钟前
ssr实现方案
前端·javascript·ssr
Kisorge1 小时前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味2 小时前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王3 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发3 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
晓纪同学3 小时前
QT-简单视觉框架代码
开发语言·qt
威桑3 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服3 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb