Skip to content

Commit

Permalink
Merge pull request #9678 from CesiumGS/revert-9657-revert-9652-distan…
Browse files Browse the repository at this point in the history
…ce-camera-fix

Update TileBoundingRegion.distanceToCamera to use OBB distance in 3D
  • Loading branch information
lilleyse committed Jul 15, 2021
2 parents a76c1ae + 69c16c6 commit 7784e70
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

##### Fixes :wrench:

- Fixed an issue in `TileBoundingRegion.distanceToCamera` that caused incorrect results when the camera was on the opposite site of the globe. [#9678](https://github.com/CesiumGS/cesium/pull/9678)
- Fixes an error with removing a CZML datasource when the clock interval has a duration of zero. [#9637](https://github.com/CesiumGS/cesium/pull/9637)
- Fixed the ability to set a material's image to `undefined` and `Material.DefaultImageId`. [#9644](https://github.com/CesiumGS/cesium/pull/9644)
- Fixed the calculation of `OrientedBoundingBox.distancedSquaredTo` such that they handle `halfAxes` with magnitudes near zero. [#9670](https://github.com/CesiumGS/cesium/pull/9670)
Expand Down
58 changes: 37 additions & 21 deletions Source/Scene/TileBoundingRegion.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Cartographic from "../Core/Cartographic.js";
import Check from "../Core/Check.js";
import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
import defaultValue from "../Core/defaultValue.js";
import defined from "../Core/defined.js";
import Ellipsoid from "../Core/Ellipsoid.js";
import GeometryInstance from "../Core/GeometryInstance.js";
import IntersectionTests from "../Core/IntersectionTests.js";
Expand Down Expand Up @@ -299,39 +300,30 @@ var negativeUnitY = new Cartesian3(0.0, -1.0, 0.0);
var negativeUnitZ = new Cartesian3(0.0, 0.0, -1.0);
var vectorScratch = new Cartesian3();

/**
* Gets the distance from the camera to the closest point on the tile. This is used for level of detail selection.
*
* @param {FrameState} frameState The state information of the current rendering frame.
* @returns {Number} The distance from the camera to the closest point on the tile, in meters.
*/
TileBoundingRegion.prototype.distanceToCamera = function (frameState) {
//>>includeStart('debug', pragmas.debug);
Check.defined("frameState", frameState);
//>>includeEnd('debug');
function distanceToCameraRegion(tileBB, frameState) {
var camera = frameState.camera;
var cameraCartesianPosition = camera.positionWC;
var cameraCartographicPosition = camera.positionCartographic;

var result = 0.0;
if (!Rectangle.contains(this.rectangle, cameraCartographicPosition)) {
var southwestCornerCartesian = this.southwestCornerCartesian;
var northeastCornerCartesian = this.northeastCornerCartesian;
var westNormal = this.westNormal;
var southNormal = this.southNormal;
var eastNormal = this.eastNormal;
var northNormal = this.northNormal;
if (!Rectangle.contains(tileBB.rectangle, cameraCartographicPosition)) {
var southwestCornerCartesian = tileBB.southwestCornerCartesian;
var northeastCornerCartesian = tileBB.northeastCornerCartesian;
var westNormal = tileBB.westNormal;
var southNormal = tileBB.southNormal;
var eastNormal = tileBB.eastNormal;
var northNormal = tileBB.northNormal;

if (frameState.mode !== SceneMode.SCENE3D) {
southwestCornerCartesian = frameState.mapProjection.project(
Rectangle.southwest(this.rectangle),
Rectangle.southwest(tileBB.rectangle),
southwestCornerScratch
);
southwestCornerCartesian.z = southwestCornerCartesian.y;
southwestCornerCartesian.y = southwestCornerCartesian.x;
southwestCornerCartesian.x = 0.0;
northeastCornerCartesian = frameState.mapProjection.project(
Rectangle.northeast(this.rectangle),
Rectangle.northeast(tileBB.rectangle),
northeastCornerScratch
);
northeastCornerCartesian.z = northeastCornerCartesian.y;
Expand Down Expand Up @@ -389,8 +381,8 @@ TileBoundingRegion.prototype.distanceToCamera = function (frameState) {
var maximumHeight;
if (frameState.mode === SceneMode.SCENE3D) {
cameraHeight = cameraCartographicPosition.height;
minimumHeight = this.minimumHeight;
maximumHeight = this.maximumHeight;
minimumHeight = tileBB.minimumHeight;
maximumHeight = tileBB.maximumHeight;
} else {
cameraHeight = cameraCartesianPosition.x;
minimumHeight = 0.0;
Expand All @@ -406,6 +398,30 @@ TileBoundingRegion.prototype.distanceToCamera = function (frameState) {
}

return Math.sqrt(result);
}

/**
* Gets the distance from the camera to the closest point on the tile. This is used for level of detail selection.
*
* @param {FrameState} frameState The state information of the current rendering frame.
* @returns {Number} The distance from the camera to the closest point on the tile, in meters.
*/
TileBoundingRegion.prototype.distanceToCamera = function (frameState) {
//>>includeStart('debug', pragmas.debug);
Check.defined("frameState", frameState);
//>>includeEnd('debug');

var regionResult = distanceToCameraRegion(this, frameState);
if (
frameState.mode === SceneMode.SCENE3D &&
defined(this._orientedBoundingBox)
) {
var obbResult = Math.sqrt(
this._orientedBoundingBox.distanceSquaredTo(frameState.camera.positionWC)
);
return Math.max(regionResult, obbResult);
}
return regionResult;
};

/**
Expand Down

0 comments on commit 7784e70

Please sign in to comment.