Cesium官方教程7--三維模型
原文地址:https://cesiumjs.org/tutorials/3D-Models-Tutorial/
三維模型 (3D Models)
這篇教程給大家介紹,如何在Cesium中通過Primitive API來轉換、載入、使用三維模型。如果你是新手,建議你先看下這篇 空間資料視覺化教程 的三維模型部分。
Cesium支援包含關鍵幀(key-frame)動畫、骨骼(skinning)動畫 的glTF格式的三維模型,並且支援模型節點(node)的拾取。 glTF是 Khronos Group 定義的一個基於web上的新興三維模型格式行業標準。Khronos Group是WebGL和 COLLADA
.dae
)模型轉換為專為Cesium優化的glTF格式。
快速開始
Cesium內建了一些隨時可用的glTF模型:
- 帶螺旋槳動畫的飛機模型
- 帶輪子動畫的汽車模型
- 帶行走骨骼動畫的人物模型
- 熱氣球模型
- 牛奶卡車 Draco壓縮
牛奶車
這些模型都在
Apps/SampleData/models
目錄下有各自的存放目錄。一部分還包含一個COLLADA (
.dae
)格式的原始檔(Cesium中不需要),一個glTF格式(
.gltf
)、一個二進位制glTF格式 (
.glb
)。
下來我們寫示例程式碼. 開啟Sandcastle Hello World 示例。在 var viewer = ...
之後第4行,增加一個 scene
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/GroundVehicle/GroundVehicle.glb', modelMatrix : modelMatrix, scale : 200.0 }));
按F8
執行,使用右上角的位置查詢工具,定位到 Exton, PA。
現在我們垂直俯視觀察這個汽車了。使用滑鼠右鍵拉近一點,然後滑鼠中鍵按下旋轉視角放平一點。
拉近視角
Cesium.Model.fromGltf
方法非同步載入了glTF 以及它的一些外部資原始檔,完全載入(響應了
readyPromise
)之後進行了渲染。只需要gltf檔案的url路徑,示例中就是這個
../../../../Apps/SampleData/models/GroundVehicle/GroundVehicle.glb
。
fromGltf
有個可選的引數scale
可以用來放大縮小模型。很多實際大小的模型都相對地球來說太小了,為了測試可以用 scale
把模型放大一些,有時候甚至可以非常大,比如200000.0
:
放大模型
fromGltf
也可以設定一個
modelMatrix
去放置或者旋轉模型。這個引數會用來建立模型的區域性座標系。我們這裡使用了
Cesium.Transforms.eastNorthUpToFixedFrame
去建立了一個以經緯度(
-75.62898254394531
,
40.02804946899414
)為原點的enu(east-north-up )區域性座標系。為了移動模型,可以隨時修改模型的
modelMatrix
屬性。
為了能看見座標系統,使用Cesium的除錯工具, 在第4行的var viewer = ...
之後新增如下程式碼:
viewer.extend(Cesium.viewerCesiumInspectorMixin);
按 F8
執行,除錯工具已經顯示在右上角了。展開 Primitives
面板,點選Pick a Primitive
,然後在場景中點選汽車模型,然後勾選show reference frame
。
參考座標系
這裡
x
軸(正東向)是紅色的,
y
軸(正北向)是綠色的,
z
軸(垂直向上)是藍色的。
如果載入飛機或者人物的模型,那麼只需要修改程式碼裡的
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檔案內部定義的)。
除了loop
選項,addAll
和 add
函式提供了一些列的引數選項,用來控制動畫的開始、結束、播放速度,以及播放方向。比如下面的程式碼設定動畫逆向按照半速(相對Cesium時鐘)播放:
model.activeAnimations.addAll({
loop : Cesium.ModelAnimationLoop.REPEAT,
speedup : 0.5, reverse : true });
add
函式返回一個 ModelAnimation
類例項 (addAll
返回一個該類的例項陣列), 這個類包含了動畫的開始、停止、每幀更新的事件。比如可以用來控制一個動畫在另一個結束後開始播放。具體檢視 start, stop, 和update 事件.
動畫是和Cesium時鐘同步的,所以可以在動畫播放控制元件上按下播放按鈕控制它。也可以通過該控制元件和時間線的加速、減速、逆向播放功能來控制動畫的狀態。
時間線(Timeline)為了讓場景中的動畫自動播放,可以用下面的程式碼來初始化Viewer
:
var viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate : true });
拾取
和Cesium的所有圖元一樣, 如果模型被選中了,那麼 Scene.pick
的返回值將包括 Model
類的例項。同時,glTF中的節點(node)id 和 三角網(mesh)id 也會被返回。用這個可以判定精確的模型點選部位。下面的程式碼在控制檯輸出了滑鼠所在位置對應的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) && Cehack.mesh)) { console.log('node: ' + pick.node.name + '. mesh: ' + pick.mesh.name); } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE );
把 COLLADA(dae)轉 glTF
可以使用Cesium的 線上工具. 把 .dae
和圖片檔案轉為一個內嵌圖片資源的.gltf
檔案。
問題
如果Cesium載入三維模型有問題,那麼首先定位問題出現在哪個階段:
- Max,Maya, Modo, SketchUp 等建模工具的 COLLADA 匯出器有沒有問題
- COLLADA-to-glTF轉換工具有沒有問題
- Cesium glTF 渲染程式碼有沒有問題
Mac 上解決問題
在Mac系統上,判定一個COLLADA 檔案是否匯出正常,雙擊.dae
檔案,它應該會顯示在預覽視窗上。如果模型帶動畫,那麼滑鼠移動到這個視窗上會顯示一個動畫控制的工具欄。
如果COLLADA 檔案有問題,那麼預覽介面會提示錯誤。這一般是由於建模工具的匯出器有bug。
模型預覽錯誤為了解決這個問題,安裝 Xcode,然後右鍵單機這個.dae
檔案,選擇 Open With -> Xcode
。
Xcode 如同預覽視窗一樣顯示模型,但是它有更多額外功能,比如選擇一個獨立的節點。Xcode實際上對於預覽視窗上顯示不了的dae有很多解決辦法。如果模型可以在Xcode 中載入,那麼選擇
File - Save
儲存一下就能解決問題,這時候預覽就沒有問題了。
Xcode中展示
如果還是無法預覽,那就是COLLADA 匯出器有嚴重問題了。首先確認你使用的最新版的建模工具,然後試下 這篇文章。如果還不能解決,那麼給建模工具提bug去吧。也可以試下先匯出
.fbx
格式,然後在其他工具中匯入fbx,再匯出dae。
Windows 上解決問題
Windows上,VS2013(包括免費的社群版本)包含一個模型編輯器,他可以載入COLLADA模型。判斷一個COLLADA檔案是否匯出正常,把 .dae
檔案拖拽到VS窗口裡,如果正常顯示,就是正常的。否則,可能有一些bug。試下 這篇文章。果還不能解決,那麼給建模工具提bug去吧。也可以試下先匯出.fbx
格式,然後在其他工具中匯入fbx,再匯出dae。
Visual Studio
如果你沒有Visual Studio,Autodesk 提供了一個基於WebGL的 視覺化工具 。可以把模型拖拽進去,無需登陸就能測試。但是這個工具不支援動畫,如果模型包含圖片,那麼上傳一個zip壓縮包,把dae和圖片都打進去。
Cesium 上解決問題
COLLADA 檔案準備好之後,那麼使用[線上工具 ] (https://cesiumjs.org/convertmodel.html)轉下格式再在Cesium中載入。如果沒於載入成功,那麼說明這個轉換工具或者Cesium有bug。為了獲取更多資訊,開啟瀏覽器的除錯工具 (Chrome快捷鍵Ctrl-Shift-I ) ,並且選中 Pause on all exceptions
(Chrome在 Sources
面板裡 ), 然後重新整理頁面.
也可以在Cesium論壇 上發一個帖子,我們修正bug後會提供一個解決方法。如果你發帖子,請包含下面內容:
- COLLADA 原始檔 和轉換後的 glTF檔案。我們也知道不是所有人都願意共享它的模型資料,但是如果你共享了,那麼對於解決問題很有幫助。
- 當模型載入的時候 瀏覽器控制檯視窗輸出的所有異常資訊 。
其他資源
再看下Sandcastle 中 3D models 示例。 Model 類和ModelAnimationCollection類的官方文件。
中國最專業的Cesium開發者社群