• 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)], // 由点构线
             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在内存使用上就稍微弱了。

     

  • 相关阅读:
    从搜索引擎角度看SEO
    关键词排名与网站优化有哪三大误区?
    真正提升关键词排名的外链应该怎样发?
    高质量外链的十大特性
    四个方面分析SEO如何提高网站的权重
    Linux(ubuntu)使用dd从iso制作win7安装u盘(读卡器一样),以及备份分区
    折腾slidingmenu
    生命游戏介绍
    21232f297a57a5a743894a0e4a801fc3
    final关键字
  • 原文地址:https://www.cnblogs.com/CreateFree/p/11243744.html
Copyright © 2020-2023  润新知