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 轴(向上)平移一定的高度。下面是对该段代码的详细分析及解释:
代码功能概述:
- 初始化变量 :通过
submodel
获取当前子模型的初始变换矩阵。 - 设置平移量 :定义一个平移向量
translation
,在 Z 轴方向上平移指定的高度(height
)。 - 设置动画时间:设置动画的持续时间为 1 秒。
- 动画执行 :使用 Cesium 的时钟(
viewer.clock
)和onTick
事件每帧更新动画,计算当前进度并更新变换矩阵,最终实现平移效果。 - 停止动画 :通过
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
,则输出错误信息。