使用Cesium加载并调整3D Tiles

简书不活跃,知乎可以捉住我,上面有动画效果展示。

3dtiles简介

3D Tiles是用于流式传输大规模异构3D地理空间数据集的开放规范。为了扩展Cesium的地形和图像流,3D Tiles将用于流式传输3D内容,包括建筑物,树木,点云和矢量数据。
3D Tiles是目前大火的开源WebGL框架Cesium的御用格式。根据实际体验,3D Tiles和二维地图中的瓦片组织非常相似,在网络中查看3D模型的话,3DTiles的效果还是很不错的,下面我们就来讲一下如何使用vue框架实现cesium加载3dtiles,以及实现对3dtiles的调整组件。

cesium加载3dtiles

cesium加载3dtiles非常简单,调用primitive的add方法即可将3dtiles加载到数字地球上了,代码如下:

    var tilesetModel = new Cesium.Cesium3DTileset({
      url: "./大桥7/tileset.json"
    });
viewer.scene.primitives.add(tilesetModel);

需要注意的是:

  1. 3dtiles文件生成时本身就具有位置和高度(此模型是使用BimAngle转换)
  2. 由于生成3dtiles文件时使用的底图和地形和cesium加载的可能不同,再加上人工调整模型位置具有一定的偏差,所以3dtiles模型加载到数字地球上之后,可能需要再次调整位置,所以最好有前端调整工具去进行模型位置的调整,下文会实现这一功能

调整3dtiles位置,包括平移、旋转、缩放、地下可视化

调整3dtiles基本思路为:

  1. 设置3dtiles贴地形放置以及初始位置
  2. 前端设置input range组件,方便模型的调整

第一步"设置初始位置"的代码:

tilesetModel.readyPromise
  .then(function(currentModel) {
    var scene = window.earth.scene;
    var globe = scene.globe;
    //开启地下可视化
    scene.screenSpaceCameraController.enableCollisionDetection = false;
    globe.translucency.frontFaceAlphaByDistance = new Cesium.NearFarScalar(
      1000.0,
      0.0,
      2000.0,
      1.0
    );
    globe.translucency.enabled = true;
    window.tileModel = currentModel;
    scene.globe.depthTestAgainstTerrain = true;
    viewer.zoomTo(
      currentModel,
      new Cesium.HeadingPitchRange(-0.5, -0.5, 800)
    );
    var boundingSphere = currentModel.boundingSphere;
    var cartographic = Cesium.Cartographic.fromCartesian(
      boundingSphere.center
    );
    //获取模型中心点经纬度坐标
    that.tileModelTool.longitude =
      (cartographic.longitude / Math.PI) * 180;
    that.tileModelTool.latitude =
      (cartographic.latitude / Math.PI) * 180;
    that.tileModelTool.height = cartographic.height;

    //修改3dtiles位置,input,range组件的change事件绑定此函数
    that.update3dtilesMaxtrix();

    //模型点击事件
    attachTileset(viewer, currentModel);
    that.tileModelToolVisiable = true; //显示3dtiles调整工具
  })
  .otherwise(function(error) {
    new Error(error);
  });

代码中需要注意的有以下几点:

  1. scene.globe.depthTestAgainstTerrain = true;开启地形检测,若不开启地形检测,导致3dtiles模型始终悬浮在地形之上,在调整数字地球视角的时候,会导致3dtiles模型的位置有偏移
  2. window.tileModel = currentModel; 由于需要将3dtiles模型的实例赋值到一个全局变量中,方便其他方法调用,注意不可将实例赋值给vue的data中,由于vue data中的数据会进行数据劫持,所以赋值给vue的data会导致数字地球变的非常卡,关于vue的数据劫持,点击这里查看
  3. 开启地形可视化为cesium1.68版本添加的功能,要添加此功能需要使用高于1.68的版本,点击这里下载

第二步“前端调整工具“的代码:

