局部修改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,则输出错误信息。

相关推荐
PXM的算法星球几秒前
使用CAS操作实现乐观锁的完整指南
开发语言
TDengine (老段)10 分钟前
基于 TSBS 标准数据集下 TimescaleDB、InfluxDB 与 TDengine 性能对比测试报告
java·大数据·开发语言·数据库·时序数据库·tdengine·iotdb
付朝鲜1 小时前
用自写的jQuery库+Ajax实现了省市联动
java·前端·javascript·ajax·jquery
coderYYY1 小时前
多个el-form-item两列布局排齐且el-select/el-input组件宽度撑满
前端·javascript·vue.js·elementui·前端框架
rylshe13141 小时前
在scala中sparkSQL连接mysql并添加新数据
开发语言·mysql·scala
小宋加油啊1 小时前
Mac QT水平布局和垂直布局
开发语言·qt·macos
MyhEhud2 小时前
kotlin @JvmStatic注解的作用和使用场景
开发语言·python·kotlin
想睡hhh2 小时前
c++进阶——哈希表的实现
开发语言·数据结构·c++·散列表·哈希
Clown952 小时前
Go语言爬虫系列教程(一) 爬虫基础入门
开发语言·爬虫·golang
Watermelo6172 小时前
前端如何应对精确数字运算?用BigNumber.js解决JavaScript原生Number类型在处理大数或高精度计算时的局限性
开发语言·前端·javascript·vue.js·前端框架·vue·es6