例子:裁剪面对模型进行裁切:裁切面有一个法向量表明面的哪一侧被裁切,有一个距离值指定裁切面距离待裁切对象中心点的位置
裁剪BIM模型
1、裁剪面必须是一个集合
2、鼠标按下后需要禁止相机事件
3、用回调来刷新裁剪面的属性
const viewer = new Cesium.Viewer("cesiumContainer", {
infoBox: false,
selectionIndicator: false,
});
let scene = viewer.scene;
let targetY = 0.0; //记录裁剪面上下移动的值
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
// 左键按下判断是否选中裁剪面,选中就禁止相机所有事件
handler.setInputAction(function(movement) {
let pickedObject = scene.pick(movement.position);
if (Cesium.defined(pickedObject?.id?.plane)) {
let selectedPlane = pickedObject.id.plane;
selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.05);
selectedPlane.outlineColor = Cesium.Color.WHITE;
scene.screenSpaceCameraController.enableInputs = false;
// 鼠标松开恢复相机事件
handler.setInputAction(function() {
if (Cesium.defined(selectedPlane)) {
selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.1);
selectedPlane.outlineColor = Cesium.Color.WHITE;
selectedPlane = undefined;
}
scene.screenSpaceCameraController.enableInputs = true;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
// 鼠标移动,刷新裁剪面到中心点的距离值
handler.setInputAction(function(movement) {
if (Cesium.defined(selectedPlane)) {
let deltaY = movement.startPosition.y - movement.endPosition.y;
targetY += deltaY;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
function loadTileset() {
// 添加模型和裁剪面,裁剪面必须是一个集合
let plane_1 = new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0);
let clippingPlanes = new Cesium.ClippingPlaneCollection({
planes: [plane_1],
edgeWidth: 1.0,
});
let tileset = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: Cesium.IonResource.fromAssetId(8564),
clippingPlanes: clippingPlanes,
})
);
return tileset.readyPromise.then(function() {
let boundingSphere = tileset.boundingSphere;
let radius = boundingSphere.radius;
viewer.zoomTo(tileset,new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0));
// 裁剪面的几何举证
if (!Cesium.Matrix4.equals(tileset.root.transform, Cesium.Matrix4.IDENTITY)) {
let transformCenter = Cesium.Matrix4.getTranslation(
tileset.root.transform,
new Cesium.Cartesian3()
);
let transformCartographic = Cesium.Cartographic.fromCartesian(transformCenter);
let boundingSphereCartographic = Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);
let height = boundingSphereCartographic.height - transformCartographic.height;
clippingPlanes.modelMatrix = Cesium.Matrix4.fromTranslation(
new Cesium.Cartesian3(0.0, 0.0, height)
);
}
viewer.entities.add({
position: boundingSphere.center,
plane: {
dimensions: new Cesium.Cartesian2(radius*2.5,radius*2.5),
material: Cesium.Color.WHITE.withAlpha(0.1),
plane: new Cesium.CallbackProperty(() => {// 回调改变裁剪面
plane_1.distance = targetY;
return plane_1;
},
false//CallbackProperty返回的值是变化的false,不变的true
),
outline: true,
outlineColor: Cesium.Color.WHITE,
},
});
return tileset;
})
.catch((error) => {
console.log(error);
});
}
loadTileset();
裁剪地形
裁剪地面限定显示的范围
const viewer = new Cesium.Viewer("cesiumContainer", {
skyAtmosphere: false,
shouldAnimate: true,
terrainProvider: Cesium.createWorldTerrain(),
scene3DOnly: true,
});
let globe = viewer.scene.globe;
function loadGrandCanyon() {
let position = Cesium.Cartographic.toCartesian(new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100));
let distance = 3000.0;
let boundingSphere = new Cesium.BoundingSphere(position, distance);
globe.clippingPlanes = new Cesium.ClippingPlaneCollection({
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(position),
planes: [
new Cesium.ClippingPlane(
new Cesium.Cartesian3(1.0, 0.0, 0.0),
distance
),
new Cesium.ClippingPlane(
new Cesium.Cartesian3(-1.0, 0.0, 0.0),
distance
),
new Cesium.ClippingPlane(
new Cesium.Cartesian3(0.0, 1.0, 0.0),
distance
),
new Cesium.ClippingPlane(
new Cesium.Cartesian3(0.0, -1.0, 0.0),
distance
),
],
unionClippingRegions: true,
edgeWidth: 1.0,
edgeColor: Cesium.Color.WHITE,
enabled: true,
});
viewer.camera.viewBoundingSphere(
boundingSphere,
new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0)
);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}
loadGrandCanyon();