给定一个实体,我试图弄清楚在特定时刻/帧是否可以在屏幕上查看其中一个实体。
我能找到的最接近的是 Entity.isVisible,但它似乎只是统计了显式的
show
属性。即使...它也会返回 true
我也找不到任何函数将实体位置转换为视口坐标以测试它是否至少在相机视锥内。
我有一个想法来测量实体和相机之间的距离,就像这样
Cesium.Cartesian3.distance(this.viewer.selectedEntity.position.getValue(Cesium.JulianDate.now()), this.viewer.camera.position);
但显然可接受的距离需要基于相机高度、FOV 以及相机是否朝那个方向看。我还没有能够用数学方法来解决这个问题。
如何判断实体当前对用户是否可见?
其中一种方法是在视锥体剔除中使用BoundingSphere。然后检查实体的边界球体在剔除体积中是否可见。
const viewer = new Cesium.Viewer('cesiumContainer');
const camera = viewer.camera;
const position = Cesium.Cartesian3.fromDegrees(23.9036, 54.8985);
const frustum = camera.frustum;
const cullingVolume = frustum.computeCullingVolume(
camera.position,
camera.direction,
camera.up
);
const someEntity = viewer.entities.add({
name: 'Some Point',
position: position,
point: {
pixelSize: 14,
color: Cesium.Color.GREEN
}
});
// Bounding sphere of the entity.
let boundingSphere = new Cesium.BoundingSphere();
viewer.dataSourceDisplay.getBoundingSphere(someEntity, false, boundingSphere);
// Check if the entity is visible in the screen.
const intersection = cullingVolume.computeVisibility(boundingSphere);
console.log(intersection);
// 1: Cesium.Intersect.INSIDE
// 0: Cesium.Intersect.INTERSECTING
// -1: Cesium.Intersect.OUTSIDE
我还制作了一个铯沙堡示例。
使用 BoundingSphere 和截锥体剔除可用于 2D 可视化,但对于地球另一端的实体将返回
Cesium.Intersect.INSIDE
。
更准确的方法是使用 Occlusionr 类。不知道为什么,但论坛和文档中的类似问题没有提及此类。这是一个给定观看者和 Cartesian3 位置的工作示例:
isPositionInView(position: Cartesian3) {
const globeBoundingSphere = new BoundingSphere(
Cartesian3.ZERO,
this.viewer.scene.globe.ellipsoid.minimumRadius
);
const occluder = new Occluder(
this.globeBoundingSphere,
this.viewer.camera.position
);
return occluder.isPointVisible(position);
}
注意:我在这里使用
ellipsoid.minimumRadius
来说明地球表面上的实体。