1. 程式人生 > >Cesium官方教程7--三維模型

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

的背後財團。Cesium提供了一個 線上的工具 ,可以把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.6289825439453140.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 選項,addAlladd 函式提供了一些列的引數選項,用來控制動畫的開始、結束、播放速度,以及播放方向。比如下面的程式碼設定動畫逆向按照半速(相對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 檔案,它應該會顯示在預覽視窗上。如果模型帶動畫,那麼滑鼠移動到這個視窗上會顯示一個動畫控制的工具欄。

  Mac 模型預覽視窗

如果COLLADA 檔案有問題,那麼預覽介面會提示錯誤。這一般是由於建模工具的匯出器有bug。

  模型預覽錯誤

為了解決這個問題,安裝 Xcode,然後右鍵單機這個.dae 檔案,選擇 Open With -> Xcode

  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面板裡 ), 然後重新整理頁面.

  Pause On All Exceptions

也可以在Cesium論壇 上發一個帖子,我們修正bug後會提供一個解決方法。如果你發帖子,請包含下面內容:

  • COLLADA 原始檔 和轉換後的 glTF檔案。我們也知道不是所有人都願意共享它的模型資料,但是如果你共享了,那麼對於解決問題很有幫助。
  • 當模型載入的時候 瀏覽器控制檯視窗輸出的所有異常資訊 。
  控制檯異常

其他資源

再看下Sandcastle 中 3D models 示例Model 類和ModelAnimationCollection類的官方文件。

  中國最專業的Cesium開發者社群