Cesium 实战 - 通过 Blender 将模型组件拆解为独立子模型
- 拆分模型
- 1.导入模型(J15.glb)
- 2.拆分模型
- 3.保存模型
- 完整代码
- 在线示例
上篇博客介绍了 Cesium 实战 - AGI_articulations 扩展:模型自定义关节动作
这篇接着介绍一下,模型组件拆分为独立模型。
本文包括 拆分模型、完整代码以及在线示例三部分。
拆分模型
模型组件拆解为独立模型相对比较简单,主要通过 Blender 来完成,以下是操作步骤:
1.导入模型(J15.glb)
(1)双击打开软件
(2)选中默认元素,按 delete 删除
(3)点击 File-import-gltf/glb,也可以选择导入其他格式。
(4)导入成功,模型会加载,右侧会显示所有组件名以及模型属性。
2.拆分模型
(1)选中需要拆分的模型组件,这里以 J15 正下方导弹为例
安装鼠标中键(滚轮),拖动调整模型视角:
(2)点击选中红框内的导弹(J15_31
),复制(ctrl+c
)。
(3)新开一个blender软件窗口,粘贴(ctrl+v)。
导弹(J15_31)的位置、大小、比例等属性均与原模型一致。
此时导弹(J15_31
)已经是独立的模型,与原模型(J15
)无关联。
(4)移除(按 delete 键)原模型(J15
)的导弹组件(J15_31
)
3.保存模型
(1)保存导弹模型(J15_31)
注意:不要对导弹模型(J15_31)进行任何修改。
File-export-glft。这里需要导出为 gltf 或者 glb。
注意:这里的模型名称,最好与原模型相关,比如:J15_J15_31
(2)保存原模型(J15
),与保存导弹操作一致。
总结:经过拆分的模型 J15_split 和 J15_J15_31 可以共同渲染到地球中,并且只要将坐标、高度以及比例、分辨率等模型参数设置一致,他们的相对位置与拆分前是相同的。
通过Cesium CZML可以分别给他们设置不同的行进时间以及轨迹,实现模拟导弹精准打击的效果。
完整代码
const czml = [
{
"id": "document",
"name": "SpaceX",
"version": "1.0",
// 需要注意的是,整个地球对象公用一个时钟系统,如果加载多个 czml,请保证时间一致
// 渲染加载其他时钟相关的对象,也要注意时间一致
"clock": {
// 运动的时间区间
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:30:33Z",
// 当前时间
"currentTime": "2023-06-14T10:00:00Z",
// 运动速率
"multiplier": 50,
// 是否循环:CLAMPED 不循环;LOOP_STOP 循环
"range": "CLAMPED",
// cesium 系统时钟速率
"step": "SYSTEM_CLOCK_MULTIPLIER"
}
},
// J15 主体
{
"id": "Vulcan",
"availability": "2023-06-14T10:00:00Z/2023-06-14T10:30:33Z",
"name": "Vulcan",
// 运动路径
"path": {
"show": [
{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:30:33Z",
"boolean": true
}
],
"width": 5,
"resolution": 1,
"material": {
polylineGlow: {
color: {rgba: [0, 0, 255, 255]},
glowPower: 0.25,
},
},
},
// 模型
"model": {
"show": true,
"gltf": [
{
"interval": "2023-06-14T10:00:00Z/9999-12-31T23:59:59.9999999Z",
"uri": "https://openlayers.vip/examples/resources/model/j15-main.glb"
},
],
"minimumPixelSize": 256,
"scale": 3,
"runAnimations": false,
},
// 运动位置
"position": {
// 插值
"interpolationAlgorithm": "LAGRANGE",
// 注意插值参数
"interpolationDegree": 1,
"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,
900.000, -2252772.6404420133, 4418632.02508438, 4025043.2226449093,
1500.000, -2298167.906071293, 4420521.33707002, 3997259.6931305756,
]
},
// 方向
"orientation": {
// 自动计算运动朝向
"velocityReference": "#position"
},
},
// J15 导弹 1
{
"id": "Vulcan1",
"availability": "2023-06-14T10:00:00Z/2023-06-14T10:14:33Z",
"name": "Vulcan1",
// 运动路径
"path": {
"show": [
{
"interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
"boolean": false
}
],
"resolution": 1,
},
// 模型
"model": {
"show": true,
"gltf": [
{
"interval": "2023-06-14T10:00:00Z/9999-12-31T23:59:59.9999999Z",
"uri": "https://openlayers.vip/examples/resources/model/j15-1.glb"
},
],
"scale": 3,
"minimumPixelSize": 40,
"runAnimations": false,
// 导弹模型边框
"silhouetteColor": { "rgba": [255, 0, 0, 255]},
// 边框宽度
"silhouetteSize": 1
},
// 运动位置
"position": {
// 插值
"interpolationAlgorithm": "LAGRANGE",
"interpolationDegree": 1,
"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, -2291045.540812567, 4445366.40019355, 3945320.706645339,
]
},
// 方向
"orientation": {
// 自动计算运动朝向
"velocityReference": "#position"
},
},
];
const viewer = new Cesium.Viewer("cesiumContainer", {
shouldAnimate: true,
});
const dataSourcePromise = viewer.dataSources.add(
Cesium.CzmlDataSource.load(czml)
);
dataSourcePromise
.then(function (dataSource) {
const entity = dataSource.entities.getById("Vulcan");
viewer.trackedEntity = entity;
entity.viewFrom = new Cesium.Cartesian3(-21756.507204248, 4412.463808623,5000);
})
.catch(function (error) {
console.error(error);
});
在线示例
J15 模拟攻击