Cesium 3D模型 - cytggit/Map-openlayers GitHub Wiki

介绍

Cesium仅支持glTF(一个新兴的Web 3D模型工业标准)格式的3D模型,并且提供在线的 COLLADA - glTF转换工具(输入、输出、工具必须在同一目录)。Cesium针对3D模型支持关键帧动画、皮肤、单独节点选取等特性。

例子

  • 一、官网例子

Cesium自带了三个模型:飞机、车辆、人。下面的例子载入一个车辆模型:

var scene = viewer.scene;  
//创建坐标  
var coord = Cesium.Cartesian3.fromDegrees( -75.62898254394531, 40.02804946899414, 0.0 );  
//创建一个东(X,红色)北(Y,绿色)上(Z,蓝色)的本地坐标系统  
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( coord );  
// 改变3D模型的模型矩阵,可以用于移动物体  
// 物体的世界坐标 = 物体的模型坐标 * 世界矩阵  
var model = scene.primitives.add( Cesium.Model.fromGltf( {//异步的加载模型  
    url : '../../SampleData/models/CesiumGround/Cesium_Ground.gltf',  
    modelMatrix : modelMatrix, //模型矩阵  
    scale : 200.0 //缩放  
} ) );  

Cesium自带的3个模型已经内嵌了动画关键桢,如果需要播放动画,可以在调用Model.fromGltf后添加以下代码:

Cesium.when( model.readyPromise ).then( function( model )  
{  
    model.activeAnimations.addAll( {//播放模型中全部动画,如果需要播放单个动画,可以调用add,传入动画id  
        loop : Cesium.ModelAnimationLoop.REPEAT, //直到被移出activeAnimations,一直播放  
         speedup : 0.5,  //加速播放  
         reverse : true  //逆序播放  
    } );  
} );  

动画与Cesium的时钟系统同步化。

与其它Primitive一样,对3D模型的选取也是被支持的,当前点击的glTF node id、glTF mess一并被获取:

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文件转换后的glTF载入

一个collada文件转换后结果有4个文件,一个.bin,一个.json,两个.glsl。.json文件是描述性的文件,.bin是实际的数据,两个glsl文件是顶点着色语言文件。把这些文件所在目录部署到web服务器上。

在client端添加:

var ellipsoid = viewer.scene.globe.ellipsoid;  
var cart3 = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, height));  
var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(cart3);  
var quat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, Cesium.Math.toRadians(rotate - 90));  
var mat3 = Cesium.Matrix3.fromQuaternion(quat);  
var mat4 = Cesium.Matrix4.fromRotationTranslation(mat3, Cesium.Cartesian3.ZERO);  
var m = Cesium.Matrix4.multiplyTransformation(modelMatrix, mat4);//获得最终变换矩阵,参考笔者前面写的《坐标变换》篇  
var model = viewer.scene.primitives.add(Cesium.Model.fromGltf({  
        url : 'http://localhost:88/gltf/tower.json',//转换后4个文件中的json文件
        modelMatrix : m,//添加模型的变换矩阵,才能显示在正确位置,否则打死也找不到,被放到地球的某个角落里
        scale:1.0//缩放倍数
}));  
//模型加载后,如果有动画就播放 
model.readyToRender.addEventListener(function(model){  
        // Play and loop all animations at half-spead
    model.activeAnimations.addAll({  
            speedup : 0.5,  
            loop : Cesium.ModelAnimationLoop.REPEAT  
    });  
});