cesium 学习(五) 加载场景模型

cesium 学习() 加载场景模型

一、前言

  现在开始实际的看看效果,目前我所接触到基本上都是使用Cesium加载模型这个内容,以及在模型上进行操作。So,现在进行一些加载模型的学习,数据的话可以去网上找,因为目前使用的都是需要保密的数据,所以不能发在网上。

二、加载Entity类型模型

  说到加载Entity模型,内容就有点多了,cesium场景中的点、线、面、label以及模型(gltfglb);还有圆、墙体、方体、球等几何对象也都可以使用Entity来加载。下面分别加载试试看。

2.1加载点、线、面

var viewer = new Cesium.Viewer('cesiumContainer');  // 场景查看器对象
// 点的Entity 
var pointEntity = new Cesium.Entity({
    id: 'point', // id属性
    position: Cesium.Cartesian3.fromDegrees(103, 30, 10), // 位置
    point: {  //
        color: new Cesium.Color.fromCssColorString("#3388ff"), // 点颜色
        pixelSize: 10,  // 点大小
        outlineColor: new Cesium.Color.fromCssColorString("#ffffff"), // 点的外圈线颜色
        outlineWidth: 2,  // 点的外圈线宽度
        disableDepthTestDistance: Number.POSITIVE_INFINITY  // 被遮挡是否可见(也就是将这个Entity在场景中置顶)
    }
});
// 线的Entity
var lineEntity = new Cesium.Entity({
    name: "line", // 线的name属性
    polyline: {  // 线
        positions: [Cesium.Cartesian3.fromDegrees(103, 30, 50), Cesium.Cartesian3.fromDegrees(104, 30, 50)], // 由点构线
        width: 5.0, // 线的宽度
        material: new Cesium.PolylineGlowMaterialProperty({
            color: Cesium.Color.GOLD,
        }), // 线的材质、样式
        depthFailMaterial: new Cesium.PolylineGlowMaterialProperty({
            color: Cesium.Color.GOLD,
        }),  // 视线被遮挡处的材质、样式(和上一个材质一样的话则就不会被遮挡,类似置顶效果)
    }
});
// 面的Entity,其他Entity属性可以自行查看API
var polygon = new Cesium.Entity({
    polygon: {
        height: 0.1,
        hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArrayHeights([103, 30, 10, 103, 40, 10, 104, 30, 10])),  // 面的顶点坐标集合
        material: new Cesium.Color.fromCssColorString("#FFD700").withAlpha(.2), // 材质样式
        perPositionHeight: true,  // 是否支持坐标高度  
    }
});
View Code

2.2加载label

  其实label一般和其他一起使用,比如点。

 1 var entity = viewer.entities.add({
 2     id: '123',
 3     position: Cesium.Cartesian3.fromDegrees(103, 30, 5),
 4     point: {
 5         color: new Cesium.Color.fromCssColorString("#3388ff"),
 6         pixelSize: 10,
 7         outlineColor: new Cesium.Color.fromCssColorString("#3388ff"),
 8         outlineWidth: 2,
 9         heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
10         disableDepthTestDistance: Number.POSITIVE_INFINITY
11     },
12     label: {
13         text: 'lable文本',
14         font: '10px sans-serif', // 字体
15         style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 样式
16         fillColor: Cesium.Color.WHITE, // 填充色
17         outlineWidth: 1,  // 字体外圈线宽度(同样也有颜色可设置)
18         verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 垂直位置
19         pixelOffset: new Cesium.Cartesian2(0, -15),  // 中心位置
20         disableDepthTestDistance: Number.POSITIVE_INFINITY
21     }
22 });
View Code

2.3加载model

  model类型的entity的资源可以是使用max等建模软件做的模型,然后转换成webgl加载的模型——gltfglb

1 var modelentity = viewer.entities.add({
2     name:'123',
3     description:"<div><img src='Build/Cesium/Assets/Images/cesium_credit.png' /><p>这是一辆大车!</div>", // 这是模型的描述属性,可以是html标签
4     position : Cesium.Cartesian3.fromDegrees(103, 30), 
5     model : {
6         uri : 'Models/GroundVehicle/GroundVehicle.glb' // 资源路径
7     }
8 });
View Code

 

三、加载Primitive类型模型

 

  Primitive类型的加载也是比较有趣的,在Entity中不好控制的一些属性,可以在Primitive中很好的控制,比如Entity没有加载完成事件,而Primitive有加载完成事件;entity只能加载一个对象,而Primitive可以一次加载多个对象。

  当然Entity类型也是有它独特的好处的,不然官方也不会将其制造出来,明显的就是Entity类封装了很多个几何对象,非常方便的绘制出几何对象来,而如果使用Primitive的话你需要懂的知识不少,比如几何对象的构造。

  回到Primitive上,它的好处是高效加载、灵活绘制;Primitive的加载机制要好于Entity,这点我没有去做详细测试,但是网上是有这个测试的;对于其灵活性,主要是它可以不仅是单个几何对象,可以是多个几何对象或是不规则的对象的绘制加载,这点Entity没法做。

  好,还是通过几个加载来认识下Primitive

