Skip to content

Commit

Permalink
Merge pull request #8811 from CesiumGS/camera-underground-controls
Browse files Browse the repository at this point in the history
Camera underground controls
  • Loading branch information
IanLilleyT authored May 31, 2020
2 parents d01584a + 5fda45a commit 41d9375
Show file tree
Hide file tree
Showing 9 changed files with 602 additions and 198 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- Fixed sky atmosphere artifacts below the horizon. [#8866](https://github.com/CesiumGS/cesium/pull/8866)
- Fixed ground primitives in orthographic mode. [#5110](https://github.com/CesiumGS/cesium/issues/5110)
- Fixed the depth plane in orthographic mode. This improves the quality of polylines and other primitives that are rendered near the horizon. [8858](https://github.com/CesiumGS/cesium/pull/8858)
- Fixed camera controls when the camera is underground. [#8811](https://github.com/CesiumGS/cesium/pull/8811)

### 1.69.0 - 2020-05-01

Expand Down
1 change: 1 addition & 0 deletions Source/Scene/Camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,7 @@ Camera.prototype._adjustOrthographicFrustum = function (zooming) {
rayIntersection = globe.pickWorldCoordinates(
ray,
scene,
true,
scratchRayIntersection
);

Expand Down
14 changes: 11 additions & 3 deletions Source/Scene/Globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -612,12 +612,18 @@ var scratchSphereIntersectionResult = {
*
* @param {Ray} ray The ray to test for intersection.
* @param {Scene} scene The scene.
* @param {Boolean} [cullBackFaces=true] Set to true to not pick back faces.
* @param {Cartesian3} [result] The object onto which to store the result.
* @returns {Cartesian3|undefined} The intersection or <code>undefined</code> if none was found. The returned position is in projected coordinates for 2D and Columbus View.
*
* @private
*/
Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
Globe.prototype.pickWorldCoordinates = function (
ray,
scene,
cullBackFaces,
result
) {
//>>includeStart('debug', pragmas.debug);
if (!defined(ray)) {
throw new DeveloperError("ray is required");
Expand All @@ -627,6 +633,8 @@ Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
}
//>>includeEnd('debug');

cullBackFaces = defaultValue(cullBackFaces, true);

var mode = scene.mode;
var projection = scene.mapProjection;

Expand Down Expand Up @@ -691,7 +699,7 @@ Globe.prototype.pickWorldCoordinates = function (ray, scene, result) {
ray,
scene.mode,
scene.mapProjection,
true,
cullBackFaces,
result
);
if (defined(intersection)) {
Expand All @@ -717,7 +725,7 @@ var cartoScratch = new Cartographic();
* var intersection = globe.pick(ray, scene);
*/
Globe.prototype.pick = function (ray, scene, result) {
result = this.pickWorldCoordinates(ray, scene, result);
result = this.pickWorldCoordinates(ray, scene, true, result);
if (defined(result) && scene.mode !== SceneMode.SCENE3D) {
result = Cartesian3.fromElements(result.y, result.z, result.x, result);
var carto = scene.mapProjection.unproject(result, cartoScratch);
Expand Down
52 changes: 36 additions & 16 deletions Source/Scene/Scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ function Scene(options) {
this._primitives = new PrimitiveCollection();
this._groundPrimitives = new PrimitiveCollection();

this._globeHeight = undefined;
this._cameraUnderground = false;

this._logDepthBuffer = context.fragmentDepth;
this._logDepthBufferDirty = true;

Expand Down Expand Up @@ -1649,6 +1652,15 @@ Object.defineProperties(Scene.prototype, {
return 0.9999;
},
},

/**
* @private
*/
globeHeight: {
get: function () {
return this._globeHeight;
},
},
});

/**
Expand Down Expand Up @@ -3309,7 +3321,10 @@ Scene.prototype.updateEnvironment = function () {
environmentState.isReadyForAtmosphere ||
globe._surface._tilesToRender.length > 0;
}
environmentState.skyAtmosphereCommand = skyAtmosphere.update(frameState);
environmentState.skyAtmosphereCommand = skyAtmosphere.update(
frameState,
globe
);
if (defined(environmentState.skyAtmosphereCommand)) {
this.updateDerivedCommands(environmentState.skyAtmosphereCommand);
}
Expand Down Expand Up @@ -3693,13 +3708,27 @@ function callAfterRenderFunctions(scene) {
functions.length = 0;
}

function getGlobeHeight(scene) {
var globe = scene._globe;
var camera = scene.camera;
var cartographic = camera.positionCartographic;
if (defined(globe) && globe.show && defined(cartographic)) {
return globe.getHeight(cartographic);
}
return undefined;
}

function isCameraUnderground(scene) {
var camera = scene.camera;
var mode = scene._mode;
var globe = scene.globe;
var cameraController = scene._screenSpaceCameraController;
var cartographic = camera.positionCartographic;

if (!defined(cartographic)) {
return false;
}

if (!cameraController.onMap() && cartographic.height < 0.0) {
// The camera can go off the map while in Columbus View.
// Make a best guess as to whether it's underground by checking if its height is less than zero.
Expand All @@ -3715,17 +3744,8 @@ function isCameraUnderground(scene) {
return false;
}

if (cameraController.adjustedHeightForTerrain()) {
// The camera controller already adjusted the camera, no need to call globe.getHeight again
return false;
}

var globeHeight = globe.getHeight(cartographic);
if (defined(globeHeight) && cartographic.height < globeHeight) {
return true;
}

return false;
var globeHeight = scene._globeHeight;
return defined(globeHeight) && cartographic.height < globeHeight;
}

/**
Expand All @@ -3741,17 +3761,17 @@ Scene.prototype.initializeFrame = function () {

this._tweens.update();

this._globeHeight = getGlobeHeight(this);
this._cameraUnderground = isCameraUnderground(this);
this._globeTranslucencyState.update(this);

this._screenSpaceCameraController.update();
if (defined(this._deviceOrientationCameraController)) {
this._deviceOrientationCameraController.update();
}

this.camera.update(this._mode);
this.camera._updateCameraChanged();

this._cameraUnderground = isCameraUnderground(this);

this._globeTranslucencyState.update(this);
};

function updateDebugShowFramesPerSecond(scene, renderedThisFrame) {
Expand Down
2 changes: 2 additions & 0 deletions Source/Scene/SceneTransitioner.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ function morphFromColumbusViewTo2D(transitioner, duration) {
var pickPos = globe.pickWorldCoordinates(
ray,
scene,
true,
scratchCVTo2DPickPos
);
if (defined(pickPos)) {
Expand Down Expand Up @@ -773,6 +774,7 @@ function morphFrom3DTo2D(transitioner, duration, ellipsoid) {
var pickedPos = globe.pickWorldCoordinates(
ray,
scene,
true,
scratch3DTo2DPickPosition
);
if (defined(pickedPos)) {
Expand Down
Loading

0 comments on commit 41d9375

Please sign in to comment.