Cesium 之实现房屋模型拆解
本文按照mars3d提供的在线例子,自己实现了类似功能。
模型的拆解其实是将模型组装的各个部分模块以延迟动画方式进行位置重置,从而能够单独浏览,更直观的看到内部结构。
实现思路很简单
1、模型的加载
使用primitives 加载模型
2、通过modelMatrix控制位置
直接上代码,可根据实际需求自行扩展。
JS
/** @Descripttion: * @version: * @Author: xiongz* @Date: 2022-05-12 11:31:46* @LastEditors: Please set LastEditors* @LastEditTime: 2022-05-12 19:37:04*/
///
// 模块描述:房屋模型移动拆分
///
define(["dojo/_base/declare","dojo/_base/lang",'dojo/_base/html',"dojo/_base/fx",'jimu/BaseWidget',
], function (declare,lang,html,fx,BaseWidget
) {return declare("jimu.widget.ModelSplit", [BaseWidget], {baseClass: "jimu-widget-ModelSplit",name: 'ModelSplit',models: [],point: null,timers: [],floorCount: 6,floorScale: 1,floorHeight: 3, // 不缩放情况下楼层高度point: {lng: 115.91455928461914,lat: 28.665192693562243,height: 0},postCreate: function () {this.inherited(arguments);},destroy: function () {this.inherited(arguments);},startup: function () {this.inherited(arguments);topic.subscribe("runMap3DWidget", lang.hitch(this, function (name) {if (name == this.name) {this.initModel();$(`.${this.baseClass}`).show()}}));topic.subscribe("clearMap3DWidget", lang.hitch(this, function(name){if(name!=this.name){this.clearAll()}}));let that = this;$('.floorWhole >button').on('click', function () {let index = $(this).index();// 全部展开if (index == 0) {that.opeAll(4, 3000, 100)}// 全部合并else if (index == 1) {that.unionAll(4, 3000, 100)}// 全部还原else if (index == 2) {that.resetAll()}})$('.floorSingle >button').on('click', function () {let index = $(this).index();let maxHeight = that.point.height + (that.floorCount + 1) * that.floorScale// 楼层查看that.openFloorModel(maxHeight, index + 1)})$('.modelfile-th .xx').on('click',function(){that.clearAll();})},initModel:function(){let model = null;let floorCount = this.floorCount; // 房屋总楼层数,不含楼顶let floorScale = this.floorScale; // 房屋缩放比例,默认一般1let floorHeight = this.floorHeight; // 每层的高度let point = this.point;for (let i = 0; i <= floorCount; i++) {if (i < floorCount) {// 底楼let height = point.height + i * floorHeight * floorScale;model = this.addModePrimitive({position: [point.lng, point.lat, height],url: './widgets/ModelSplit/data/floor.glb',name: 'fw',scale: floorScale})model.option = {oriHeight: height,scale: floorScale,currentHeight:height}this.models.push(model)} else {// 顶楼let height = point.height + i * floorHeight * floorScale;model = this.addModePrimitive({position: [point.lng, point.lat, height],url: './widgets/ModelSplit/data/top.glb',name: 'fw',scale: floorScale})model.option = {oriHeight: height,scale: floorScale,currentHeight:height}this.models.push(model)}}window.viewer.camera.flyTo({destination : Cesium.Cartesian3.fromDegrees(115.91326536913103, 28.66495725572756, 55.24826616710503,),orientation : {heading : Cesium.Math.toRadians(78.06653423571397),pitch : Cesium.Math.toRadians(-15.156766587402164),roll : 0}});},clearAll:function(){if(this.models.length>0){this.models.forEach(m=>{window.viewer.scene.primitives.remove(m)})}$('.jimu-widget-ModelSplit').hide()},opeAll: function (height, time = 4000, interval = 100) {this.resetAll();let point = this.point; //楼栋位置this.clearFloorTimers()for (let i = 0; i < this.models.length; i++) {let model = this.models[i]let changeRate = Number((i * height * model.option.scale)) * (interval / time)// let alt = i * height * model.option.scale + model.option.oriHeight;if (i != 0) {// model.position = new Cesium.CallbackProperty(function () {// let height = model.option.oriHeight + (i * height * model.option.scale) / time// if (height < alt) {// return Cesium.Cartesian3(model.position[0], model.position[1], height)// } else {// return Cesium.Cartesian3(model.position[0], model.position[1], alt)// }// }, false)let count = 1;let timer = setInterval(function () {let add = model.option.oriHeight + changeRate * (count++)var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, add);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;if (count >= (time / interval)) {model.option.currentHeight=add;clearInterval(timer)timer = null;}// console.log(count)}, interval)this.timers.push(timer)}}},unionAll: function (height, time = 4000, interval = 100) {let point = this.point; //楼栋位置this.clearFloorTimers()for (let i = 0; i < this.models.length; i++) {let model = this.models[i];// 如果是初始位置,代表已经为合并状态。if(model.option.currentHeight==model.option.oriHeight){continue;}let currentHeight = model.option.oriHeight + (i * height * model.option.scale);let changeRate = Number((i * height * model.option.scale)) * (interval / time)model.show = true;let count = 1;let timer = setInterval(function () {let add = currentHeight - changeRate * (count++)var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, add);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;if (count >= (time / interval)) {var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, model.option.oriHeight);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;model.option.currentHeight=model.option.oriHeightclearInterval(timer)}}, interval)this.timers.push(timer)}},resetAll: function () {this.clearFloorTimers()let point = this.point; //楼栋位置for (let i = 0; i < this.models.length; i++) {let model = this.models[i];var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, model.option.oriHeight);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.option.currentHeight=model.option.oriHeightmodel.modelMatrix = modelMatrix;model.show = true;}},/*** 显示指定楼层** @param {Number} maxHeight 指定从顶部落下的高度* @param {Number} floorNum 指定显示的楼层,第1层开始* @param {Number} [time=1000] 楼层下落需要时间,单位:毫秒* @param {Number} [interval=100] 楼层下落触发间隔时间,单位:毫秒* @return {void} 无*/openFloorModel: function (maxHeight = 120, floorNum, time = 1000, interval = 100) {this.clearFloorTimers();floorNum--;let point = this.point; //楼栋位置for (let i = floorNum; i < this.models.length; i++) {let model = this.models[i];var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, model.option.oriHeight + maxHeight);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;model.show = false;model.option.currentHeight=model.option.oriHeight + maxHeight}for (let j = 0; j <= floorNum; j++) {let model = this.models[j];// 如果是初始位置,代表已经为合并状态。model.show = true;if(model.option.currentHeight==model.option.oriHeight&&j!=floorNum){continue;}let currentHeight = model.option.oriHeight + maxHeight;let changeRate = maxHeight * (interval / time)let count = 1;let timer = setInterval(function () {let add = currentHeight - changeRate * (count++)var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, add);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;if (count >= (time / interval)) {var origin = Cesium.Cartesian3.fromDegrees(point.lng, point.lat, model.option.oriHeight);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);model.modelMatrix = modelMatrix;model.option.currentHeight=model.option.oriHeightclearInterval(timer)}}, interval)this.timers.push(timer)}},clearFloorTimers: function () {if (this.timers.length > 0) {this.timers.forEach(t => {if (t) {clearInterval(t)}})}this.timers = [];},// 3d模型addModePrimitive: function (option) {var origin = Cesium.Cartesian3.fromDegrees(option.position[0], option.position[1], option.position[2]);var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(origin);var modelPrimitive = null;modelPrimitive = window.viewer.scene.primitives.add(Cesium.Model.fromGltf({url: option.url,modelMatrix: modelMatrix,show: true, // defaultscale: option.scale || 1, // double size// minimumPixelSize : 128, // never smaller than 128 pixelsmaximumScale: 20000, // never larger than 20000 * model size (overrides minimumPixelSize)allowPicking: true,// heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,scene: viewer.scene}));modelPrimitive.name = option.name;modelPrimitive.type = "model"if (option.rotationz) {var mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(option.rotationz));var rotationz = Cesium.Matrix4.fromRotationTranslation(mz);//旋转、平移矩阵相乘Cesium.Matrix4.multiply(modelMatrix, rotationz, modelMatrix);modelPrimitive.modelMatrix = modelMatrix}modelPrimitive.readyPromise.then(function (model) {// Play all animations when the model is ready to rendermodel.activeAnimations.addAll({speedup: 0.5,loop: Cesium.ModelAnimationLoop.REPEAT});});return modelPrimitive;}});
});
html
<div><div class="model-Split"><div class="modelfile-th"><!--<i class="i"></i>--><span class="tsls">房屋拆解</span><span class="xx"><i class="layui-icon">ဆ</i></span></div><div class="modelfile-td"><div class="infoview"><div class="floorWhole">整体控制:<button class="btn btn-primary">展开</button><button class="btn btn-primary">合并</button><button class="btn btn-primary">还原</button></div><div class="floorSingle">显示指定:<button class="btn btn-primary">一楼</button><button class="btn btn-primary">二楼</button><button class="btn btn-primary">三楼</button><button class="btn btn-primary">四楼</button><button class="btn btn-primary">五楼</button><button class="btn btn-primary">六楼</button><button class="btn btn-primary">顶楼</button></div></div></div></div>
</div>
结果展示:
https://live.csdn.net/v/210549
Cesium 之实现房屋模型拆解相关推荐
- cesium加载 gltf模型
cesium加载 gltf模型 首先自己配置一个iis环境 :http://www.xitongcheng.com/jiaocheng/win10_article_60912.html,其他环境 比如 ...
- cesium加载批量模型
cesium加载批量模型 class CreateModel {constructor() { }// 添加单条数据addEntity(item) {// 删除实体// viewer.entities ...
- Cesium中添加entitie模型,实现贴地。
1.Cesium中添加entitie模型,实现贴地. 2. 添加模型 const createModel = (url) => {const entity = viewer.entities.a ...
- 街道道路模型,高架桥模型,摊位模型,毁坏房屋模型等等
街道道路模型,高架桥模型,摊位模型,毁坏房屋模型等等 点我下载资源
- Cesium基础知识-创建模型,动画
viewer = new Cesium.Viewer('cesiumContainer' /* ,{ shouldAnimate : true }*/ ); //创建3d模型 function Cre ...
- AISAS模型拆解营销,抓住用户决策的每一步
AISAS模型拆解营销,抓住用户决策的每一步 AISAS模型是一种用户决策分析模型,由电通公司提出.这个模型是基于AIDMA模型,是消费者行为学领域很成熟的理论模型之一. 这个模型的理论认为消费者从接 ...
- Cesium加载3Dtiles模型-大疆智图
Cesium加载3Dtiles模型 Cesium加载3Dtiles模型步骤: (一)如果您使用的是大疆智图,则该软件可以直接输出3Dtiles格式(B3DM切片)的数据,如图所示: var viewe ...
- 增长模型拆解:分享有礼裂变玩法的底层逻辑与细节设计
自从转型运营,就一直做裂变和转介绍业务,虽然一直输出关于这两个用户增长模型的认知和运营经验,但实际从未系统地对"分享"这个行为进行系统解读. 分享是非常简单的,比如群裂变,转发海报 ...
- Cesium加载建筑物模型(shp转Geojson\3Dtiles)
本文主要介绍cesium加载Geojson和3dtile格式的建筑物模型文件,除此之外还介绍了Cesium工具栏的屏蔽方法.天地图的加载.地球初始状态设置等几个部分的内容,其中又不乏参照.优化诸如: ...
- cesium加载BIM模型
自己尝试用cesium引擎加载BIM模型,操作步骤如下: 第一步: 下载一个BIM模型 第二步: 将BIM模型转换成FBX格式 转成gltf格式 在如下网站进行转换: https://products ...
最新文章
- idea卸载不干净怎么办_挡风玻璃总是洗不干净,该怎么办
- 【数据结构】八大数据结构分类
- 557. 反转字符串中的单词 III
- 基于 LiteSpeed 的一站式 PHP 网站解决方案 LLStack V1.0-1 发布
- 设计一套基于NHibernate二级缓存的MongoDB组件(上)
- pyqt5 getsavefilename 默认文件名_经Jerry编程小课堂之python如何安装PyQt5和QT Designer...
- 如何在Mac上的Safari浏览器中输入画中画视频?
- velocity 语法
- 一款功能强大、高颜值、官方出品的Redis可视化工具
- OneDrive免费5T云盘空间
- steam显示网页错误怎么办?
- Xilinx FPGA的DNA是什么?
- 清除电脑缓存的bat文件
- 【内推】阿里云 云原生团队 2022 届秋招
- 极光笔记 | 极光推送业务无中断迁移上云实践
- 研究生学php丢不丢人,研究生压力过大?导师给研究生朋友的一些建议
- 《浪潮之巅》——吴军
- 大数据处理问题及解决方法
- C/S客户端渗透测试(一)客户端渗透环境配置
- 游戏开发unity杂项知识系列:合理使用Unity的AssetStore