-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Solve the issue of #11877 #11907
base: main
Are you sure you want to change the base?
Solve the issue of #11877 #11907
Conversation
Thank you for the pull request, @HapDragon! Welcome to the Cesium community! In order for us to review your PR, please complete the following steps:
Review Pull Request Guidelines to make sure your PR gets accepted quickly. |
Thanks @HapDragon! We'll review this shortly! |
Hi, @ggetz , like the graph below: Origin P will turn to P1 after terrain adjustment, actually I am not sure whether there should add some property to specify the threshold. Or use some angle threshold to determine whether to ignore the height change, I mean if the difference between origin P centric angle and new P1 centric angle bigger than some threshold, we will ignore the height change. Thank you for reviewing. |
Matrix4.getTranslation(transform, transformOrigin); | ||
transformOriginLen = Cartesian3.magnitude(transformOrigin); | ||
} | ||
if (transformOriginLen > controller._minimumCollisionTerrainHeight) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about the use of controller._minimumCollisionTerrainHeight
here. That value was design to be the height above the ellipsoid surface, not the absolute value.
Additionally, that put us in this strange "middle ground" where the camera still re-orients strangely, like in this example below:
const viewer = new Cesium.Viewer("cesiumContainer", {
//globe: false
});
const url = "../../SampleData/models/CesiumAir/Cesium_Air.glb";
const position = new Cesium.Cartesian3(0.0, 100000.0, 0.0);
const orientation = new Cesium.Quaternion(0.0, 0.0, 0.0, 1.0);
const entity = viewer.entities.add({
name: url,
position: position,
orientation: orientation,
model: {
uri: url,
},
});
viewer.camera.lookAt(
new Cesium.Cartesian3(0.0, 100000.0, 1),
new Cesium.Cartesian3(0, 50, 0));
How would you feel about instead using a percentage of the ellipsoid radius? That will ensure we scale to other ellipsoids if needed without having to manually set a value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello ,
At line 2897, the comparision: controller._minimumCollisionTerrainHeight, it seemed should not be such a value. What I thought is to put a threshold to specify the maximum centric length of cartesian3, then let any point in a centric ball with the threshold radius will not do the height adjustment (if there is a transform upon the camera).
Thanks for your advice, I am a little confused about using a percentage of the ellipsoid radius. Does it mean using percentage of ellipsoid radius as the height threshold test?
I modify the adjustHeightForTerrain function again: it will avoid the problem in your example above and issue of #11877 as well:
function adjustHeightForTerrain(controller, cameraChanged) {
controller._adjustedHeightForTerrain = true;
const scene = controller._scene;
const mode = scene.mode;
const globe = scene.globe;
if (mode === SceneMode.SCENE2D || mode === SceneMode.MORPHING) {
return;
}
const camera = scene.camera;
const ellipsoid = defaultValue(globe?.ellipsoid, Ellipsoid.WGS84);
const projection = scene.mapProjection;
let transform;
let mag;
if (!Matrix4.equals(camera.transform, Matrix4.IDENTITY)) {
transform = Matrix4.clone(camera.transform, scratchAdjustHeightTransform);
mag = Cartesian3.magnitude(camera.position);
camera._setTransform(Matrix4.IDENTITY);
}
const cartographic = scratchAdjustHeightCartographic;
if (mode === SceneMode.SCENE3D) {
ellipsoid.cartesianToCartographic(camera.position, cartographic);
} else {
projection.unproject(camera.position, cartographic);
}
let heightUpdated = false;
if (cartographic.height < controller._minimumCollisionTerrainHeight) {
if((defined(transform)&&cartographic.height>-ellipsoid.maximumRadius*0.3)||!defined(transform)){
const globeHeight = controller._scene.globeHeight;
if (defined(globeHeight)) {
const height = globeHeight + controller.minimumZoomDistance;
const difference = globeHeight - controller._lastGlobeHeight;
const percentDifference = difference / controller._lastGlobeHeight;
// Unless the camera has been moved by user input, to avoid big jumps during tile loads
// only make height updates when the globe height has been fairly stable across several frames
if (
cartographic.height < height &&
(cameraChanged || Math.abs(percentDifference) <= 0.1)
) {
cartographic.height = height;
if (mode === SceneMode.SCENE3D) {
ellipsoid.cartographicToCartesian(cartographic, camera.position);
} else {
projection.project(cartographic, camera.position);
}
heightUpdated = true;
}
if (cameraChanged || Math.abs(percentDifference) <= 0.1) {
controller._lastGlobeHeight = globeHeight;
} else {
controller._lastGlobeHeight += difference * 0.1;
}
}
}
}
if (defined(transform)) {
camera._setTransform(transform);
if (heightUpdated) {
Cartesian3.normalize(camera.position, camera.position);
Cartesian3.negate(camera.position, camera.direction);
Cartesian3.multiplyByScalar(
camera.position,
Math.max(mag, controller.minimumZoomDistance),
camera.position
);
Cartesian3.normalize(camera.direction, camera.direction);
Cartesian3.cross(camera.direction, camera.up, camera.right);
Cartesian3.cross(camera.right, camera.direction, camera.up);
}
}
}
It use this code to filter point in deep underground areas:
(defined(transform)&&cartographic.height>-ellipsoid.maximumRadius*0.3)
Thanks for the suggestion @HapDragon! I have one comment before we proceed. |
Thanks for the suggestion@ggetz , I have commented on the code several months ago, it seemed could not been seen. that is to use: |
solve the issue #11877
###11877
Testing plan
when camera lookAt something, using transform, which will lead to recompute camera position, add a restrict in the terrain adjustment process by comparing the magnitude of the transform's origin to a height level, to filter the position which is far away from the globe surface.
Author checklist
CONTRIBUTORS.md
CHANGES.md
with a short summary of my change