Cesium 实战 - Cesium 通过 CZML 加载自定义关节(articulations)动作
之前介绍了如何 给模型添加 AGI_articulations 扩展:模型自定义关节动作。
本文介绍使用 Cesium
中的 czml
来实现 glTF 模型加载以及开启 glTF
自定义关节(articulations
)动作。
1.模型关节介绍(J15.glb)
以下是 J15.glb 模型中自定义的关节(articulations)属性。
包含一个关节(missiles)以及四个动作(MoveZ、MoveY、Size、RotateX)。
其中:
MoveZ 为向 Z 轴(行进方向)运动,阈值为 -1000 至 1000。
MoveY 为向 Y 轴(相对于模型上下)运动,阈值为 -1000 至 1000。
Size 为模型大小,阈值为 0 至 1,0 模型会消失。
RotateX 为绕 X 轴旋转,阈值为 -360 至 360。
以下是 gltf-vscode 中关节动作的配置(czml 中需要与此配置名称保持一致):
2.Cesium CZML 应用关节代码介绍
articulations 参数需要配置在 model 对象中。
epoch 指的是动作开始的时间。
number 属性两两成对,第一个指的时刻,第二个指的数值。
下图是指定 missiles 关节的四个动作(MoveZ、MoveY、Size、RotateX),注意写法!
需要注意的是:关节名称和动作需要与 gltf-vscode中配置保持一致!
3.完整代码
const czml = [
{
"id": "document",
"name": "SpaceX",
"version": "1.0",
// 需要注意的是,整个地球对象公用一个时钟系统,如果加载多个 czml,请保证时间一致
// 渲染加载其他时钟相关的对象,也要注意时间一致
"clock": {
// 运动的时间区间
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
// 当前时间
"currentTime": "2023-06-14T10:00:00Z",
// 运动速率
"multiplier": 50,
// 是否循环:CLAMPED 不循环;LOOP_STOP 循环
"range": "CLAMPED",
// cesium 系统时钟速率
"step": "SYSTEM_CLOCK_MULTIPLIER"
}
},
{
"id": "Vulcan",
"availability": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
"name": "Vulcan",
// 运动路径
"path": {
"show": [
{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
"boolean": true
}
],
"width": 5,
"resolution": 1,
"leadTime": [
{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
"epoch": "2023-06-14T10:00:00Z",
"number": [
0, 1053,
1053, 0
]
}
],
"trailTime": [
{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
"epoch": "2023-06-14T10:00:00Z",
"number": [
0, 0,
1053, 1053
]
}
],
"material": {
polylineGlow: {
color: [{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z",
rgba: [255, 0, 0, 255],
},
{
"interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z",
rgba: [0, 0, 255, 255],
},
{
"interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z",
rgba: [255, 0, 255, 255],
}
],
glowPower: 0.25,
// taperPower: 0.5,
},
},
},
// 模型
"model": {
"show": true,
"gltf": [
{
"interval": "2023-06-14T10:00:00Z/9999-12-31T23:59:59.9999999Z",
"uri": "https://openlayers.vip/examples/resources/model/J-15_articulation.glb"
}
],
"minimumPixelSize": 128,
"scale": 3,
"runAnimations": false,
// 自定义动作,需要模型存在自定义关节属性
"articulations": {
// 导弹组件向前移动
// MoveZ 为 glTF 中自定义的关节名称
"missiles MoveZ": {
// 开始移动时刻
"epoch": "2023-06-14T10:10:00Z",
// 设置移动参数
"number": [
// 当前 epoch 时刻,第 0 秒的时,Z 轴移动的距离(米)
0, 0,
// 当前 epoch 时刻,第 300 秒的时,Z 轴移动的距离(米)
// 与模型行进方向相反
300, -60
]
},
// 导弹组件向下移动
// MoveY 为 glTF 中自定义的关节名称
"missiles MoveY": {
"epoch": "2023-06-14T10:10:00Z",
"number": [
// 当前 epoch 时刻,第 0 秒的时,Y 轴移动的距离(米)
0, 0,
10, -1,
100, -5,
300, -55
]
},
// 导弹组件向前旋转(下坠效果)
// RotateX 为 glTF 中自定义的关节名称
"missiles RotateX": {
"epoch": "2023-06-14T10:10:00Z",
"number": [
// 当前 epoch 时刻,第 0 秒的时,X 轴旋转角度(度)
0, 0,
100, -5,
150, -25,
300, -80,
]
},
// 导弹组件缩小(隐藏效果)
// Size 为 glTF 中自定义的关节名称
"missiles Size": {
"epoch": "2023-06-14T10:10:00Z",
"number": [
// 当前 epoch 时刻,第 0 秒的时,组件大小为百分之百(0-1)
0, 1,
100, 1,
// 当前 epoch 时刻,第 200 秒的时,组件大小为 0,即消失
200, 1,
300, 0,
]
},
}
},
// 运动位置
"position": {
// 插值
"interpolationAlgorithm": "LAGRANGE",
"interpolationDegree": 2,
"referenceFrame": "FIXED",
"epoch": "2023-06-14T10:00:00Z",
// 位置信息
// 时间、x、y、z
"cartesian": [
0.000, -2181756.507204248, 4401502.463808623, 4082345.0951582263,
300.000, -2221900.867803482, 4405392.727091728, 4056473.1271699946,
600.000, -2252772.6404420133, 4418632.02508438, 4025043.2226449093,
900.000, -2298167.906071293, 4420521.33707002, 3997259.6931305756,
]
},
// 方向
"orientation": {
// 自动计算运动朝向
"velocityReference": "#position"
},
},
]
const viewer = new Cesium.Viewer("cesiumContainer", {
shouldAnimate: true,
});
const dataSourcePromise = viewer.dataSources.add(
Cesium.CzmlDataSource.load(czml)
);
dataSourcePromise
.then(function (dataSource) {
viewer.trackedEntity = dataSource.entities.getById("Vulcan");
})
.catch(function (error) {
console.error(error);
});
总结:articulations 关节动作配置请参考: Cesium 实战 - AGI_articulations 扩展:模型自定义骨骼动画 。
glTF 模型只有经过自定义关节配置之后,才可以通过 Cesium 在地球中使用关节动作(官方示例中的火箭模型已经添加了关节动作)。
一般来说,关节动作尝应用于实现模型组件非准确坐标的动作,比如车轮转动、火箭推进器脱落.
而模拟导弹攻击往往需要具体的坐标位置,应该使用独立模型来实现效果(参照:《Cesium 实战 - 通过 Blender 将模型组件拆解为独立子模型》)。