3.1加载模型

 1 var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
 2     Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 0.0)
 3 );
 4 viewer.scene.primitives.add(Cesium.Model.fromGltf({    //fromGltf方法:从Gltf资源加载模型  
 5     url: 'Models/GroundVehicle/GroundVehicle.glb',
 6     modelMatrix: modelMatrix,
 7     // minimumPixelSize : 512,     
 8     // maximumScale : 200000   
 9 })
10 );
11 viewer.camera.flyTo({
12     destination: Cesium.Cartesian3.fromDegrees(-75.62898254394531, 40.02804946899414, 30.0)
13 });

 3.2加载动画模型 

 1 var controller = viewer.scene.screenSpaceCameraController;
 2 //中心点
 3 var center = new Cesium.Cartesian3();
 4 //模型的偏移参数
 5 var hpRoll = new Cesium.HeadingPitchRoll();
 6 //相机的偏移参数
 7 var hpRange = new Cesium.HeadingPitchRange();
 8 //初始位置
 9 position = Cesium.Cartesian3.fromDegrees(103, 30, 0.08);
10 //速度向量
11 var speedVector = new Cesium.Cartesian3();
12 //生成一个由两个参考系生成的矩阵
13 var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west');
14 //加载模型
15 peoPrimitive = scene.primitives.add(Cesium.Model.fromGltf({
16     //这里需要把模型路径改下(如果你用的还是HelloWord.html的话就用这个,不是的话请自行修改)
17     url: '../Models/GLTF/CesiumMan/Cesium_Man.glb',
18     modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform),
19     //minimumPixelSize: 128
20 }));
21 
22 //动画播放
23 peoPrimitive.readyPromise.then(function (model) {
24     // 以半速循环动画            
25     model.activeAnimations.addAll({
26         speedup: 1,
27         loop: Cesium.ModelAnimationLoop.REPEAT
28     });
29     //r=2*max(模型的半径,相机的最近距离)
30     r = 2.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
31     //镜头最近距离
32     controller.minimumZoomDistance = r * 0.5;
33     //计算center位置(也为下面的镜头跟随提供了center位置)
34     Cesium.Matrix4.multiplyByPoint(model.modelMatrix, model.boundingSphere.center, center);
35     //相机偏移角度
36     var heading = Cesium.Math.toRadians(0.0);
37     var pitch = Cesium.Math.toRadians(-20.0);
38     hpRange.heading = heading;
39     hpRange.pitch = pitch;
40     hpRange.range = r + 5;
41     //固定相机
42     camera.lookAt(center, hpRange);
43 });
View Code

3.3加载多个几何对象 

 1 var instances = [];
 2 var positions_l = [......];  // Cartesian3坐标集合
 3 positions_l.forEach(position => {
 4     instances.push(new Cesium.GeometryInstance({
 5         geometry: new Cesium.EllipseGeometry({
 6             center: position,
 7             semiMinorAxis: 0.024,
 8             semiMajorAxis: 0.024,
 9             height: 0,
10             extrudedHeight: height1,
11             material: Cesium.Color.GOLD,
12         }),
13         id: { guid: guid, jsj_name: name, name: '立杆' },
14         attributes: {
15             color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.GOLDENROD)
16         }
17     }));
18 });
19 // instances 就是很多个几何对象(这里是圆柱),然后后用primitive统一合并加载
20 var ganmodel = viewer.scene.primitives.add(new Cesium.Primitive({
21     geometryInstances: instances,
22     appearance: new Cesium.MaterialAppearance({
23         material: Cesium.Material.fromType('Color', {
24             color: Cesium.Color.GOLD
25         }),
26     }),
27 }));
View Code

四、总结

  Entity加载方式在一定程度上是比Primitive方式更加方便的,特别是Entity不仅可以加载点、线、面、标签、模型、几何对象,而且是可以同时加载比如点和标签一起加载,如果愿意可以使用一个Entity对象加载一个点、一条线、一个面、一个模型、多个不同的几何对象!当然Primitive方法也是可以的,不过就没有Entity这么方便了。

  Primitive主要是更偏底层一些,它可以使用Entity没有的一些属性,然后也更加灵活一些,比如我最后的添加多个立杆模型,Entity方法是没法构造一个Entity对象完成多个立杆的绘制的,有多少个立杆就得创建多少个Entity在内存使用上就稍微弱了。

 

posted @ 2019-07-25 13:42  CreateFree  阅读(4095)  评论(0编辑  收藏  举报