本教程将教您如何通过 Primitive API 在 Cesium 中转换,加载和使用3D模型。 如果您不熟悉 Cesium,则可能需要查看 Visualizing Spatial Data 教程的 3D Models 部分。
Cesium 支持 3D模型,包括关键帧动画,蒙皮和单个节点拾取,使用 GlTF(由Khronos Group,WebGL和 COLLADA 联合成立的 Khronos Group 在网络上为 3D模型提供的一种新兴的行业标准格式)支持。 Cesium ion 还提供了将 COLLADA 模型转换为glTF的解决方案,以优化流式传输到 CesiumJS 应用程序中。
Cesium包括一些现成的二进制glTF模型:
这些模型在Apps / SampleData / models中都有各自的目录。 大多数将包括原始COLLADA文件(.dae),glTF文件(.gltf)和/或二进制glTF文件(.glb)。 在Cesium应用程序中无需使用原始COLLADA文件。
让我们编写代码来加载这些模型。 在 Sandcastle 中打开 Hello World 示例。 在第4行的var viewer = …下,添加一个场景变量。
var scene = viewer.scene;
接下来,通过添加以下代码,使用Cesium.Model.fromGltf加载地面车辆模型。
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0));
var model = scene.primitives.add(Cesium.Model.fromGltf({
url : '../../../../Apps/SampleData/models/GroundVehiclePBR/GroundVehiclePBR.gltf',
modelMatrix : modelMatrix,
scale : 200.0
}));
点击F8,然后使用右上角的地理编码器工具缩放到 Exton, PA。
我们现在正直视地面车辆。 我们可以使用鼠标右键拖动来放大更近,使用鼠标中键拖动来倾斜视图。
Cesium.Model.fromGltf 异步加载glTF模型(包括所有外部文件),并在完全加载后将其呈现,从而解决了 readyPromise 问题。 仅需要.gltf文件的url,在此示例中为 …/…/…/…/Apps/SampleData/models/GroundVehiclePBR/GroundVehiclePBR.gltf。
还为fromGltf提供了一个可选比例,以放大模型。 许多真实比例的模型可能很小,因此在首次测试模型时甚至可以使用像200000.0这样的大模型,都可以帮助使用较大比例的模型。 例如:
还提供了 modelMatrix 来 fromGltf 来定位和旋转模型。 这将为模型创建局部坐标系。 在此, Cesium.Transforms.eastNorthUpToFixedFrame 用于创建本地东北向上坐标系,其原点为经度-75.62898254394531,纬度为40.02804946899414。 可以随时更改模型的 modelMatrix 属性以移动模型。
要显示坐标系,请使用Cesium Inspector,在第4行的var viewer = …下的任何位置添加以下代码行。
viewer.extend(Cesium.viewerCesiumInspectorMixin);
嗨,F8,现在检查器用户界面显示在左上方。 展开 Primitive,单击 Pick a Primitive,在地面车辆模型上单击,然后检查 show reference frame 。
在此,x轴(东)是红色,y轴(北)是绿色,z(上)是蓝色。
通过将传递给 fromGltf 的url更改为“ …/…/…/…/Apps/SampleData/models/CesiumAir/Cesium_Air.glb”或“,我们可以使用相同的代码加载飞机或角色模型。 ./…/…/…/Apps/SampleData/models/CesiumMan/Cesium_Man.glb’。 有关所有选项,请参阅 Cesium.Model.fromGltf 的参考文档。
这些模型中的每个模型都内置有动画,这些动画由美术师进行关键帧拍摄,即,美术师通过定义几个关键姿势创建了动画, Cesium 在运行时对其进行插值以创建平滑动画。
要播放动画,请在调用 Cesium.Model.fromGltf 之后添加以下代码。
Cesium.when(model.readyPromise).then(function(model) {
model.activeAnimations.addAll({
loop : Cesium.ModelAnimationLoop.REPEAT
});
});
由于动画存储在 glTF 模型中,因此我们需要等待 readyPromise 解析后才能访问它们。 addAll 用于播放模型中的所有动画。 Cesium.ModelAnimationLoop.REPEAT 循环播放动画,直到将其从 activeAnimations 集合中移除为止。 要播放特定动画,请使用 add,然后提供动画的ID(glTF JSON属性名称)。
除了 loop 选项之外,addAll 和add 还提供了许多选项来控制动画的开始和停止时间,速度和方向。 例如,以下动画以半速(相对于 Cesium 钟)进行动画处理,而相反。
model.activeAnimations.addAll({
loop : Cesium.ModelAnimationLoop.REPEAT,
speedup : 0.5,
reverse : true
});
add 返回一个 ModelAnimation 对象( addAll 返回这些对象的数组),该对象具有有关动画开始,停止和更新每个帧的事件。 例如,这允许相对于另一动画开始一个动画。 查看 start,stop 和 update 事件。
动画与Cesium时钟同步,因此要查看它们,请按播放小部件上的play。 您可以使用时间轴和回放窗口小部件来增加,减少和反转动画的速度。
要将您的应用配置为自动播放动画,请按以下方式初始化查看器:
var viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate : true
});
与所有 Cesium 基本体一样,如果选择了模型,Scene.pick 将返回 Model 作为其结果的一部分。 此外,还会返回 glTF 节点的 glTF id(JSON属性名称)和 glTF 网格,从而可以精确选择不同的模型零件。 以下示例在控制台窗口中的鼠标光标下显示节点和网格名称。
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(
function (movement) {
var pick = scene.pick(movement.endPosition);
if (Cesium.defined(pick) && Cesium.defined(pick.node) && Cesium.defined(pick.mesh)) {
console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name);
}
},
Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
要将COLLADA模型转换为与Cesium一起使用的glTF,请使用Cesium ion上的托管模型转换器转换器,或参阅Khronos Group提供的 COLLADA2GLTF 转换器。
如果在Cesium中加载3D模型时出现问题,请首先查明问题所在。 要么在
查看Sandcastle中的 3D Model example 以及 Model 和 ModelAnimationCollection 的参考文档。