Cesium案例解析(四)——3DModels模型加載

1. 概述

Cesium自帶的3D Models示例,展現瞭如何加載glTF格式三維模型數據。glTF是爲WebGL量身定製的數據格式,在網絡環境下有本身的優勢。能夠在Cesium的源碼包中找到一些該類型的數據。css

2. 代碼

HTML頁面3DModels.html代碼以下: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以下:java

"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();  
}

運行效果以下:網絡

Cesium加載模型

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對象:ui

Cesium.Entity參數

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

Cesium.ModelGraphics參數

參數minimumPixelSize表示模型縮小到多少像素後,再也不能被縮小。scala

maximumScale這個參數就有點很差理解了,文檔描述爲模型的最大比例尺寸,minimumPixelSize的最大上限。從實際表現上來看,應該表示的就是,縮放時保持模型保持必定的尺度不變,可是不能保持永遠不變,當縮放必定的尺度後,就會縮放一塊兒變小。這個值就是第二次縮放時的尺度。code

模型的位置以及方位參數是有外部的Cesium.Entity來決定的。position是其位置信息,orientation是方位信息,這裏有點像給Camera設置參數的部分,只不過傳入的方位參數經過headingPitchRollQuaternion進一步轉換成了四元數。

另一個值得關注的點就是,從文檔中能夠看出不少options對象的鍵值實際上是Property類型,或者是與Property相關的類型。這裏面其實包含了Cesium的Property機制,簡單來講就是這些值能夠與時間相關聯,在不一樣的時間能夠動態地返回不一樣的屬性值,可以數據驅動,實時動態三維展現。這個Property機制,值得進一步研究。

4. 參考

[1] SuperMap iClient3D for WebGL教程(Entity)-ModelGraphics
[2] Cesium的Property機制總結

相關文章
相關標籤/搜索