<div class="tileModelTool" v-if="tileModelToolVisiable">
  <p>比例:</p>
  <el-input-number
    v-model="tileModelTool.scale"
    label="描述文字"
    @change="update3dtilesMaxtrix()"
    :step="0.1"
  ></el-input-number>
  <p>位置:</p>
  <p>经度:</p>
  <el-input-number
    v-model="tileModelTool.longitude"
    label="描述文字"
    @change="update3dtilesMaxtrix()"
    :step="0.00001"
  ></el-input-number>
  <p>纬度:</p>
  <el-input-number
    v-model="tileModelTool.latitude"
    label="描述文字"
    @change="update3dtilesMaxtrix()"
    :step="0.00001"
  ></el-input-number>
  <p>高度:</p>
  <el-slider
    v-model="tileModelTool.height"
    @input="update3dtilesMaxtrix"
    :min="-100"
    :max="1000"
  ></el-slider>
  <p>以x轴旋转</p>
  <el-slider v-model="tileModelTool.rx" @input="update3dtilesMaxtrix" :min="-100" :max="100"></el-slider>
  <p>以y轴旋转</p>
  <el-slider v-model="tileModelTool.ry" @input="update3dtilesMaxtrix" :min="-100" :max="100"></el-slider>
  <p>以z轴旋转</p>
  <el-slider v-model="tileModelTool.rz" @input="update3dtilesMaxtrix" :min="-100" :max="100"></el-slider>

  <p>透明度</p>
  <el-slider
    v-model="tileModelTool.alpha"
    @input="update3dtilesMaxtrix"
    :min="0"
    :max="1"
    :step="0.1"
  ></el-slider>
</div>
  tileModelTool: {
    scale: 1.0,
    longitude: 0,
    latitude: 0,
    height: 419, //修改高度
    rx: 0,
    ry: 0,
    rz: 33.5, //修改旋转
    alpha: 0.5
  }
    update3dtilesMaxtrix() {
      var mx = Cesium.Matrix3.fromRotationX(
        Cesium.Math.toRadians(this.tileModelTool.rx)
      );
      var my = Cesium.Matrix3.fromRotationY(
        Cesium.Math.toRadians(this.tileModelTool.ry)
      );
      var mz = Cesium.Matrix3.fromRotationZ(
        Cesium.Math.toRadians(this.tileModelTool.rz)
      );
      var rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
      var rotationY = Cesium.Matrix4.fromRotationTranslation(my);
      var rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
      //平移 修改经纬度
      var position = Cesium.Cartesian3.fromDegrees(
        this.tileModelTool.longitude,
        this.tileModelTool.latitude,
        this.tileModelTool.height
      );
      var m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
      //旋转、平移矩阵相乘
      Cesium.Matrix4.multiply(m, rotationX, m);
      Cesium.Matrix4.multiply(m, rotationY, m);
      Cesium.Matrix4.multiply(m, rotationZ, m);
      //缩放 修改缩放比例
      var scale = Cesium.Matrix4.fromUniformScale(this.tileModelTool.scale);
      Cesium.Matrix4.multiply(m, scale, m);
      //赋值给tileset
      window.tileModel._root.transform = m;
      //调整地下透明度
      viewer.scene.globe.translucency.frontFaceAlphaByDistance.nearValue = Cesium.Math.clamp(
        this.tileModelTool.alpha,
        0.0,
        1.0
      );
    }

使用elementui的组件inputrange,绑定其change事件为改变3dtiles的函数即可。cesium加载3dtiles还有很多其他的配置和效果,想要学习更多的配置和技巧,请配合cesium的沙盒学习相关的代码.
本文点击3dtiles模型显示信息框的函数代码暂未提供,即上文的 attachTileset(viewer, currentModel) 函数,如需要此部分代码,请先关注作者然后私聊获取。如有疑问欢迎评论区交流,如本文对你有帮助,不要忘记点赞收藏或转发

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343