3dtiles 剖切
通过一个裁切平面进行 dtiles 的剖切,实现 3dtiles 的局部显示/隐藏,可以通过鼠标上下移动实现裁切平面位置的改变。
注册鼠标事件
实现移动平面实现裁切
注册鼠标按下事件
js
let _this = this
let selectedPlane
//鼠标按下时事件
const downHandler = new LSGlobe.ScreenSpaceEventHandler(
LSGlobe.Viewer.scene.canvas
)
downHandler.setInputAction(function (movement) {
const pickedObject = LSGlobe.Viewer.scene.pick(movement.position)
if (
LSGlobe.defined(pickedObject) &&
LSGlobe.defined(pickedObject.id) &&
LSGlobe.defined(pickedObject.id.plane)
) {
selectedPlane = pickedObject.id.plane //设置选中平面
selectedPlane.material = LSGlobe.Color.WHITE.withAlpha(0.05) //设置样式
selectedPlane.outlineColor = LSGlobe.Color.WHITE //设置样式
LSGlobe.Viewer.scene.screenSpaceCameraController.enableInputs = false //禁止相机活动
}
}, LSGlobe.ScreenSpaceEventType.LEFT_DOWN)
注册鼠标抬起事件
js
// 鼠标抬起事件
const upHandler = new LSGlobe.ScreenSpaceEventHandler(
LSGlobe.Viewer.scene.canvas
)
upHandler.setInputAction(function () {
if (LSGlobe.defined(selectedPlane)) {
selectedPlane.material = LSGlobe.Color.WHITE.withAlpha(0.1) //设置样式
selectedPlane.outlineColor = LSGlobe.Color.WHITE //设置样式
selectedPlane = undefined
}
LSGlobe.Viewer.scene.screenSpaceCameraController.enableInputs = true //启用相机活动
}, LSGlobe.ScreenSpaceEventType.LEFT_UP)
注册鼠标移动事件
js
// 鼠标移动事件
window.targetY = 0
const moveHandler = new LSGlobe.ScreenSpaceEventHandler(
LSGlobe.Viewer.scene.canvas
)
moveHandler.setInputAction(function (movement) {
if (LSGlobe.defined(selectedPlane)) {
const deltaY = movement.startPosition.y - movement.endPosition.y
window.targetY += deltaY //设置平面的偏移量
}
}, LSGlobe.ScreenSpaceEventType.MOUSE_MOVE)
加载模型
js
LSGlobe.Viewer.scene.globe.depthTestAgainstTerrain = true //启用深度检测
//加载3dtiles
const tileset = LSGlobe.Viewer.scene.primitives.add(
new LSGlobe.Cesium3DTileset({
url: ''
})
)
设置调整切面
对于 3dtiles,root tile 的 transform 被用来定位 clippingPlanes。
对于裁切平面,一般来说,剪裁平面的坐标是相对于它们所连接的对象而言的,所以一个距离设置为 0 的平面将通过对象的中心进行剪裁。
如果 3d tiles 没有定义 transform(没有定义时 root tile 的 transform 为单位矩阵即 LSGlobe.Matrix4.IDENTITY),则使用 root tile 的 Cesium3DTile#boundingSphere 代替。
js
tileset.readyPromise.then(function () {
//创建裁切平面
let clippingPlanes = new LSGlobe.ClippingPlaneCollection({
planes: [
new LSGlobe.ClippingPlane(new LSGlobe.Cartesian3(0.0, 0.0, -1.0), 0.0)
],
edgeWidth: 1.0
})
//设置倾斜模型的裁切平面
tileset.clippingPlanes = clippingPlanes
const { boundingSphere } = tileset
const { radius } = boundingSphere
//视野调整至倾斜模型处
LSGlobe.Viewer.zoomTo(
tileset,
new LSGlobe.HeadingPitchRange(0.5, -0.2, radius * 4.0)
)
// 强制模型贴地
const cartographic = LSGlobe.Cartographic.fromCartesian(
tileset.boundingSphere.center
)
//
if (
!LSGlobe.Matrix4.equals(tileset.root.transform, LSGlobe.Matrix4.IDENTITY)
) {
/* For 3D Tiles, the root tile's transform is used to position the clipping planes.
If a transform is not defined, the root tile's Cesium3DTile#boundingSphere is used instead.
The clipping plane is initially positioned at the tileset's root transform.
Apply an additional matrix to center the clipping plane on the bounding sphere center. */
//转换matrix4至Cartesian3,获取3dtile transform的世界坐标
const transformCenter = LSGlobe.Matrix4.getTranslation(
tileset.root.transform,
new LSGlobe.Cartesian3()
)
//3dtile transform的世界坐标转换为wgs84坐标
const transformCartographic =
LSGlobe.Cartographic.fromCartesian(transformCenter)
//3dtile boundingSphere的中心的世界坐标转换为wgs84坐标
const boundingSphereCartographic = LSGlobe.Cartographic.fromCartesian(
tileset.boundingSphere.center
)
//clippingplane偏移高度
const height =
boundingSphereCartographic.height - transformCartographic.height
// 将裁剪平面居中在模型的中心
clippingPlanes.modelMatrix = LSGlobe.Matrix4.fromTranslation(
new LSGlobe.Cartesian3(0.0, 0.0, height)
)
}
// 创建辅助切面,使得clipping plane可见
for (let i = 0; i < clippingPlanes.length; ++i) {
const plane = clippingPlanes.get(i)
LSGlobe.Viewer.entities.add({
position: boundingSphere.center,
plane: {
dimensions: new LSGlobe.Cartesian2(radius * 1.5, radius * 1.5),
material: LSGlobe.Color.WHITE.withAlpha(0.1),
plane: new LSGlobe.CallbackProperty(
_this.createPlaneUpdateFunction(plane),
false
),
outline: true,
outlineColor: LSGlobe.Color.WHITE
},
name: 'plane',
show: true
})
}
return tileset
})