Cesium 中包含两种添加 model 的方法,分别为:javascript
viewer.entities.add()
函数添加viewer.scene.primitives.add()
函数添加两种方法本质上是相通的,方法 1
对方法 2
在某种程度上进行了封装。java
方法 1
经过指定 model 的 position 和 orientation 来控制模型的位置,对模型进行精确变换的难度较大;方法 2
经过 modelMatrix 控制模型的位置和方向,可进行较为精确的模型变换。方法 1
提供了较为方便的 viewer.trackedEntity 函数;方法 2
追踪 model 较为复杂,须要手动操做相机变换。方法 1
须要修改 object.id(Entity 类型) 中 model(ModelGraphics 类型) 的 scale 和 nodeTransformations;方法 2
能够直接修改 object.primitive(model 类型) 中的 scale 和 modelMatrix。分别使用方法 1
和方法 2
创建两个模型,而后对其进行点击操做,查看点击获得的物体,方法 1
和方法 2
返回的都为一样的 object 对象,其结构以下所示。node
{ id: object mesh: ModelMesh node: ModeNode primitive: Model }
其不一样的是,方法 2
中的 id 对象为用户自定义对象,方法 1
中的 Entity 对象。所以方法 1
至关于首先经过 方法 2
中的 Cesium.Model.fromGltf() 函数创建 Model,经过该 Model 创建对应的 Entity(方法暂何尝试,由于 Entity 构造函数中的 options.model 接收的是 ModelGraphics 类型,而不是 Model 类型),将 Entity 赋予对象的 id 属性,实现双向绑定,具体的实现可能要参考 viewer.entities.add() 的源码实现。函数
function getModelForEntity(entity) { var primitives = viewer.scene.primitives; for (var i = 0; i < primitives.length; i++) { var primitive = primitives.get(i); if (primitive instanceof Cesium.Model && primitive.id === entity) { return primitive; } } };
构建的对象中还包含 ModelMesh 和 ModeNode,ModelMesh 中包含了模型的网格和材质,ModeNode 中包含了一个 transform,能够在运行时对模型进行动态变换,以实现自定义模型动画。oop
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; }
function createModel(url, height, heading, pitch, roll) { height = Cesium.defaultValue(height, 0.0); heading = Cesium.defaultValue(heading, 0.0); pitch = Cesium.defaultValue(pitch, 0.0); roll = Cesium.defaultValue(roll, 0.0); var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); var origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height); var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, hpr); scene.primitives.removeAll(); // Remove previous model model = scene.primitives.add(Cesium.Model.fromGltf({ url : url, modelMatrix : modelMatrix, minimumPixelSize : 128 })); model.readyPromise.then(function(model) { model.color = Cesium.Color.fromAlpha(getColor(viewModel.color), Number(viewModel.alpha)); model.colorBlendMode = getColorBlendMode(viewModel.colorBlendMode); model.colorBlendAmount = viewModel.colorBlendAmount; // Play and loop all animations at half-speed model.activeAnimations.addAll({ speedup : 0.5, loop : Cesium.ModelAnimationLoop.REPEAT }); var camera = viewer.camera; // Zoom to model var controller = scene.screenSpaceCameraController; var r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near); controller.minimumZoomDistance = r * 0.5; var center = Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, new Cesium.Cartesian3()); var heading = Cesium.Math.toRadians(230.0); var pitch = Cesium.Math.toRadians(-20.0); camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)); }).otherwise(function(error){ window.alert(error); }); }