diff --git a/CHANGES.md b/CHANGES.md index 78ff1633c38a..63602f80eda0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -28,6 +28,7 @@ Change Log * Fixed an error where `clampToHeightMostDetailed` or `sampleHeightMostDetailed` would crash if entities were created when the promise resolved. [#7690](https://github.com/AnalyticalGraphicsInc/cesium/pull/7690) * Fixed an issue with compositing merged entity availability. [#7717](https://github.com/AnalyticalGraphicsInc/cesium/issues/7717) * Fixed an error where many imagery layers within a single tile would cause parts of the tile to render as black on some platforms. [#7649](https://github.com/AnalyticalGraphicsInc/cesium/issues/7649) +* Fixed a bug that could cause terrain with a single, global root tile (e.g. that uses `WebMercatorTilingScheme`) to be culled unexpectedly in some views. [#7702](https://github.com/AnalyticalGraphicsInc/cesium/issues/7702) * Fixed a problem where instanced 3D models were incorrectly lit when using physically based materials. [#7775](https://github.com/AnalyticalGraphicsInc/cesium/issues/7775) ### 1.56.1 - 2019-04-02 diff --git a/Source/Core/GoogleEarthEnterpriseTerrainData.js b/Source/Core/GoogleEarthEnterpriseTerrainData.js index 08ce5604a264..fe740a32be58 100644 --- a/Source/Core/GoogleEarthEnterpriseTerrainData.js +++ b/Source/Core/GoogleEarthEnterpriseTerrainData.js @@ -193,16 +193,18 @@ define([ var that = this; return verticesPromise .then(function(result) { + // Clone complex result objects because the transfer from the web worker + // has stripped them down to JSON-style objects. that._mesh = new TerrainMesh( center, new Float32Array(result.vertices), new Uint16Array(result.indices), result.minimumHeight, result.maximumHeight, - result.boundingSphere3D, - result.occludeePointInScaledSpace, + BoundingSphere.clone(result.boundingSphere3D), + Cartesian3.clone(result.occludeePointInScaledSpace), result.numberOfAttributes, - result.orientedBoundingBox, + OrientedBoundingBox.clone(result.orientedBoundingBox), TerrainEncoding.clone(result.encoding), exaggeration, result.westIndicesSouthToNorth, diff --git a/Source/Core/HeightmapTerrainData.js b/Source/Core/HeightmapTerrainData.js index e7f012c04b1a..769941131245 100644 --- a/Source/Core/HeightmapTerrainData.js +++ b/Source/Core/HeightmapTerrainData.js @@ -1,11 +1,14 @@ define([ '../ThirdParty/when', + './BoundingSphere', + './Cartesian3', './defaultValue', './defined', './defineProperties', './DeveloperError', './GeographicProjection', './HeightmapTessellator', + './OrientedBoundingBox', './Math', './Rectangle', './TaskProcessor', @@ -14,12 +17,15 @@ define([ './TerrainProvider' ], function( when, + BoundingSphere, + Cartesian3, defaultValue, defined, defineProperties, DeveloperError, GeographicProjection, HeightmapTessellator, + OrientedBoundingBox, CesiumMath, Rectangle, TaskProcessor, @@ -242,16 +248,18 @@ define([ var that = this; return when(verticesPromise, function(result) { + // Clone complex result objects because the transfer from the web worker + // has stripped them down to JSON-style objects. that._mesh = new TerrainMesh( center, new Float32Array(result.vertices), TerrainProvider.getRegularGridIndices(result.gridWidth, result.gridHeight), result.minimumHeight, result.maximumHeight, - result.boundingSphere3D, - result.occludeePointInScaledSpace, + BoundingSphere.clone(result.boundingSphere3D), + Cartesian3.clone(result.occludeePointInScaledSpace), result.numberOfAttributes, - result.orientedBoundingBox, + OrientedBoundingBox.clone(result.orientedBoundingBox), TerrainEncoding.clone(result.encoding), exaggeration, result.westIndicesSouthToNorth, @@ -324,6 +332,8 @@ define([ arrayHeight += 2; } + // No need to clone here (as we do in the async version) because the result + // is not coming from a web worker. return new TerrainMesh( center, result.vertices, @@ -334,7 +344,7 @@ define([ result.occludeePointInScaledSpace, result.encoding.getStride(), result.orientedBoundingBox, - TerrainEncoding.clone(result.encoding), + result.encoding, exaggeration, result.westIndicesSouthToNorth, result.southIndicesEastToWest, diff --git a/Source/Core/QuantizedMeshTerrainData.js b/Source/Core/QuantizedMeshTerrainData.js index 35bca0020b54..f8ab24532bba 100644 --- a/Source/Core/QuantizedMeshTerrainData.js +++ b/Source/Core/QuantizedMeshTerrainData.js @@ -326,15 +326,17 @@ define([ var rtc = result.center; var minimumHeight = result.minimumHeight; var maximumHeight = result.maximumHeight; - var boundingSphere = defaultValue(result.boundingSphere, that._boundingSphere); - var obb = defaultValue(result.orientedBoundingBox, that._orientedBoundingBox); - var occlusionPoint = that._horizonOcclusionPoint; + var boundingSphere = defaultValue(BoundingSphere.clone(result.boundingSphere), that._boundingSphere); + var obb = defaultValue(OrientedBoundingBox.clone(result.orientedBoundingBox), that._orientedBoundingBox); + var occlusionPoint = Cartesian3.clone(that._horizonOcclusionPoint); var stride = result.vertexStride; var terrainEncoding = TerrainEncoding.clone(result.encoding); that._skirtIndex = result.skirtIndex; that._vertexCountWithoutSkirts = that._quantizedVertices.length / 3; + // Clone complex result objects because the transfer from the web worker + // has stripped them down to JSON-style objects. that._mesh = new TerrainMesh( rtc, vertices, diff --git a/Source/Scene/GlobeSurfaceTile.js b/Source/Scene/GlobeSurfaceTile.js index 79c3a221b858..705eec1e0272 100644 --- a/Source/Scene/GlobeSurfaceTile.js +++ b/Source/Scene/GlobeSurfaceTile.js @@ -6,6 +6,7 @@ define([ '../Core/defineProperties', '../Core/IndexDatatype', '../Core/IntersectionTests', + '../Core/OrientedBoundingBox', '../Core/PixelFormat', '../Core/Request', '../Core/RequestState', @@ -34,6 +35,7 @@ define([ defineProperties, IndexDatatype, IntersectionTests, + OrientedBoundingBox, PixelFormat, Request, RequestState, @@ -511,6 +513,8 @@ define([ when(meshPromise, function(mesh) { surfaceTile.mesh = mesh; + surfaceTile.orientedBoundingBox = OrientedBoundingBox.clone(mesh.orientedBoundingBox, surfaceTile.orientedBoundingBox); + surfaceTile.occludeePointInScaledSpace = Cartesian3.clone(mesh.occludeePointInScaledSpace, surfaceTile.occludeePointInScaledSpace); surfaceTile.terrainState = TerrainState.TRANSFORMED; }, function() { surfaceTile.terrainState = TerrainState.FAILED; diff --git a/Source/Scene/GlobeSurfaceTileProvider.js b/Source/Scene/GlobeSurfaceTileProvider.js index 000e2e5008c2..c6be75ac926c 100644 --- a/Source/Scene/GlobeSurfaceTileProvider.js +++ b/Source/Scene/GlobeSurfaceTileProvider.js @@ -605,6 +605,10 @@ define([ var cullingVolume = frameState.cullingVolume; var boundingVolume = surfaceTile.orientedBoundingBox; + if (!defined(boundingVolume) && defined(surfaceTile.renderedMesh)) { + boundingVolume = surfaceTile.renderedMesh.boundingSphere3D; + } + // Check if the tile is outside the limit area in cartographic space surfaceTile.clippedByBoundaries = false; var clippedCartographicLimitRectangle = clipRectangleAntimeridian(tile.rectangle, this.cartographicLimitRectangle); @@ -635,9 +639,14 @@ define([ } } - var intersection = cullingVolume.computeVisibility(boundingVolume); - if (intersection === Intersect.OUTSIDE) { - return Visibility.NONE; + var intersection = Intersect.INTERSECTING; + if (defined(boundingVolume)) { + intersection = cullingVolume.computeVisibility(boundingVolume); + if (intersection === Intersect.OUTSIDE) { + return Visibility.NONE; + } + } else { + console.log('no bounding volume'); } var ortho3D = frameState.mode === SceneMode.SCENE3D && frameState.camera.frustum instanceof OrthographicFrustum; @@ -898,14 +907,18 @@ define([ } else if (surfaceTile.boundingVolumeSourceTile !== heightSource) { // Heights are from a new source tile, so update the bounding volume. surfaceTile.boundingVolumeSourceTile = heightSource; - surfaceTile.orientedBoundingBox = OrientedBoundingBox.fromRectangle( - tile.rectangle, - tileBoundingRegion.minimumHeight, - tileBoundingRegion.maximumHeight, - tile.tilingScheme.ellipsoid, - surfaceTile.orientedBoundingBox); - - surfaceTile.occludeePointInScaledSpace = computeOccludeePoint(this, surfaceTile.orientedBoundingBox.center, tile.rectangle, tileBoundingRegion.maximumHeight, surfaceTile.occludeePointInScaledSpace); + + var rectangle = tile.rectangle; + if (defined(rectangle) && rectangle.width < CesiumMath.PI_OVER_TWO + CesiumMath.EPSILON5) { + surfaceTile.orientedBoundingBox = OrientedBoundingBox.fromRectangle( + tile.rectangle, + tileBoundingRegion.minimumHeight, + tileBoundingRegion.maximumHeight, + tile.tilingScheme.ellipsoid, + surfaceTile.orientedBoundingBox); + + surfaceTile.occludeePointInScaledSpace = computeOccludeePoint(this, surfaceTile.orientedBoundingBox.center, tile.rectangle, tileBoundingRegion.maximumHeight, surfaceTile.occludeePointInScaledSpace); + } } var min = tileBoundingRegion.minimumHeight;