作者 Kele
前言
在三维项目中,BIM模型是非常常见的数据格式,BIM分层、BIM爆炸查看内部结构是三维系统常见的功能。对于BIM爆炸,我想大家都知道其实现原理是控制构件的偏移,然而要实现各个构件向四周发散型的爆炸效果,各个构件的偏移方向及偏移量该如何计算呢,接下来我向大家提供一种新的思路
一、实现思路
实现模型爆炸的核心接口是模型偏移,setBatchObjsTranslate
实现模型向四周爆炸效果,那么每个模型构建的偏移方向、偏移距离都会不同,我们按以下步骤实现
1.获取整个图层中心点
2.获取各个构建中心点
3.计算各个构建的偏移方向和偏移距离
4.实现偏移
二、数据准备
1.获取各个构建中心点
坐标系选择wgs84,该方法只能获取模型构建xy坐标,接下来获取模型构建z坐标
通过模型属性提取,获得最大最小高度,再通过计算平均值得到中心点z值(顶部高程 + 底部高程)/ 2,记得提前建好字段来保存z值
这样,我们就获取到各个构建的中心点坐标了
由于后面我们会通过数据服务查询的方式获取这些坐标,为了使查询更快,我们将模型的属性信息单独存为属性表,查询数据的时候查询这个属性表
2.模型数据生成缓存
将模型数据集添加到场景,保存场景,对场景生成缓存
缓存成功后,打开生成的工作空间,将数据源添加进来,确保当前工作空间有数据源和场景
发布数据服务和三维服务
三、WebGL实现步骤
1.获取图层中心点
function getLayerCenterPos() {
building = viewer.scene.layers.find('楼板_办公楼__@DatasourceYYD007');
if(building){
let cartographic = Cesium.Cartographic.fromCartesian(building._position);
let longitude = Cesium.Math.toDegrees(cartographic.longitude);
let latitude = Cesium.Math.toDegrees(cartographic.latitude);
let height = cartographic.height;
let layerCenterPos = Cesium.Cartesian3.fromDegrees(longitude,latitude,height);
return layerCenterPos
}
}
2.获取构建中心点
构建中心点坐标我们已经在上面处理好了,现在通过查询数据服务获取
function modelTranslate(layerCenterPos) {
let sqlParameter = {
toIndex: -1,
datasetNames: ["DatasourceYYD007:info"],
getFeatureMode: "SQL",
queryParameter: {
attributeFilter: "smid>=0"
}
};
let url = dataUrl;
let queryData = JSON.stringify(sqlParameter);
$.ajax({
type: "post",
url: url,
data: queryData,
success: function (result) {
let resultObj = JSON.parse(result);
for(let item of resultObj.features){
//构件中心点
let center = Cesium.Cartesian3.fromDegrees(Number(item.fieldValues[12]),Number(item.fieldValues[13]),Number(item.fieldValues[14]));
}
},
error: function (msg) {
console.log(msg);
},
})
}
3.通过图层中心点和各个构建中心点,计算偏移参数
//将图层中心点变换成4*4矩阵
let transform = Cesium.Transforms.eastNorthUpToFixedFrame(layerCenterPos);
let inverseTransform = Cesium.Matrix4.inverseTransformation(transform, {});
//计算图层中心点矩阵与构建中心点乘积,得到变换矩阵
Cesium.Matrix4.multiplyByPoint(inverseTransform, center, center);
//计算图层中心点与构建中心点距离
let distance = Cesium.Cartesian3.magnitude(center);
oExplode.directions.push(Cesium.Cartesian3.clone(center));
Cesium.Cartesian3.normalize(center, center);
oExplode.distances.push(distance);
oExplode.directions_normalize.push(center);
oExplode.ids.push(Number(item.fieldValues[0]));
4.执行偏移
Cesium.knockout.track(viewModel);
let toolbar = document.getElementById('toolbar');
Cesium.knockout.applyBindings(viewModel, toolbar);
Cesium.knockout.getObservable(viewModel, 'scale').subscribe(
function (newValue) {
let option = {};
for (let i = 0; i < oExplode.ids.length; i++) {
let currentTranslate = new Cesium.Cartesian3(
//新偏移量 = 原始偏移量*偏移比例*输入偏移值
oExplode.directions_normalize[i].x * oExplode.scale[i] * newValue,
oExplode.directions_normalize[i].y * oExplode.scale[i] * newValue,
oExplode.directions_normalize[i].z * oExplode.scale[i] * newValue
);
option[i] = currentTranslate
}
building.setBatchObjsTranslate(option)
}
);
四、效果展示
小提示:偏移接口底层优化过,需要结合最新WebGL包使用,demo和包获取地址:
链接:https://pan.baidu.com/s/15MDsElNVFaiTfkK5XZ6j5A
提取码:6655