3dtiles 裁剪
裁剪 3dtiles 的一部分,使其不显示
加载模型
js
LSGlobe.Viewer.scene.globe.depthTestAgainstTerrain = true
const url = ''
try {
const tileset = await LSGlobe.Cesium3DTileset.fromUrl(url)
LSGlobe.Viewer.scene.primitives.add(tileset)
} catch(error){
console.log(`Error loading tileset: ${error}`);
}
裁剪 3dtile
js
//获取逆变换矩阵
function getInverseTransform(tileSet) {
let transform
let tmp = tileSet.root.transform
if ((tmp && tmp.equals(LSGlobe.Matrix4.IDENTITY)) || !tmp) {
// 如果root.transform不存在,则3DTiles的原点变成了boundingSphere.center
transform = LSGlobe.Transforms.eastNorthUpToFixedFrame(
tileSet.boundingSphere.center
)
} else {
transform = LSGlobe.Matrix4.fromArray(tileSet.root.transform)
}
// return LSGlobe.Matrix4.inverse(
// transform,
// new LSGlobe.Matrix4()
// )
return LSGlobe.Matrix4.inverseTransformation(
transform,
new LSGlobe.Matrix4()
)
}
//获取逆变换矩阵
let inverseTransform = getInverseTransform(tileset)
let planes = []
//要裁剪的区域每个点的坐标,其中起点要在数组末端再出现一次
let points = LSGlobe.Cartesian3.fromDegreesArrayHeights([
102.24015312195303,
38.548924823370974,
1437.6399169392878, //起点
102.24015336017237,
38.54832642138077,
1438.068924491933,
102.24137204709595,
38.548310330480355,
1437.5701734404097,
102.24135488402865,
38.54894734689907,
1437.1842877571341,
102.24015312195303,
38.548924823370974,
1437.6399169392878 //起点再出现一次
])
for (let i = 0; i < points.length; i++) {
if (i + 1 > points.length - 1) {
break
}
//转换点坐标为3dtile本地坐标系
let p1C3 = LSGlobe.Matrix4.multiplyByPoint(
inverseTransform,
points[i],
new LSGlobe.Cartesian3(0, 0, 0)
)
//转换点坐标为3dtile本地坐标系
let p2C3 = LSGlobe.Matrix4.multiplyByPoint(
inverseTransform,
points[i + 1],
new LSGlobe.Cartesian3(0, 0, 0)
)
//获取一个p2 -> p1 的方向向量
let right = LSGlobe.Cartesian3.subtract(
p2C3,
p1C3,
new LSGlobe.Cartesian3()
)
//求p2p1和up的法向量
let up = new LSGlobe.Cartesian3(0, 0, 10)
let normal = LSGlobe.Cartesian3.cross(right, up, new LSGlobe.Cartesian3())
//归一化
normal = LSGlobe.Cartesian3.normalize(normal, normal)
//创建平面
let planeTmp = LSGlobe.Plane.fromPointNormal(p1C3, normal)
planes.push(LSGlobe.ClippingPlane.fromPlane(planeTmp))
}
//创建裁切平面
//unionClippingRegions如果为真,如果一个区域在集合中的任何平面的外面,它将被剪切。
//否则,一个区域只有在每个平面的外面才会被剪掉。
let clippingPlanes = new LSGlobe.ClippingPlaneCollection({
planes: planes,
unionClippingRegions: false,
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)
)
return tileset
js
//获取逆变换矩阵
function getInverseTransform(tileSet) {
let transform
let tmp = tileSet.root.transform
if ((tmp && tmp.equals(LSGlobe.Matrix4.IDENTITY)) || !tmp) {
// 如果root.transform不存在,则3DTiles的原点变成了boundingSphere.center
transform = LSGlobe.Transforms.eastNorthUpToFixedFrame(
tileSet.boundingSphere.center
)
} else {
transform = LSGlobe.Matrix4.fromArray(tileSet.root.transform)
}
// return LSGlobe.Matrix4.inverse(
// transform,
// new LSGlobe.Matrix4()
// )
return LSGlobe.Matrix4.inverseTransformation(
transform,
new LSGlobe.Matrix4()
)
}
//获取逆变换矩阵
let inverseTransform = getInverseTransform(tileset)
let planes = []
//要裁剪的区域每个点的坐标,其中起点要在数组末端再出现一次
let points = LSGlobe.Cartesian3.fromDegreesArrayHeights([
102.24015312195303,
38.548924823370974,
1437.6399169392878, //起点
102.24015336017237,
38.54832642138077,
1438.068924491933,
102.24137204709595,
38.548310330480355,
1437.5701734404097,
102.24135488402865,
38.54894734689907,
1437.1842877571341,
102.24015312195303,
38.548924823370974,
1437.6399169392878 //起点再出现一次
])
for (let i = 0; i < points.length; i++) {
if (i + 1 > points.length - 1) {
break
}
//转换点坐标为3dtile本地坐标系
let p1C3 = LSGlobe.Matrix4.multiplyByPoint(
inverseTransform,
points[i],
new LSGlobe.Cartesian3(0, 0, 0)
)
//转换点坐标为3dtile本地坐标系
let p2C3 = LSGlobe.Matrix4.multiplyByPoint(
inverseTransform,
points[i + 1],
new LSGlobe.Cartesian3(0, 0, 0)
)
//获取一个p2 -> p1 的方向向量
let right = LSGlobe.Cartesian3.subtract(
p2C3,
p1C3,
new LSGlobe.Cartesian3()
)
//求p2p1和up的法向量
let up = new LSGlobe.Cartesian3(0, 0, 10)
//和裁剪区域内的不一样,这次计算的法线与裁剪区域内的相反
let normal = LSGlobe.Cartesian3.cross(up, right, new LSGlobe.Cartesian3())
//归一化
normal = LSGlobe.Cartesian3.normalize(normal, normal)
//创建平面
let planeTmp = LSGlobe.Plane.fromPointNormal(p1C3, normal)
planes.push(LSGlobe.ClippingPlane.fromPlane(planeTmp))
}
//创建裁切平面
//unionClippingRegions如果为真,如果一个区域在集合中的任何平面的外面,它将被剪切。
//否则,一个区域只有在每个平面的外面才会被剪掉。
let clippingPlanes = new LSGlobe.ClippingPlaneCollection({
planes: planes,
unionClippingRegions: true,
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)
)
return tileset