1. 概述
Cesium自帶的3D Models示例,展示了如何加載glTF格式三維模型數據。glTF是為WebGL量身定制的數據格式,在網絡環境下有自己的優點。可以在Cesium的源碼包中找到一些該類型的數據。
2. 代碼
HTML頁面3DModels.html代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<meta name="description" content="Create 3D models using glTF.">
<meta name="cesium-sandcastle-labels" content="Beginner, Tutorials, Showcases">
<title>Cesium Demo</title>
<script type="text/javascript" src="../Build/Cesium/Cesium.js"></script>
<style>
@import url(../Build/Cesium/Widgets/widgets.css);
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
font-family: sans-serif;
background: #000;
}
.fullSize {
display: block;
position: absolute;
top: 0;
left: 0;
border: none;
width: 100%;
height: 100%;
}
#toolbar {
margin: 5px;
padding: 2px 5px;
position: absolute;
}
</style>
</head>
<body>
<div id="cesiumContainer" class="fullSize"></div>
<div id="toolbar">
<select id = "model_select" class="cesium-button">
<option value="Aircraft">Aircraft</option>
<option value="Ground Vehicle">Ground Vehicle</option>
<option value="Hot Air Balloon">Hot Air Balloon</option>
<option value="Milk Truck">Milk Truck</option>
<option value="Skinned Character">Skinned Character</option>
<option value="Draco Compressed Model">Draco Compressed Model</option>
</select>
</div>
<script src="3DModels.js"></script>
</body>
</html>
主要的javascript代碼3DModels.js如下:
"use strict"
//Add your ion access token from cesium.com/ion/
Cesium.Ion.defaultAccessToken = '你申請的key';
//var viewer = new Cesium.Viewer('cesiumContainer');
var viewer = new Cesium.Viewer('cesiumContainer', {
infoBox: false,
selectionIndicator: false,
shadows: true,
shouldAnimate: true
});
function createModel(url, height) {
viewer.entities.removeAll();
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
minimumPixelSize: 128,
maximumScale: 20000
}
});
viewer.trackedEntity = entity;
}
var model_select = document.getElementById("model_select");
if (model_select) {
model_select.onchange = function () {
switch (model_select.selectedIndex) {
case 0:
createModel('../SampleData/models/CesiumAir/Cesium_Air.glb', 5000.0);
break;
case 1:
createModel('../SampleData/models/GroundVehicle/GroundVehicle.glb', 0);
break;
case 2:
createModel('../SampleData/models/CesiumBalloon/CesiumBalloon.glb', 1000.0);
break;
case 3:
createModel('../SampleData/models/CesiumMilkTruck/CesiumMilkTruck-kmc.glb', 0);
break;
case 4:
createModel('../SampleData/models/CesiumMan/Cesium_Man.glb', 0);
break;
case 5:
createModel('../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf', 0);
break;
default:
break;
}
}
model_select.value="Aircraft";
model_select.onchange();
}
運行效果如下:

3. 解析
3D模型在Cesium中被描述為名為Cesium.Entity的實體類,可以通過這個類加載gltf的3D模型數據。而地球顯示組件Cesium.Viewer存在一個成員變量entities,它就是Cesium.Entity的集合類,提供了add函數接口。所以關鍵代碼如下:
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var heading = Cesium.Math.toRadians(135);
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
var entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
minimumPixelSize: 128,
maximumScale: 20000
}
});
add函數填入的參數及其就是創建Cesium.Entity對象需要的options對象:

其中,model鍵的值就是一個Cesium.ModelGraphics對象,也就是想要加載的的gltf模型,它也有創建自己的options對象:

參數minimumPixelSize表示模型縮小到多少像素后,不再能被縮小。
maximumScale這個參數就有點不好理解了,文檔描述為模型的最大比例尺寸,minimumPixelSize的最大上限。從實際表現上來看,應該表示的就是,縮放時保持模型保持一定的尺度不變,但是不能保持永遠不變,當縮放一定的尺度后,就會縮放一起變小。這個值就是第二次縮放時的尺度。
模型的位置以及方位參數是有外部的Cesium.Entity來決定的。position是其位置信息,orientation是方位信息,這里有點像給Camera設置參數的部分,只不過傳入的方位參數通過headingPitchRollQuaternion進一步轉換成了四元數。
另外一個值得關注的點就是,從文檔中可以看出很多options對象的鍵值其實是Property類型,或者是與Property相關的類型。這里面其實包含了Cesium的Property機制,簡單來說就是這些值可以與時間相關聯,在不同的時間可以動態地返回不同的屬性值,能夠數據驅動,實時動態三維展示。這個Property機制,值得進一步研究。
4. 參考
[1] SuperMap iClient3D for WebGL教程(Entity)-ModelGraphics
[2] Cesium的Property機制總結