C2——裁切面3Dtiles的例子

例子:裁剪面对模型进行裁切:裁切面有一个法向量表明面的哪一侧被裁切,有一个距离值指定裁切面距离待裁切对象中心点的位置

裁剪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();

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值