本人使用cesium版本依旧是1.6.1。
现阶段可以实现单面和多面(盒子)裁剪,不多说,直接上代码:
加载模型数据:
m_b3dm = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
type: "3dtiles",
url: RootURL + '/Datasource/Model/b3dm/tileset.json'
}));
viewer.zoomTo(m_b3dm);
单面切割:
var clippingPlanes = m_b3dm.clippingPlanes = loadClip();
var boundingSphere = m_b3dm.boundingSphere;
for (var i = 0; i < clippingPlanes.length; ++i) {
var plane = clippingPlanes.get(i);
var planeEntity = viewer.entities.add({ //添加平面实体 直观裁切面
id: '裁切面' + i,
position: boundingSphere.center,// offset, 根据3dtiles同步调整裁切面高度
plane: {
dimensions: new Cesium.Cartesian2(150, 150),//(radius * 2.5, radius * 2.5),
material: Cesium.Color.WHITE.withAlpha(0.0),
plane: new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false),
outline: true,
outlineColor: Cesium.Color.WHITE
}
});
}
方法补充:
function loadClip() {
clippingPlanes = new Cesium.ClippingPlaneCollection({
planes: [
new Cesium.ClippingPlane(new Cesium.Cartesian3(1.0, 0.0, 0), 0),
],
edgeColor: Cesium.Color.RED,
edgeWidth: 1.0,
unionClippingRegions: true, //true 才能多个切割
})
return clippingPlanes
}
function createPlaneUpdateFunction(plane) {
return function () {
if (window.localStorage.getItem('slider')) {
plane.distance = window.localStorage.getItem('slider');
return plane;
}
plane.distance = 0;
return plane;
};
}
var CreateSlider = function (f_id, left, top, max,localStoragename) {
var fEve = document.getElementById(f_id);
window.localStorage.setItem(localStoragename, 0);
var sliderDiv = document.createElement('div');
sliderDiv.style.position = 'absolute';
sliderDiv.style.left = left + 'px';
sliderDiv.style.top = top + 'px';
sliderDiv.style.zIndex = 99;
//滑动长条
var outerDiv = document.createElement('div');
outerDiv.style.position = 'absolute';
outerDiv.style.width = max + 'px';
outerDiv.style.height = '8px';
outerDiv.style.margin = '6px 0 0 0';
outerDiv.style.background = '#fff';
outerDiv.style.border = 'none';
outerDiv.style.borderRadius = '3px';
sliderDiv.appendChild(outerDiv);
//滑动条指针
var innerDiv = document.createElement('div');
innerDiv.style.position = 'absolute';
innerDiv.style.height = '20px';
innerDiv.style.width = '5px';
innerDiv.style.left = max / 2 + 'px';
innerDiv.style.background = 'chocolate';
innerDiv.style.border = '1px solid';
innerDiv.style.borderRadius = '3px';
sliderDiv.appendChild(innerDiv);
fEve.appendChild(sliderDiv);
function getPos(ev) {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
return { x: ev.clientX + scrollLeft, y: ev.clientY + scrollTop };
}
function getStyle(obj, name) {
if (obj.currentStyle) {
return obj.currentStyle[name];
}
else {
return getComputedStyle(obj, false)[name];
}
}
innerDiv.onmousedown = function (ev) {
var oEvent = ev || event;
var pos = getPos(oEvent);
var disx = pos.x - parseInt(getStyle(innerDiv, 'left'));
document.onmousemove = function (ev) {
var oEvent = ev || event;
var pos = getPos(oEvent);
var l = pos.x - disx;
if (l < 0) {
l = 0;
}
if (l > parseInt(getStyle(outerDiv, 'width')) - parseInt(getStyle(innerDiv, 'width'))) {
l = parseInt(getStyle(outerDiv, 'width')) - parseInt(getStyle(innerDiv, 'width'))
}
innerDiv.style.left = l + 'px';
window.localStorage.setItem(localStoragename, l - max / 2);
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
return false;
}
}
效果图:
多面(盒子)裁切 :
CreateSlider('MapContainer', 10, 10, 300, 'slider_x');
CreateSlider('MapContainer', 10, 60, 300, 'slider_y');
CreateSlider('MapContainer', 10, 110, 300, 'slider_z');
// return;
var clippingPlanes = m_b3dm.clippingPlanes = loadClip_box();
var boundingSphere = m_b3dm.boundingSphere;
// 创建一个坐标轴,便于测试
var transform = Cesium.Transforms.eastNorthUpToFixedFrame(boundingSphere.center);
var modelMatrixPrimitive = viewer.scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({
modelMatrix: transform,
length: 40.0
}));
var m_box;
for (var i = 0; i < clippingPlanes.length; ++i) {
var plane = clippingPlanes.get(i);
var getPlaneType = getType4Plane(plane);
var planeEntity = viewer.entities.add({ //添加平面实体 直观裁切面
id: 'ClipPlane' + i,
position: boundingSphere.center,// 根据3dtiles同步调整裁切面高度
plane: {
dimensions: new Cesium.Cartesian2(80, 80),//切面的长和宽
plane: new Cesium.CallbackProperty(createPlaneUpdateFunction_box(plane, getPlaneType, boundingSphere.center), false),
material: Cesium.Color.WHITE.withAlpha(0),
outline: false
}
});
if (!m_box) {
m_box = viewer.entities.add({
id: 'ClopBox',
modelMatrixPrimitive:modelMatrixPrimitive,
position: boundingSphere.center,
box: {
dimensions: new Cesium.Cartesian3(80, 80, 80),
material: Cesium.Color.RED.withAlpha(0.2),
}
})
}
}
方法补充:
//获取切面的type // 上、下、左、右、前、后
function getType4Plane(plane) {
var m_type;
var normal = plane._normal;
var x = normal.x;
var y = normal.y;
var z = normal.z;
if (x == 1 && y == 0 && z == 0) {
m_type = 'left';
}
else if (x == -1 && y == 0 && z == 0) {
m_type = 'right';
}
else if (x == 0 && y == 1 && z == 0) {
m_type = 'behind';
}
else if (x == 0 && y == -1 && z == 0) {
m_type = 'front';
}
else if (x == 0 && y == 0 && z == -1) {
m_type = 'top';
}
return m_type;
}
function loadClip_box() {
clippingPlanes = new Cesium.ClippingPlaneCollection({
planes: [
//前后切割
new Cesium.ClippingPlane(new Cesium.Cartesian3(0, 1, 0), 0), //后
new Cesium.ClippingPlane(new Cesium.Cartesian3(0, -1, 0), 0), //前
// 左右切割
new Cesium.ClippingPlane(new Cesium.Cartesian3(1.0, 0.0, 0), 0), //左
new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0, 0.0, 0), 0), //右
// 上下切割
new Cesium.ClippingPlane(new Cesium.Cartesian3(0, 0.0, -1), 0), //上→下
// new Cesium.ClippingPlane(new Cesium.Cartesian3(0, 0.0, 1), 0), //下→上
],
edgeColor: Cesium.Color.RED,
edgeWidth: 1.0,
unionClippingRegions: true, //true 才能多个切割
})
return clippingPlanes
}
function createPlanePos(origin, x, y, z) {
var clipbox=viewer.entities.getById('ClopBox');
if (clipbox) {
clipbox.position=new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegrees(origin[0] + x, origin[1] + y, +origin[2] + z);//实时返回当前盒子的位置
}, false);
}
}
function createPlaneUpdateFunction_box(plane, type, origin) {
return function () {
// plane.distance = 40;
var num_x = window.localStorage.getItem('slider_x') / 100000;
var num_y = window.localStorage.getItem('slider_y') / 100000;
var num_z = window.localStorage.getItem('slider_z')/1.5;//读取滑动条值
var origin_degree = cartesian3ToDegrees(origin);
var target_degree_x = [origin_degree[0] + num_x, origin_degree[1], +origin_degree[2]];
var target_degree_y = [origin_degree[0], origin_degree[1] + num_y, +origin_degree[2]];
var target_degree_z = [origin_degree[0], origin_degree[1], +origin_degree[2] + num_z];
var m_dis_x = Cesium.Cartesian3.distance(origin, Cesium.Cartesian3.fromDegrees(target_degree_x[0], target_degree_x[1], target_degree_x[2]));
var m_dis_y = Cesium.Cartesian3.distance(origin, Cesium.Cartesian3.fromDegrees(target_degree_y[0], target_degree_y[1], target_degree_y[2]));
var m_dis_z = Cesium.Cartesian3.distance(origin, Cesium.Cartesian3.fromDegrees(target_degree_z[0], target_degree_z[1], target_degree_z[2]));
createPlanePos(origin_degree, num_x, num_y, num_z);
if (type == 'left') {
if (num_x < 0) {
plane.distance = 40 - (-m_dis_x);
return plane;
} else {
plane.distance = 40 - m_dis_x
return plane;
}
}
else if (type == 'behind') {
if (num_y < 0) {
plane.distance = 40 - (-m_dis_y);
return plane;
} else {
plane.distance = 40 - m_dis_y;
return plane;
}
}
else if (type == 'right') {
if (num_x < 0) {
plane.distance = 40 - m_dis_x;
return plane;
} else {
plane.distance = 40 - (-m_dis_x);
return plane;
}
}
else if (type == 'front') {
if (num_y < 0) {
plane.distance = 40 - m_dis_y;
return plane;
} else {
plane.distance = 40 - (-m_dis_y);
return plane;
}
}
else if (type == 'top') {
if (num_z < 0) {
plane.distance = 40 - m_dis_z;
return plane;
} else {
plane.distance = 40 - (-m_dis_z);
return plane;
}
}
return plane;
};
}
效果图:
现阶段效果暂时先这样,如有问题或者建议欢迎提出.......