From ad7abcd08886ea8210285f7e664b45141cf645ba Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 11 Sep 2018 14:37:07 -0400 Subject: [PATCH 01/29] Always use root tileset's transform --- Source/Scene/Batched3DModel3DTileContent.js | 2 ++ Source/Scene/Instanced3DModel3DTileContent.js | 2 ++ Source/Scene/Model.js | 10 +++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index f3e291eaaa40..1aa3772525bd 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -465,6 +465,8 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { + // Use the root tile's transform. + this._model._clippingPlaneOffsetMatrix = this._tileset._root.computedTransform; // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. // This will also trigger synchronous shader regeneration to remove or add the clipping plane and color blending code. diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 96a8711e1559..6693e395131a 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -472,6 +472,8 @@ define([ // Update for clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { + // Use the root tile's transform. + model._clippingPlaneOffsetMatrix = this._tileset._root.computedTransform; // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. model._clippingPlanes = (tilesetClippingPlanes.enabled && this._tile._isClipped) ? tilesetClippingPlanes : undefined; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 22b36ad03ab4..d3e4566cf9ca 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -539,6 +539,9 @@ define([ this.clippingPlanes = options.clippingPlanes; // Used for checking if shaders need to be regenerated due to clipping plane changes. this._clippingPlanesState = 0; + // If defined, it's used to position the clipping planes instead of the modelMatrix. + // Used for RTC coordinates or if this model is part of a tileset. + this._clippingPlaneOffsetMatrix = Matrix4.IDENTITY; /** * This property is for debugging only; it is not for production use nor is it optimized. @@ -4426,7 +4429,12 @@ define([ var clippingPlanes = this._clippingPlanes; var currentClippingPlanesState = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { - Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); + if (Matrix4.equals(this._clippingPlaneOffsetMatrix, Matrix4.IDENTITY)) { + Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); + } else { + Matrix4.multiply(context.uniformState.view3D, this._clippingPlaneOffsetMatrix, this._modelViewMatrix); + } + currentClippingPlanesState = clippingPlanes.clippingPlanesState; } From 9f5553972975f42c860268c2979d2dc17d027cda Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 11 Sep 2018 16:22:03 -0400 Subject: [PATCH 02/29] Apply RTC & bounding sphere fallback for clipping planes --- Source/Scene/Batched3DModel3DTileContent.js | 17 +++++++++++++---- Source/Scene/Cesium3DTile.js | 3 ++- Source/Scene/Instanced3DModel3DTileContent.js | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 1aa3772525bd..dbfd41c69cde 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -9,11 +9,11 @@ define([ '../Core/destroyObject', '../Core/DeveloperError', '../Core/FeatureDetection', - '../Core/getBaseUri', '../Core/getStringFromTypedArray', '../Core/Matrix4', '../Core/RequestType', '../Core/RuntimeError', + '../Core/Transforms', '../Renderer/Pass', './Axis', './Cesium3DTileBatchTable', @@ -33,11 +33,11 @@ define([ destroyObject, DeveloperError, FeatureDetection, - getBaseUri, getStringFromTypedArray, Matrix4, RequestType, RuntimeError, + Transforms, Pass, Axis, Cesium3DTileBatchTable, @@ -361,7 +361,10 @@ define([ content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter), content._rtcCenterTransform); } + tile._useBoundingSphereForClipping = !defined(rtcCenter) && !defined(tileset.root._header.transform); + content._contentModelMatrix = Matrix4.multiply(tile.computedTransform, content._rtcCenterTransform, new Matrix4()); + tile._contentModelMatrix = content._contentModelMatrix; if (!defined(tileset.classificationType)) { // PERFORMANCE_IDEA: patch the shader on demand, e.g., the first time show/color changes. @@ -465,8 +468,14 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - // Use the root tile's transform. - this._model._clippingPlaneOffsetMatrix = this._tileset._root.computedTransform; + // Use the root tile's transform + if (!this._tile._useBoundingSphereForClipping) { + this._model._clippingPlaneOffsetMatrix = this._tileset.root._contentModelMatrix; + } else if (this._tileset.ready) { + // If no RTC or transform for root tile, just use the bounding sphere as a fallback + this._model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); + } + // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. // This will also trigger synchronous shader regeneration to remove or add the clipping plane and color blending code. diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 2e24ba16c617..2d132a7a50cb 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -817,8 +817,9 @@ define([ Cesium3DTile.prototype.visibility = function(frameState, parentVisibilityPlaneMask) { var cullingVolume = frameState.cullingVolume; var boundingVolume = getBoundingVolume(this, frameState); + return CullingVolume.MASK_INSIDE; - var tileset = this._tileset; + var tileset = this._tileset; // eslint-disable-line no-unreachable var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 6693e395131a..c99c196ac9d2 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -417,6 +417,12 @@ define([ } content._modelInstanceCollection = new ModelInstanceCollection(collectionOptions); + content._modelInstanceCollection._useBoundingSphereForClipping = !defined(rtcCenter) && !defined(content._tileset.root._header.transform); + + if (defined(rtcCenter)) { + content._modelInstanceCollection._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenterArray)); + } + } function createFeatures(content) { @@ -467,13 +473,20 @@ define([ this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; var model = this._modelInstanceCollection._model; + var useBoundingSphereForClipping = this._modelInstanceCollection._useBoundingSphereForClipping; + var rtcCenterTransform = this._modelInstanceCollection._rtcCenterTransform; if (defined(model)) { // Update for clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { // Use the root tile's transform. - model._clippingPlaneOffsetMatrix = this._tileset._root.computedTransform; + if (!useBoundingSphereForClipping) { + model._clippingPlaneOffsetMatrix = Matrix4.multiply(rtcCenterTransform, this._tileset.root.computedTransform, new Matrix4()); + } else if (this._tileset.ready) { + model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); + } + // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. model._clippingPlanes = (tilesetClippingPlanes.enabled && this._tile._isClipped) ? tilesetClippingPlanes : undefined; From 9ed3695540e94aae78b2322b5d148c02bb8535c5 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Fri, 14 Sep 2018 10:22:38 -0400 Subject: [PATCH 03/29] Fixed crash if root tile wasn't loaded --- Source/Scene/Batched3DModel3DTileContent.js | 18 +++++++++++++----- Source/Scene/Instanced3DModel3DTileContent.js | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index dbfd41c69cde..f6749497f452 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -359,10 +359,13 @@ define([ var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); if (defined(rtcCenter)) { content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter), content._rtcCenterTransform); + tile._hasRTC = true; } - tile._useBoundingSphereForClipping = !defined(rtcCenter) && !defined(tileset.root._header.transform); - + // Use the boundingSphere fallback if the root tile has neither a defined transform nor an RTC property. + // If the root tile hasn't loaded yet, we don't know if it has RTC, so we assume it does not. + tile._useBoundingSphereForClipping = !defined(tileset.root._header.transform) && !defined(tileset.root._hasRTC); + content._contentModelMatrix = Matrix4.multiply(tile.computedTransform, content._rtcCenterTransform, new Matrix4()); tile._contentModelMatrix = content._contentModelMatrix; @@ -468,11 +471,16 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - // Use the root tile's transform + // Use the root tile's transform. if (!this._tile._useBoundingSphereForClipping) { - this._model._clippingPlaneOffsetMatrix = this._tileset.root._contentModelMatrix; + if (defined(this._tileset.root._contentModelMatrix)) { + this._model._clippingPlaneOffsetMatrix = this._tileset.root._contentModelMatrix; + } else { + // If the root tile isn't loaded yet, just use its transform directly from the header. + this._model._clippingPlaneOffsetMatrix = Matrix4.multiply(this._tileset.root._header.transform, this._tileset.modelMatrix, new Matrix4()); + } } else if (this._tileset.ready) { - // If no RTC or transform for root tile, just use the bounding sphere as a fallback + // If no RTC or transform for root tile, just use the bounding sphere as a fallback. this._model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); } diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index c99c196ac9d2..4bdff4018115 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -419,6 +419,7 @@ define([ content._modelInstanceCollection = new ModelInstanceCollection(collectionOptions); content._modelInstanceCollection._useBoundingSphereForClipping = !defined(rtcCenter) && !defined(content._tileset.root._header.transform); + content._modelInstanceCollection._rtcCenterTransform = Matrix4.IDENTITY; if (defined(rtcCenter)) { content._modelInstanceCollection._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenterArray)); } From bdb87996017bcaa38f1a8bb3eb4351e32660a772 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Fri, 14 Sep 2018 10:36:13 -0400 Subject: [PATCH 04/29] Apply eastNorthUp to RTC center --- Source/Scene/Batched3DModel3DTileContent.js | 2 +- Source/Scene/Instanced3DModel3DTileContent.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index f6749497f452..090de8ac8875 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -358,7 +358,7 @@ define([ content._rtcCenterTransform = Matrix4.clone(Matrix4.IDENTITY); var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); if (defined(rtcCenter)) { - content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter), content._rtcCenterTransform); + content._rtcCenterTransform = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromArray(rtcCenter), content._rtcCenterTransform); tile._hasRTC = true; } diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 4bdff4018115..e6978facfb26 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -421,7 +421,7 @@ define([ content._modelInstanceCollection._rtcCenterTransform = Matrix4.IDENTITY; if (defined(rtcCenter)) { - content._modelInstanceCollection._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenterArray)); + content._modelInstanceCollection._rtcCenterTransform = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromArray(rtcCenterArray)); } } From 6cb042624af7a5094f15f240e9f592ebc49d2a4e Mon Sep 17 00:00:00 2001 From: Shehata Date: Mon, 17 Sep 2018 18:18:41 -0400 Subject: [PATCH 05/29] Fixed RTC for b3dm --- Source/Scene/Batched3DModel3DTileContent.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 090de8ac8875..4fb870b4ac4b 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -355,10 +355,10 @@ define([ primitive : tileset }; - content._rtcCenterTransform = Matrix4.clone(Matrix4.IDENTITY); + content._rtcCenterTransform = Matrix4.IDENTITY; var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); if (defined(rtcCenter)) { - content._rtcCenterTransform = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromArray(rtcCenter), content._rtcCenterTransform); + content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter)); tile._hasRTC = true; } From aa71e96019c16a84a5feffbfa33931f9b19d19e5 Mon Sep 17 00:00:00 2001 From: Shehata Date: Tue, 18 Sep 2018 07:54:44 -0400 Subject: [PATCH 06/29] Traversal uses correct tileset transforms for clipping --- Source/Scene/Batched3DModel3DTileContent.js | 1 + Source/Scene/Cesium3DTile.js | 15 ++++++++++----- Source/Scene/Cesium3DTileset.js | 1 - Source/Scene/ClippingPlaneCollection.js | 2 +- Source/Scene/Instanced3DModel3DTileContent.js | 1 + 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 4fb870b4ac4b..60b0142b7d3d 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -483,6 +483,7 @@ define([ // If no RTC or transform for root tile, just use the bounding sphere as a fallback. this._model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); } + this._tileset._clippingPlaneOffsetMatrix = this._model._clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 2d132a7a50cb..31b68a8d8604 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -24,6 +24,7 @@ define([ '../Core/RequestType', '../Core/Resource', '../Core/RuntimeError', + '../Core/Transforms', '../ThirdParty/when', './Cesium3DTileContentFactory', './Cesium3DTileContentState', @@ -60,6 +61,7 @@ define([ RequestType, Resource, RuntimeError, + Transforms, when, Cesium3DTileContentFactory, Cesium3DTileContentState, @@ -306,7 +308,7 @@ define([ * * @private */ - this.clippingPlanesDirty = false; + this.clippingPlanesDirty = true; // Members that are updated every frame for tree traversal and rendering optimizations: this._distanceToCamera = 0; @@ -702,7 +704,6 @@ define([ } var contentFailedFunction = getContentFailedFunction(this); - promise.then(function(arrayBuffer) { if (that.isDestroyed()) { // Tile is unloaded before the content finishes loading @@ -817,12 +818,15 @@ define([ Cesium3DTile.prototype.visibility = function(frameState, parentVisibilityPlaneMask) { var cullingVolume = frameState.cullingVolume; var boundingVolume = getBoundingVolume(this, frameState); - return CullingVolume.MASK_INSIDE; - var tileset = this._tileset; // eslint-disable-line no-unreachable + var tileset = this._tileset; var clippingPlanes = tileset.clippingPlanes; - if (defined(clippingPlanes) && clippingPlanes.enabled) { + // Don't run the clipping plane visibility check until the content has at least been initialized. + if (defined(clippingPlanes) && clippingPlanes.enabled && defined(this._content)) { var tileTransform = tileset.root.computedTransform; + if(tileset._clippingPlaneOffsetMatrix) { + tileTransform = tileset._clippingPlaneOffsetMatrix; + } var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); this._isClipped = intersection !== Intersect.INSIDE; if (intersection === Intersect.OUTSIDE) { @@ -858,6 +862,7 @@ define([ var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; + // TODO: When does this run? Should the transform be updated here too? var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); this._isClipped = intersection !== Intersect.INSIDE; if (intersection === Intersect.OUTSIDE) { diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 604742192531..afda600cbc21 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1478,7 +1478,6 @@ define([ filterProcessingQueue(tileset); var tiles = tileset._processingQueue; var length = tiles.length; - // Process tiles in the PROCESSING state so they will eventually move to the READY state. for (var i = 0; i < length; ++i) { tiles[i].process(tileset, frameState); diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index 01a3d88dac1e..0183efb9d689 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -587,7 +587,7 @@ define([ var modelMatrix = this.modelMatrix; if (defined(transform)) { - modelMatrix = Matrix4.multiply(modelMatrix, transform, scratchMatrix); + modelMatrix = Matrix4.multiply(transform, modelMatrix, scratchMatrix); } // If the collection is not set to union the clipping regions, the volume must be outside of all planes to be diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index e6978facfb26..eb035979f11f 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -487,6 +487,7 @@ define([ } else if (this._tileset.ready) { model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); } + tileset._clippingPlaneOffsetMatrix = model._clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. From 0ec49a548e83f20b82927573be1a23d22db0c132 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 12:34:59 -0400 Subject: [PATCH 07/29] Sinplified BoundingSphere fallback check --- .../gallery/3D Tiles Clipping Planes.html | 8 ++----- Source/Scene/Batched3DModel3DTileContent.js | 23 ++++--------------- Source/Scene/Cesium3DTile.js | 21 +++++++++++++---- Source/Scene/Instanced3DModel3DTileContent.js | 8 +++---- Source/Scene/Model.js | 7 +++--- 5 files changed, 28 insertions(+), 39 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index a2d7a1c8a274..50bb14059524 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -218,13 +218,9 @@ if (newValue === clipObjects[0]) { loadTileset(bimUrl); } else if (newValue === clipObjects[1]) { - loadTileset(pointCloudUrl).then(function(tileset) { - tileset.clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center); - }); + loadTileset(pointCloudUrl); } else if (newValue === clipObjects[2]) { - loadTileset(instancedUrl).then(function(tileset) { - tileset.clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center); - }); + loadTileset(instancedUrl); } else { loadModel(modelUrl); } diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 60b0142b7d3d..64f1a5ba8ddf 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -359,15 +359,9 @@ define([ var rtcCenter = featureTable.getGlobalProperty('RTC_CENTER', ComponentDatatype.FLOAT, 3); if (defined(rtcCenter)) { content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter)); - tile._hasRTC = true; } - - // Use the boundingSphere fallback if the root tile has neither a defined transform nor an RTC property. - // If the root tile hasn't loaded yet, we don't know if it has RTC, so we assume it does not. - tile._useBoundingSphereForClipping = !defined(tileset.root._header.transform) && !defined(tileset.root._hasRTC); content._contentModelMatrix = Matrix4.multiply(tile.computedTransform, content._rtcCenterTransform, new Matrix4()); - tile._contentModelMatrix = content._contentModelMatrix; if (!defined(tileset.classificationType)) { // PERFORMANCE_IDEA: patch the shader on demand, e.g., the first time show/color changes. @@ -471,20 +465,11 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - // Use the root tile's transform. - if (!this._tile._useBoundingSphereForClipping) { - if (defined(this._tileset.root._contentModelMatrix)) { - this._model._clippingPlaneOffsetMatrix = this._tileset.root._contentModelMatrix; - } else { - // If the root tile isn't loaded yet, just use its transform directly from the header. - this._model._clippingPlaneOffsetMatrix = Matrix4.multiply(this._tileset.root._header.transform, this._tileset.modelMatrix, new Matrix4()); - } - } else if (this._tileset.ready) { - // If no RTC or transform for root tile, just use the bounding sphere as a fallback. - this._model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); + if (!this._tileset.root._useBoundingSphereForClipping) { + this._model._clippingPlaneOffsetMatrix = this._tileset.root.computedTransform; + } else { + this._model._clippingPlaneOffsetMatrix = this._tileset.root._clippingPlaneOffsetMatrix; } - this._tileset._clippingPlaneOffsetMatrix = this._model._clippingPlaneOffsetMatrix; - // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. // This will also trigger synchronous shader regeneration to remove or add the clipping plane and color blending code. diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 31b68a8d8604..41bccd7480da 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -201,7 +201,6 @@ define([ Cesium3DTile._deprecationWarning('contentUrl', 'This tileset JSON uses the "content.url" property which has been deprecated. Use "content.uri" instead.'); contentHeaderUri = contentHeader.url; } - hasEmptyContent = false; contentState = Cesium3DTileContentState.UNLOADED; contentResource = baseResource.getDerivedResource({ @@ -335,6 +334,12 @@ define([ this._priority = 0.0; this._isClipped = true; this._clippingPlanesState = 0; // encapsulates (_isClipped, clippingPlanes.enabled) and number/function + this._useBoundingSphereForClipping = false; + // If this is the root tile, and it doesn't have a defined transform, fall back to bounding sphere. + if (!defined(this.parent) && !defined(this._header.transform)) { + this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); + this._useBoundingSphereForClipping = true; + } this._debugBoundingVolume = undefined; this._debugContentBoundingVolume = undefined; @@ -822,10 +827,10 @@ define([ var tileset = this._tileset; var clippingPlanes = tileset.clippingPlanes; // Don't run the clipping plane visibility check until the content has at least been initialized. - if (defined(clippingPlanes) && clippingPlanes.enabled && defined(this._content)) { + if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; - if(tileset._clippingPlaneOffsetMatrix) { - tileTransform = tileset._clippingPlaneOffsetMatrix; + if(defined(tileset.root._clippingPlaneOffsetMatrix)) { + tileTransform = tileset.root._clippingPlaneOffsetMatrix; } var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); this._isClipped = intersection !== Intersect.INSIDE; @@ -862,7 +867,9 @@ define([ var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; - // TODO: When does this run? Should the transform be updated here too? + if(defined(tileset.root._clippingPlaneOffsetMatrix)) { + tileTransform = tileset.root._clippingPlaneOffsetMatrix; + } var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); this._isClipped = intersection !== Intersect.INSIDE; if (intersection === Intersect.OUTSIDE) { @@ -1057,6 +1064,10 @@ define([ this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume); } + if (this._useBoundingSphereForClipping) { + this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); + } + // Destroy the debug bounding volumes. They will be generated fresh. this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index eb035979f11f..a6ed399a2dfb 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -482,13 +482,11 @@ define([ var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { // Use the root tile's transform. - if (!useBoundingSphereForClipping) { - model._clippingPlaneOffsetMatrix = Matrix4.multiply(rtcCenterTransform, this._tileset.root.computedTransform, new Matrix4()); + if (!this._tileset.root._useBoundingSphereForClipping) { + model._clippingPlaneOffsetMatrix = this._tileset.root.computedTransform; } else if (this._tileset.ready) { - model._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this._tileset.boundingSphere.center); + model._clippingPlaneOffsetMatrix = this._tileset.root._clippingPlaneOffsetMatrix; } - tileset._clippingPlaneOffsetMatrix = model._clippingPlaneOffsetMatrix; - // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. model._clippingPlanes = (tilesetClippingPlanes.enabled && this._tile._isClipped) ? tilesetClippingPlanes : undefined; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index d3e4566cf9ca..979058c27adf 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -540,8 +540,8 @@ define([ // Used for checking if shaders need to be regenerated due to clipping plane changes. this._clippingPlanesState = 0; // If defined, it's used to position the clipping planes instead of the modelMatrix. - // Used for RTC coordinates or if this model is part of a tileset. - this._clippingPlaneOffsetMatrix = Matrix4.IDENTITY; + // This is so that when models are part of a tileset they all share the same matrix. + this._clippingPlaneOffsetMatrix = undefined; /** * This property is for debugging only; it is not for production use nor is it optimized. @@ -4429,12 +4429,11 @@ define([ var clippingPlanes = this._clippingPlanes; var currentClippingPlanesState = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { - if (Matrix4.equals(this._clippingPlaneOffsetMatrix, Matrix4.IDENTITY)) { + if (!defined(this._clippingPlaneOffsetMatrix)) { Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); } else { Matrix4.multiply(context.uniformState.view3D, this._clippingPlaneOffsetMatrix, this._modelViewMatrix); } - currentClippingPlanesState = clippingPlanes.clippingPlanesState; } From 0a07e562027d9799ad346e4ed996c7b27bf201c5 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 13:32:35 -0400 Subject: [PATCH 08/29] No need to keep track of RTC anymore --- Source/Scene/Batched3DModel3DTileContent.js | 2 +- Source/Scene/Cesium3DTile.js | 6 ++---- Source/Scene/Instanced3DModel3DTileContent.js | 9 --------- Source/Scene/Model.js | 3 ++- 4 files changed, 5 insertions(+), 15 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index 64f1a5ba8ddf..f832a2a147de 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -360,7 +360,7 @@ define([ if (defined(rtcCenter)) { content._rtcCenterTransform = Matrix4.fromTranslation(Cartesian3.fromArray(rtcCenter)); } - + content._contentModelMatrix = Matrix4.multiply(tile.computedTransform, content._rtcCenterTransform, new Matrix4()); if (!defined(tileset.classificationType)) { diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index 41bccd7480da..dead7d0de589 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -307,7 +307,7 @@ define([ * * @private */ - this.clippingPlanesDirty = true; + this.clippingPlanesDirty = false; // Members that are updated every frame for tree traversal and rendering optimizations: this._distanceToCamera = 0; @@ -335,7 +335,7 @@ define([ this._isClipped = true; this._clippingPlanesState = 0; // encapsulates (_isClipped, clippingPlanes.enabled) and number/function this._useBoundingSphereForClipping = false; - // If this is the root tile, and it doesn't have a defined transform, fall back to bounding sphere. + // If this is the root tile, and it doesn't have a defined transform, fall back to bounding sphere. if (!defined(this.parent) && !defined(this._header.transform)) { this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); this._useBoundingSphereForClipping = true; @@ -826,7 +826,6 @@ define([ var tileset = this._tileset; var clippingPlanes = tileset.clippingPlanes; - // Don't run the clipping plane visibility check until the content has at least been initialized. if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; if(defined(tileset.root._clippingPlaneOffsetMatrix)) { @@ -1067,7 +1066,6 @@ define([ if (this._useBoundingSphereForClipping) { this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); } - // Destroy the debug bounding volumes. They will be generated fresh. this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index a6ed399a2dfb..f9eacae347cc 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -417,13 +417,6 @@ define([ } content._modelInstanceCollection = new ModelInstanceCollection(collectionOptions); - content._modelInstanceCollection._useBoundingSphereForClipping = !defined(rtcCenter) && !defined(content._tileset.root._header.transform); - - content._modelInstanceCollection._rtcCenterTransform = Matrix4.IDENTITY; - if (defined(rtcCenter)) { - content._modelInstanceCollection._rtcCenterTransform = Transforms.eastNorthUpToFixedFrame(Cartesian3.fromArray(rtcCenterArray)); - } - } function createFeatures(content) { @@ -474,8 +467,6 @@ define([ this._modelInstanceCollection.debugWireframe = this._tileset.debugWireframe; var model = this._modelInstanceCollection._model; - var useBoundingSphereForClipping = this._modelInstanceCollection._useBoundingSphereForClipping; - var rtcCenterTransform = this._modelInstanceCollection._rtcCenterTransform; if (defined(model)) { // Update for clipping planes diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 979058c27adf..a57f715465d0 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -540,7 +540,8 @@ define([ // Used for checking if shaders need to be regenerated due to clipping plane changes. this._clippingPlanesState = 0; // If defined, it's used to position the clipping planes instead of the modelMatrix. - // This is so that when models are part of a tileset they all share the same matrix. + // This is so that when models are part of a tileset they all get clipped relative + // to the root tile. this._clippingPlaneOffsetMatrix = undefined; /** From 5aee22ab0af156cce77691a21b8e1463f4599f67 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 14:43:01 -0400 Subject: [PATCH 09/29] Simplify clipping sandcastle example --- .../gallery/3D Tiles Clipping Planes.html | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html index 50bb14059524..9f30816a1d26 100644 --- a/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html +++ b/Apps/Sandcastle/gallery/3D Tiles Clipping Planes.html @@ -104,11 +104,10 @@ } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); -var scratchPlane = new Cesium.ClippingPlane(Cesium.Cartesian3.UNIT_X, 0.0); -function createPlaneUpdateFunction(plane, transform) { +function createPlaneUpdateFunction(plane) { return function () { plane.distance = targetY; - return Cesium.Plane.transform(plane, transform, scratchPlane); + return plane; }; } @@ -116,7 +115,7 @@ function loadTileset(url) { clippingPlanes = new Cesium.ClippingPlaneCollection({ planes : [ - new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), -100.0) + new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0) ], edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0 }); @@ -140,7 +139,7 @@ plane : { dimensions : new Cesium.Cartesian2(radius * 2.5, radius * 2.5), material : Cesium.Color.WHITE.withAlpha(0.1), - plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane, tileset.modelMatrix), false), + plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false), outline : true, outlineColor : Cesium.Color.WHITE } @@ -157,7 +156,7 @@ function loadModel(url) { clippingPlanes = new Cesium.ClippingPlaneCollection({ planes : [ - new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), -100.0) + new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 0.0, -1.0), 0.0) ], edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0 }); @@ -189,7 +188,7 @@ plane : { dimensions : new Cesium.Cartesian2(300.0, 300.0), material : Cesium.Color.WHITE.withAlpha(0.1), - plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane, Cesium.Matrix4.IDENTITY), false), + plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane), false), outline : true, outlineColor : Cesium.Color.WHITE } From 1f1cd16b4b2f179ee644ddbba3815a7b41324770 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 14:43:31 -0400 Subject: [PATCH 10/29] Use correct matrix for point clouds --- Source/Scene/PointCloud.js | 13 +++++++++++-- Source/Scene/PointCloud3DTileContent.js | 6 ++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index 6623383bcf69..e8aaa2bd823e 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -185,6 +185,10 @@ define([ this.clippingPlanes = undefined; this.isClipped = false; this.clippingPlanesDirty = false; + // If defined, it's used to position the clipping planes instead of the modelMatrix. + // This is so that when point clouds are part of a tileset they all get clipped relative + // to the root tile. + this._clippingPlaneOffsetMatrix = undefined; this.attenuation = false; this._attenuation = false; @@ -819,8 +823,13 @@ define([ if (!defined(clippingPlanes)) { return Matrix4.IDENTITY; } - var modelViewMatrix = Matrix4.multiply(context.uniformState.view3D, pointCloud._modelMatrix, scratchClippingPlaneMatrix); - return Matrix4.multiply(modelViewMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix); + + if (!defined(pointCloud._clippingPlaneOffsetMatrix)) { + Matrix4.multiply(context.uniformState.view3D, pointCloud._modelMatrix, scratchClippingPlaneMatrix); + } else { + Matrix4.multiply(context.uniformState.view3D, pointCloud._clippingPlaneOffsetMatrix, scratchClippingPlaneMatrix); + } + return scratchClippingPlaneMatrix; } }; diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 83e929963023..7dc139190327 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -297,6 +297,12 @@ define([ var styleDirty = this._styleDirty; this._styleDirty = false; + if (!tileset.root._useBoundingSphereForClipping) { + pointCloud._clippingPlaneOffsetMatrix = tileset.root.computedTransform; + } else { + pointCloud._clippingPlaneOffsetMatrix = tileset.root._clippingPlaneOffsetMatrix; + } + pointCloud.style = defined(batchTable) ? undefined : tileset.style; pointCloud.styleDirty = styleDirty; pointCloud.modelMatrix = tile.computedTransform; From 8996da60b8183f4bb61f44108337ea6f71478ab7 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 15:14:07 -0400 Subject: [PATCH 11/29] Fixed old tests --- Specs/Scene/Cesium3DTilesetSpec.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 204ae8911bc9..032d002089bc 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -3122,7 +3122,9 @@ defineSuite([ tileset.update(scene.frameState); - var plane = new ClippingPlane(Cartesian3.UNIT_Z, 0.0); + var radius = 287.0736139905632; + + var plane = new ClippingPlane(Cartesian3.UNIT_X, radius); tileset.clippingPlanes = new ClippingPlaneCollection({ planes : [ plane @@ -3135,7 +3137,7 @@ defineSuite([ expect(statistics.numberOfCommands).toEqual(5); expect(root._isClipped).toBe(false); - plane.distance = -4081630.311150717; // center + plane.distance = -1; tileset.update(scene.frameState); scene.renderForSpecs(); @@ -3143,7 +3145,7 @@ defineSuite([ expect(statistics.numberOfCommands).toEqual(3); expect(root._isClipped).toBe(true); - plane.distance = -4081630.31115071 - 287.0736139905632; // center + radius + plane.distance = -radius; tileset.update(scene.frameState); scene.renderForSpecs(); @@ -3164,7 +3166,9 @@ defineSuite([ tileset.update(scene.frameState); - var plane = new ClippingPlane(Cartesian3.UNIT_Z, 0.0); + var radius = 142.19001637409772; + + var plane = new ClippingPlane(Cartesian3.UNIT_Z, radius); tileset.clippingPlanes = new ClippingPlaneCollection({ planes : [ plane @@ -3177,7 +3181,7 @@ defineSuite([ expect(statistics.numberOfCommands).toEqual(6); expect(root._isClipped).toBe(false); - plane.distance = -4081608.4377916814; // center + plane.distance = 0; tileset.update(scene.frameState); scene.renderForSpecs(); @@ -3185,7 +3189,7 @@ defineSuite([ expect(statistics.numberOfCommands).toEqual(6); expect(root._isClipped).toBe(true); - plane.distance = -4081608.4377916814 - 142.19001637409772; // center + radius + plane.distance = -radius; tileset.update(scene.frameState); scene.renderForSpecs(); From 7d5bb573f64ff825363786045fe67832af3f925a Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 15:50:54 -0400 Subject: [PATCH 12/29] Fix point cloud tests --- Specs/Cesium3DTilesTester.js | 3 ++- Specs/Scene/PointCloud3DTileContentSpec.js | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Specs/Cesium3DTilesTester.js b/Specs/Cesium3DTilesTester.js index ab7b62618e7c..8a959d8cf1db 100644 --- a/Specs/Cesium3DTilesTester.js +++ b/Specs/Cesium3DTilesTester.js @@ -132,7 +132,8 @@ define([ var tileset = { _statistics : { batchTableByteLength : 0 - } + }, + root : {} }; var url = Resource.createIfNeeded(''); var content = Cesium3DTileContentFactory[type](tileset, mockTile, url, arrayBuffer, 0); diff --git a/Specs/Scene/PointCloud3DTileContentSpec.js b/Specs/Scene/PointCloud3DTileContentSpec.js index 80d5100f715e..ec020fb43bd1 100644 --- a/Specs/Scene/PointCloud3DTileContentSpec.js +++ b/Specs/Scene/PointCloud3DTileContentSpec.js @@ -934,8 +934,7 @@ defineSuite([ tileset.clippingPlanes = new ClippingPlaneCollection({ planes : [ clipPlane - ], - modelMatrix : Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center) + ] }); expect(scene).notToRender(color); From b605a614e3e06e2e762de9c7787e07edb6009d7f Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 16:07:29 -0400 Subject: [PATCH 13/29] Added bounding sphere tests --- Specs/Scene/Cesium3DTilesetSpec.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index 032d002089bc..c72ffed3cdeb 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -15,6 +15,7 @@ defineSuite([ 'Core/PrimitiveType', 'Core/RequestScheduler', 'Core/Resource', + 'Core/Transforms', 'Renderer/ClearCommand', 'Renderer/ContextLimits', 'Scene/Cesium3DTile', @@ -46,6 +47,7 @@ defineSuite([ PrimitiveType, RequestScheduler, Resource, + Transforms, ClearCommand, ContextLimits, Cesium3DTile, @@ -3198,4 +3200,27 @@ defineSuite([ expect(root._isClipped).toBe(true); }); }); + + it('uses bounding sphere for clipping only if root has no transforms', function() { + return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then(function(tileset) { + expect(tileset.root._useBoundingSphereForClipping).toBe(true); + + return Cesium3DTilesTester.loadTileset(scene, withTransformBoxUrl).then(function(tileset) { + expect(tileset.root._useBoundingSphereForClipping).toBe(false); + }); + }); + }); + + it('correctly computes clippingPlaneOffsetMatrix', function() { + return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then(function(tileset) { + var offsetMatrix = tileset.root._clippingPlaneOffsetMatrix; + var boundingSphereMatrix = Transforms.eastNorthUpToFixedFrame(tileset.root.boundingSphere.center); + expect(Matrix4.equals(offsetMatrix,boundingSphereMatrix)).toBe(true); + + return Cesium3DTilesTester.loadTileset(scene, withTransformBoxUrl).then(function(tileset) { + expect(tileset.root._clippingPlaneOffsetMatrix).toBeUndefined(); + }); + }); + }); + }, 'WebGL'); From 0d2dd5f0e3af0c2d16117f5cbcaaf9a9226f442b Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Tue, 18 Sep 2018 16:39:57 -0400 Subject: [PATCH 14/29] Added clipping plane doc example --- Source/Scene/ClippingPlaneCollection.js | 31 +++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index 0183efb9d689..ebddbe5171a5 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -55,6 +55,13 @@ define([ /** * Specifies a set of clipping planes. Clipping planes selectively disable rendering in a region on the * outside of the specified list of {@link ClippingPlane} objects for a single gltf model, 3D Tileset, or the globe. + *

+ * In general the clipping planes' coordinates are relative to the object they're attached to, so a plane with distance set to 0 will clip + * through the center of the object. + *

+ *

+ * For 3D Tiles, the root tile's transform is used to position the clipping planes. If a transform is not defined, the root tile's {@link Cesium3DTile#boundingSphere} is used instead. + *

* * @alias ClippingPlaneCollection * @constructor @@ -66,6 +73,30 @@ define([ * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if included in any plane in the collection. Otherwise, the region to be clipped must intersect the regions defined by all planes in this collection. * @param {Color} [options.edgeColor=Color.WHITE] The color applied to highlight the edge along which an object is clipped. * @param {Number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. + * + * @demo {@link https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=3D%20Tiles%20Clipping%20Planes.html|Clipping 3D Tiles and glTF models.} + * @demo {@link https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/?src=Terrain%20Clipping%20Planes.html|Clipping the Globe.} + * + * @example + * // This clipping plane's distance is positive, which means its normal + * // is facing the origin. This will clip everything that is behind + * // the plane, which is all pixels with y > 5. + * var clippingPlanes = new Cesium.ClippingPlaneCollection({ + * planes : [ + * new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 1.0, 0.0), 5.0) + * ], + * }); + * // Create an entity and attach the ClippingPlaneCollection to the model. + * var entity = viewer.entities.add({ + * position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 10000), + * model : { + * uri : '../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb', + * minimumPixelSize : 128, + * maximumScale : 20000, + * clippingPlanes : clippingPlanes + * } + * }); + * viewer.zoomTo(entity); */ function ClippingPlaneCollection(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); From 814c5aee2550995835182e02564f27da397f3a04 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 10:54:27 -0400 Subject: [PATCH 15/29] Fix 'Many Clipping Planes' example --- Apps/Sandcastle/gallery/development/Many Clipping Planes.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html index 46cb523a11e2..47a6d19cf34d 100644 --- a/Apps/Sandcastle/gallery/development/Many Clipping Planes.html +++ b/Apps/Sandcastle/gallery/development/Many Clipping Planes.html @@ -226,9 +226,7 @@ }); } else if (newValue === clipObjects[3]) { // i3dm - loadTileset(instancedUrl, 100.0).then(function() { - tileset.clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center); - }); + loadTileset(instancedUrl, 100.0); } else if (newValue === clipObjects[4]) { // Terrain var position = Cesium.Cartesian3.fromRadians(-2.0872979473351286, 0.6596620013036164, 2380.0); From dd3a7c65f8edcc78f284f1d5177c5b557cb838bb Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 11:19:27 -0400 Subject: [PATCH 16/29] Put back point cloud clipping plane matrix --- Source/Scene/PointCloud.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index e8aaa2bd823e..3577e34cbaab 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -829,7 +829,8 @@ define([ } else { Matrix4.multiply(context.uniformState.view3D, pointCloud._clippingPlaneOffsetMatrix, scratchClippingPlaneMatrix); } - return scratchClippingPlaneMatrix; + + return Matrix4.multiply(scratchClippingPlaneMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix);; } }; From 9db45006d8118c2bbb3910197cc4b406acb86b93 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 11:50:39 -0400 Subject: [PATCH 17/29] Style and wording edits --- Source/Scene/Cesium3DTile.js | 4 ++-- Source/Scene/ClippingPlaneCollection.js | 4 ++-- Source/Scene/Model.js | 13 +++++-------- Source/Scene/PointCloud.js | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index dead7d0de589..d533c9d7c321 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -828,7 +828,7 @@ define([ var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; - if(defined(tileset.root._clippingPlaneOffsetMatrix)) { + if (defined(tileset.root._clippingPlaneOffsetMatrix)) { tileTransform = tileset.root._clippingPlaneOffsetMatrix; } var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); @@ -866,7 +866,7 @@ define([ var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { var tileTransform = tileset.root.computedTransform; - if(defined(tileset.root._clippingPlaneOffsetMatrix)) { + if (defined(tileset.root._clippingPlaneOffsetMatrix)) { tileTransform = tileset.root._clippingPlaneOffsetMatrix; } var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index ebddbe5171a5..ec55d4735a7b 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -80,7 +80,7 @@ define([ * @example * // This clipping plane's distance is positive, which means its normal * // is facing the origin. This will clip everything that is behind - * // the plane, which is all pixels with y > 5. + * // the plane, which is anything with y coordinate > 5. * var clippingPlanes = new Cesium.ClippingPlaneCollection({ * planes : [ * new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 1.0, 0.0), 5.0) @@ -90,7 +90,7 @@ define([ * var entity = viewer.entities.add({ * position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 10000), * model : { - * uri : '../../../../Apps/SampleData/models/CesiumAir/Cesium_Air.glb', + * uri : 'model.gltf', * minimumPixelSize : 128, * maximumScale : 20000, * clippingPlanes : clippingPlanes diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index a57f715465d0..391cebbd8fcb 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -539,7 +539,7 @@ define([ this.clippingPlanes = options.clippingPlanes; // Used for checking if shaders need to be regenerated due to clipping plane changes. this._clippingPlanesState = 0; - // If defined, it's used to position the clipping planes instead of the modelMatrix. + // If defined, use this matrix to position the clipping planes instead of the modelMatrix. // This is so that when models are part of a tileset they all get clipped relative // to the root tile. this._clippingPlaneOffsetMatrix = undefined; @@ -598,7 +598,7 @@ define([ this.opaquePass = defaultValue(options.opaquePass, Pass.OPAQUE); this._computedModelMatrix = new Matrix4(); // Derived from modelMatrix and scale - this._modelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from modelMatrix, scale, and the current view matrix + this._clippingPlaneModelViewMatrix = Matrix4.clone(Matrix4.IDENTITY); // Derived from modelMatrix, scale, and the current view matrix this._initialRadius = undefined; // Radius without model's scale property, model-matrix scale, animations, or skins this._boundingSphere = undefined; this._scaledBoundingSphere = new BoundingSphere(); @@ -3013,7 +3013,7 @@ define([ if (!defined(clippingPlanes)) { return Matrix4.IDENTITY; } - return Matrix4.multiply(model._modelViewMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix); + return Matrix4.multiply(model._clippingPlaneModelViewMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix); }; } @@ -4430,11 +4430,8 @@ define([ var clippingPlanes = this._clippingPlanes; var currentClippingPlanesState = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { - if (!defined(this._clippingPlaneOffsetMatrix)) { - Matrix4.multiply(context.uniformState.view3D, modelMatrix, this._modelViewMatrix); - } else { - Matrix4.multiply(context.uniformState.view3D, this._clippingPlaneOffsetMatrix, this._modelViewMatrix); - } + var clippingPlaneOffsetMatrix = defaultValue(this._clippingPlaneOffsetMatrix, modelMatrix); + Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, this._modelViewMatrix); currentClippingPlanesState = clippingPlanes.clippingPlanesState; } diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index 3577e34cbaab..4b9e86db003d 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -185,7 +185,7 @@ define([ this.clippingPlanes = undefined; this.isClipped = false; this.clippingPlanesDirty = false; - // If defined, it's used to position the clipping planes instead of the modelMatrix. + // If defined, use this matrix to position the clipping planes instead of the modelMatrix. // This is so that when point clouds are part of a tileset they all get clipped relative // to the root tile. this._clippingPlaneOffsetMatrix = undefined; From 2dac9f44d00cc98f8f83d5ed6928e2108e9aa74b Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 12:27:32 -0400 Subject: [PATCH 18/29] Moved clippingPlaneOffsetMatrix to Tileset --- Source/Scene/Batched3DModel3DTileContent.js | 6 +---- Source/Scene/Cesium3DTile.js | 23 +++-------------- Source/Scene/Cesium3DTileset.js | 25 +++++++++++++++++++ Source/Scene/ClippingPlaneCollection.js | 6 ++--- Source/Scene/Instanced3DModel3DTileContent.js | 7 +----- Source/Scene/Model.js | 2 +- Source/Scene/PointCloud.js | 3 +-- Source/Scene/PointCloud3DTileContent.js | 6 +---- 8 files changed, 37 insertions(+), 41 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index f832a2a147de..bbea34485c3a 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -465,11 +465,7 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - if (!this._tileset.root._useBoundingSphereForClipping) { - this._model._clippingPlaneOffsetMatrix = this._tileset.root.computedTransform; - } else { - this._model._clippingPlaneOffsetMatrix = this._tileset.root._clippingPlaneOffsetMatrix; - } + this._model._clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. // This will also trigger synchronous shader regeneration to remove or add the clipping plane and color blending code. diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index d533c9d7c321..c5aaa1fb6dbc 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -334,13 +334,6 @@ define([ this._priority = 0.0; this._isClipped = true; this._clippingPlanesState = 0; // encapsulates (_isClipped, clippingPlanes.enabled) and number/function - this._useBoundingSphereForClipping = false; - // If this is the root tile, and it doesn't have a defined transform, fall back to bounding sphere. - if (!defined(this.parent) && !defined(this._header.transform)) { - this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); - this._useBoundingSphereForClipping = true; - } - this._debugBoundingVolume = undefined; this._debugContentBoundingVolume = undefined; this._debugViewerRequestVolume = undefined; @@ -827,11 +820,7 @@ define([ var tileset = this._tileset; var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { - var tileTransform = tileset.root.computedTransform; - if (defined(tileset.root._clippingPlaneOffsetMatrix)) { - tileTransform = tileset.root._clippingPlaneOffsetMatrix; - } - var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); + var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileset.clippingPlaneOffsetMatrix); this._isClipped = intersection !== Intersect.INSIDE; if (intersection === Intersect.OUTSIDE) { return CullingVolume.MASK_OUTSIDE; @@ -865,11 +854,7 @@ define([ var tileset = this._tileset; var clippingPlanes = tileset.clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { - var tileTransform = tileset.root.computedTransform; - if (defined(tileset.root._clippingPlaneOffsetMatrix)) { - tileTransform = tileset.root._clippingPlaneOffsetMatrix; - } - var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileTransform); + var intersection = clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume, tileset.clippingPlaneOffsetMatrix); this._isClipped = intersection !== Intersect.INSIDE; if (intersection === Intersect.OUTSIDE) { return Intersect.OUTSIDE; @@ -1063,8 +1048,8 @@ define([ this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume); } - if (this._useBoundingSphereForClipping) { - this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); + if (this._tileset._useBoundingSphereForClipping && !defined(this.parent)) { + this._tileset.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); } // Destroy the debug bounding volumes. They will be generated fresh. this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index afda600cbc21..48c8163cf40a 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -18,6 +18,7 @@ define([ '../Core/Matrix4', '../Core/Resource', '../Core/RuntimeError', + '../Core/Transforms', '../Renderer/ClearCommand', '../Renderer/Pass', '../ThirdParty/when', @@ -60,6 +61,7 @@ define([ Matrix4, Resource, RuntimeError, + Transforms, ClearCommand, Pass, when, @@ -209,6 +211,9 @@ define([ this._ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84); + this._useBoundingSphereForClipping = false; + this._clippingPlaneOffsetMatrix = undefined; + /** * Optimization option. Whether the tileset should refine based on a dynamic screen space error. Tiles that are further * away will be rendered with lower detail than closer tiles. This improves performance by rendering fewer @@ -1107,6 +1112,21 @@ define([ } }, + /** + * @private + */ + clippingPlaneOffsetMatrix : { + get : function() { + if (this._useBoundingSphereForClipping) { + return this._clippingPlaneOffsetMatrix; + } + return this.root.computedTransform; + }, + set : function(value) { + this._clippingPlaneOffsetMatrix = Matrix4.clone(value, this._clippingPlaneOffsetMatrix); + } + }, + /** * @private */ @@ -1277,6 +1297,11 @@ define([ } } + if (!defined(rootTile._header.transform)) { + this._useBoundingSphereForClipping = true; + this.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(rootTile.boundingSphere.center); + } + return rootTile; }; diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index ec55d4735a7b..e71ea7706bdf 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -56,8 +56,8 @@ define([ * Specifies a set of clipping planes. Clipping planes selectively disable rendering in a region on the * outside of the specified list of {@link ClippingPlane} objects for a single gltf model, 3D Tileset, or the globe. *

- * In general the clipping planes' coordinates are relative to the object they're attached to, so a plane with distance set to 0 will clip - * through the center of the object. + * In general the clipping planes' coordinates are relative to the object they're attached to, so a plane with distance set to 0 will clip + * through the center of the object. *

*

* For 3D Tiles, the root tile's transform is used to position the clipping planes. If a transform is not defined, the root tile's {@link Cesium3DTile#boundingSphere} is used instead. @@ -79,7 +79,7 @@ define([ * * @example * // This clipping plane's distance is positive, which means its normal - * // is facing the origin. This will clip everything that is behind + * // is facing the origin. This will clip everything that is behind * // the plane, which is anything with y coordinate > 5. * var clippingPlanes = new Cesium.ClippingPlaneCollection({ * planes : [ diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index f9eacae347cc..8516992c780a 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -472,12 +472,7 @@ define([ // Update for clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - // Use the root tile's transform. - if (!this._tileset.root._useBoundingSphereForClipping) { - model._clippingPlaneOffsetMatrix = this._tileset.root.computedTransform; - } else if (this._tileset.ready) { - model._clippingPlaneOffsetMatrix = this._tileset.root._clippingPlaneOffsetMatrix; - } + model._clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. model._clippingPlanes = (tilesetClippingPlanes.enabled && this._tile._isClipped) ? tilesetClippingPlanes : undefined; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index 391cebbd8fcb..e401362c1c7b 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -4431,7 +4431,7 @@ define([ var currentClippingPlanesState = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { var clippingPlaneOffsetMatrix = defaultValue(this._clippingPlaneOffsetMatrix, modelMatrix); - Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, this._modelViewMatrix); + Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, this._clippingPlaneModelViewMatrix); currentClippingPlanesState = clippingPlanes.clippingPlanesState; } diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index 4b9e86db003d..b232417cb185 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -829,8 +829,7 @@ define([ } else { Matrix4.multiply(context.uniformState.view3D, pointCloud._clippingPlaneOffsetMatrix, scratchClippingPlaneMatrix); } - - return Matrix4.multiply(scratchClippingPlaneMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix);; + return Matrix4.multiply(scratchClippingPlaneMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix); } }; diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 7dc139190327..30de6625949d 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -297,11 +297,7 @@ define([ var styleDirty = this._styleDirty; this._styleDirty = false; - if (!tileset.root._useBoundingSphereForClipping) { - pointCloud._clippingPlaneOffsetMatrix = tileset.root.computedTransform; - } else { - pointCloud._clippingPlaneOffsetMatrix = tileset.root._clippingPlaneOffsetMatrix; - } + pointCloud._clippingPlaneOffsetMatrix = tileset.clippingPlaneOffsetMatrix; pointCloud.style = defined(batchTable) ? undefined : tileset.style; pointCloud.styleDirty = styleDirty; From 2fadcf91b938dffa3475b32b56bf68668ae481c2 Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 13:16:12 -0400 Subject: [PATCH 19/29] Updated tests --- Source/Scene/Cesium3DTileset.js | 9 ++++----- Specs/Scene/Cesium3DTilesetSpec.js | 9 +++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 48c8163cf40a..f072b073ee28 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -702,6 +702,10 @@ define([ that._extensionsUsed = tilesetJson.extensionsUsed; that._gltfUpAxis = gltfUpAxis; that._extras = tilesetJson.extras; + if (!defined(tilesetJson.root.transform)) { + that._useBoundingSphereForClipping = true; + that.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(that.boundingSphere.center); + } that._readyPromise.resolve(that); }).otherwise(function(error) { that._readyPromise.reject(error); @@ -1297,11 +1301,6 @@ define([ } } - if (!defined(rootTile._header.transform)) { - this._useBoundingSphereForClipping = true; - this.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(rootTile.boundingSphere.center); - } - return rootTile; }; diff --git a/Specs/Scene/Cesium3DTilesetSpec.js b/Specs/Scene/Cesium3DTilesetSpec.js index c72ffed3cdeb..b572ad57003f 100644 --- a/Specs/Scene/Cesium3DTilesetSpec.js +++ b/Specs/Scene/Cesium3DTilesetSpec.js @@ -3203,22 +3203,23 @@ defineSuite([ it('uses bounding sphere for clipping only if root has no transforms', function() { return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then(function(tileset) { - expect(tileset.root._useBoundingSphereForClipping).toBe(true); + expect(tileset._useBoundingSphereForClipping).toBe(true); return Cesium3DTilesTester.loadTileset(scene, withTransformBoxUrl).then(function(tileset) { - expect(tileset.root._useBoundingSphereForClipping).toBe(false); + expect(tileset._useBoundingSphereForClipping).toBe(false); }); }); }); it('correctly computes clippingPlaneOffsetMatrix', function() { return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then(function(tileset) { - var offsetMatrix = tileset.root._clippingPlaneOffsetMatrix; + var offsetMatrix = tileset.clippingPlaneOffsetMatrix; var boundingSphereMatrix = Transforms.eastNorthUpToFixedFrame(tileset.root.boundingSphere.center); expect(Matrix4.equals(offsetMatrix,boundingSphereMatrix)).toBe(true); return Cesium3DTilesTester.loadTileset(scene, withTransformBoxUrl).then(function(tileset) { - expect(tileset.root._clippingPlaneOffsetMatrix).toBeUndefined(); + offsetMatrix = tileset.clippingPlaneOffsetMatrix; + expect(Matrix4.equals(offsetMatrix,tileset.root.computedTransform)).toBe(true); }); }); }); From b251c6b273a2fbf67db06bda81588c9f22cf061e Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 15:25:47 -0400 Subject: [PATCH 20/29] Fixed old clipping planes test --- Specs/Scene/ModelSpec.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 62d066ffbf7f..03d9887df11a 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -2848,7 +2848,7 @@ defineSuite([ scene.renderForSpecs(); var callsBeforeClipping = gl.texImage2D.calls.count(); - expect(model._modelViewMatrix).toEqual(Matrix4.IDENTITY); + expect(model._clippingPlaneModelViewMatrix).toEqual(Matrix4.IDENTITY); model.clippingPlanes = new ClippingPlaneCollection({ planes : [ @@ -2858,7 +2858,10 @@ defineSuite([ model.update(scene.frameState); scene.renderForSpecs(); - expect(gl.texImage2D.calls.count() - callsBeforeClipping * 2).toEqual(2); + // When clipping planes are created, we expect two calls to texImage2D + // (one for initial creation, and one for copying the data in) + // because clipping planes is stored inside a texture. + expect(gl.texImage2D.calls.count() - callsBeforeClipping).toEqual(2); primitives.remove(model); }); From e879cca2df7dbb931034c76270f063889033bdab Mon Sep 17 00:00:00 2001 From: Omar Shehata Date: Wed, 19 Sep 2018 15:58:47 -0400 Subject: [PATCH 21/29] Fix lint --- Specs/Scene/ModelSpec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Specs/Scene/ModelSpec.js b/Specs/Scene/ModelSpec.js index 03d9887df11a..05bc03f51e5e 100644 --- a/Specs/Scene/ModelSpec.js +++ b/Specs/Scene/ModelSpec.js @@ -2858,9 +2858,9 @@ defineSuite([ model.update(scene.frameState); scene.renderForSpecs(); - // When clipping planes are created, we expect two calls to texImage2D - // (one for initial creation, and one for copying the data in) - // because clipping planes is stored inside a texture. + // When clipping planes are created, we expect two calls to texImage2D + // (one for initial creation, and one for copying the data in) + // because clipping planes is stored inside a texture. expect(gl.texImage2D.calls.count() - callsBeforeClipping).toEqual(2); primitives.remove(model); From 5245643f5e765b7ce22e7762230353d2bdfbfdfe Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 09:09:03 -0400 Subject: [PATCH 22/29] Remove underscore from _clippingPlaneOffsetMatrix --- Source/Scene/Batched3DModel3DTileContent.js | 2 +- Source/Scene/Instanced3DModel3DTileContent.js | 2 +- Source/Scene/Model.js | 4 ++-- Source/Scene/PointCloud.js | 9 +++------ Source/Scene/PointCloud3DTileContent.js | 2 +- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/Source/Scene/Batched3DModel3DTileContent.js b/Source/Scene/Batched3DModel3DTileContent.js index bbea34485c3a..7566e3a67850 100644 --- a/Source/Scene/Batched3DModel3DTileContent.js +++ b/Source/Scene/Batched3DModel3DTileContent.js @@ -465,7 +465,7 @@ define([ // Update clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - this._model._clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; + this._model.clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant. // Link/Dereference directly to avoid ownership checks. // This will also trigger synchronous shader regeneration to remove or add the clipping plane and color blending code. diff --git a/Source/Scene/Instanced3DModel3DTileContent.js b/Source/Scene/Instanced3DModel3DTileContent.js index 8516992c780a..d10ef66f480e 100644 --- a/Source/Scene/Instanced3DModel3DTileContent.js +++ b/Source/Scene/Instanced3DModel3DTileContent.js @@ -472,7 +472,7 @@ define([ // Update for clipping planes var tilesetClippingPlanes = this._tileset.clippingPlanes; if (this._tile.clippingPlanesDirty && defined(tilesetClippingPlanes)) { - model._clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; + model.clippingPlaneOffsetMatrix = this._tileset.clippingPlaneOffsetMatrix; // Dereference the clipping planes from the model if they are irrelevant - saves on shading // Link/Dereference directly to avoid ownership checks. model._clippingPlanes = (tilesetClippingPlanes.enabled && this._tile._isClipped) ? tilesetClippingPlanes : undefined; diff --git a/Source/Scene/Model.js b/Source/Scene/Model.js index e401362c1c7b..3d23693c3e1a 100644 --- a/Source/Scene/Model.js +++ b/Source/Scene/Model.js @@ -542,7 +542,7 @@ define([ // If defined, use this matrix to position the clipping planes instead of the modelMatrix. // This is so that when models are part of a tileset they all get clipped relative // to the root tile. - this._clippingPlaneOffsetMatrix = undefined; + this.clippingPlaneOffsetMatrix = undefined; /** * This property is for debugging only; it is not for production use nor is it optimized. @@ -4430,7 +4430,7 @@ define([ var clippingPlanes = this._clippingPlanes; var currentClippingPlanesState = 0; if (defined(clippingPlanes) && clippingPlanes.enabled) { - var clippingPlaneOffsetMatrix = defaultValue(this._clippingPlaneOffsetMatrix, modelMatrix); + var clippingPlaneOffsetMatrix = defaultValue(this.clippingPlaneOffsetMatrix, modelMatrix); Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, this._clippingPlaneModelViewMatrix); currentClippingPlanesState = clippingPlanes.clippingPlanesState; } diff --git a/Source/Scene/PointCloud.js b/Source/Scene/PointCloud.js index b232417cb185..2edd8c05735d 100644 --- a/Source/Scene/PointCloud.js +++ b/Source/Scene/PointCloud.js @@ -188,7 +188,7 @@ define([ // If defined, use this matrix to position the clipping planes instead of the modelMatrix. // This is so that when point clouds are part of a tileset they all get clipped relative // to the root tile. - this._clippingPlaneOffsetMatrix = undefined; + this.clippingPlaneOffsetMatrix = undefined; this.attenuation = false; this._attenuation = false; @@ -824,11 +824,8 @@ define([ return Matrix4.IDENTITY; } - if (!defined(pointCloud._clippingPlaneOffsetMatrix)) { - Matrix4.multiply(context.uniformState.view3D, pointCloud._modelMatrix, scratchClippingPlaneMatrix); - } else { - Matrix4.multiply(context.uniformState.view3D, pointCloud._clippingPlaneOffsetMatrix, scratchClippingPlaneMatrix); - } + var clippingPlaneOffsetMatrix = defaultValue(pointCloud.clippingPlaneOffsetMatrix, pointCloud._modelMatrix); + Matrix4.multiply(context.uniformState.view3D, clippingPlaneOffsetMatrix, scratchClippingPlaneMatrix); return Matrix4.multiply(scratchClippingPlaneMatrix, clippingPlanes.modelMatrix, scratchClippingPlaneMatrix); } }; diff --git a/Source/Scene/PointCloud3DTileContent.js b/Source/Scene/PointCloud3DTileContent.js index 30de6625949d..6ef13b2dc634 100644 --- a/Source/Scene/PointCloud3DTileContent.js +++ b/Source/Scene/PointCloud3DTileContent.js @@ -297,7 +297,7 @@ define([ var styleDirty = this._styleDirty; this._styleDirty = false; - pointCloud._clippingPlaneOffsetMatrix = tileset.clippingPlaneOffsetMatrix; + pointCloud.clippingPlaneOffsetMatrix = tileset.clippingPlaneOffsetMatrix; pointCloud.style = defined(batchTable) ? undefined : tileset.style; pointCloud.styleDirty = styleDirty; From 65a849637b4dc1d2e023619b0900b0c5f6495620 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 09:12:18 -0400 Subject: [PATCH 23/29] Moved clippingPlaneOffset update to tileset --- Source/Scene/Cesium3DTile.js | 3 --- Source/Scene/Cesium3DTileset.js | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Scene/Cesium3DTile.js b/Source/Scene/Cesium3DTile.js index c5aaa1fb6dbc..113fc0d7acc2 100644 --- a/Source/Scene/Cesium3DTile.js +++ b/Source/Scene/Cesium3DTile.js @@ -1048,9 +1048,6 @@ define([ this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume); } - if (this._tileset._useBoundingSphereForClipping && !defined(this.parent)) { - this._tileset.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); - } // Destroy the debug bounding volumes. They will be generated fresh. this._debugBoundingVolume = this._debugBoundingVolume && this._debugBoundingVolume.destroy(); this._debugContentBoundingVolume = this._debugContentBoundingVolume && this._debugContentBoundingVolume.destroy(); diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index f072b073ee28..5ba9eae27801 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -1832,6 +1832,9 @@ define([ var clippingPlanes = this._clippingPlanes; if (defined(clippingPlanes) && clippingPlanes.enabled) { clippingPlanes.update(frameState); + if (this._useBoundingSphereForClipping) { + this.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); + } } this._timeSinceLoad = Math.max(JulianDate.secondsDifference(frameState.time, this._loadTimestamp) * 1000, 0.0); From 3cc7aa0135b708926c3a159d8cb0e2845d47eee5 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 13:14:53 -0400 Subject: [PATCH 24/29] No need to use setter for clippingPlaneOffsetMatrix --- Source/Scene/Cesium3DTileset.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Scene/Cesium3DTileset.js b/Source/Scene/Cesium3DTileset.js index 5ba9eae27801..eee397109f6b 100644 --- a/Source/Scene/Cesium3DTileset.js +++ b/Source/Scene/Cesium3DTileset.js @@ -704,7 +704,7 @@ define([ that._extras = tilesetJson.extras; if (!defined(tilesetJson.root.transform)) { that._useBoundingSphereForClipping = true; - that.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(that.boundingSphere.center); + that._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(that.boundingSphere.center); } that._readyPromise.resolve(that); }).otherwise(function(error) { @@ -1125,9 +1125,6 @@ define([ return this._clippingPlaneOffsetMatrix; } return this.root.computedTransform; - }, - set : function(value) { - this._clippingPlaneOffsetMatrix = Matrix4.clone(value, this._clippingPlaneOffsetMatrix); } }, @@ -1833,7 +1830,7 @@ define([ if (defined(clippingPlanes) && clippingPlanes.enabled) { clippingPlanes.update(frameState); if (this._useBoundingSphereForClipping) { - this.clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); + this._clippingPlaneOffsetMatrix = Transforms.eastNorthUpToFixedFrame(this.boundingSphere.center); } } From 888e2b2f2df090aacfb92088aa272755137b129c Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 13:26:07 -0400 Subject: [PATCH 25/29] Added breaking change to CHANGES.md --- CHANGES.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index bf2ba5572d65..466c0803d678 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,14 @@ Change Log ### 1.50 - 2018-10-01 +##### Breaking Changes :mega: +* Clipping planes on tilesets now use the root tile's transform, or the root tile's bounding sphere if a transform is not defined. [#7034](https://github.com/AnalyticalGraphicsInc/cesium/pull/7034) + * This is to make clipping planes' coordinates always relative to the object they're attached to. So if you were positioning the clipping planes as in the example below, this is no longer necessary: + ```javascript + clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center); + ``` + * This also fixes several issues with clipping planes not using the correct transform for tilesets with children. + ##### Additions :tada: * Added `cartographicLimitRectangle` to `Globe`. Use this to limit terrain and imagery to a specific `Rectangle` area. [#6987](https://github.com/AnalyticalGraphicsInc/cesium/pull/6987) From f56c71c53703428cc7f3428a1ed4ea0bdb7aa514 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 17:16:52 -0400 Subject: [PATCH 26/29] Fix sign in doc --- Source/Scene/ClippingPlaneCollection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index e71ea7706bdf..9ecb931f4cdd 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -80,7 +80,7 @@ define([ * @example * // This clipping plane's distance is positive, which means its normal * // is facing the origin. This will clip everything that is behind - * // the plane, which is anything with y coordinate > 5. + * // the plane, which is anything with y coordinate < -5. * var clippingPlanes = new Cesium.ClippingPlaneCollection({ * planes : [ * new Cesium.ClippingPlane(new Cesium.Cartesian3(0.0, 1.0, 0.0), 5.0) From 911a520142c13b8d00ef117220f00df2d059eab0 Mon Sep 17 00:00:00 2001 From: Shehata Date: Thu, 20 Sep 2018 18:46:17 -0400 Subject: [PATCH 27/29] Reworded unionClippingRegions --- Source/Scene/ClippingPlaneCollection.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index 9ecb931f4cdd..f5014202e174 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -70,7 +70,7 @@ define([ * @param {ClippingPlane[]} [options.planes=[]] An array of {@link ClippingPlane} objects used to selectively disable rendering on the outside of each plane. * @param {Boolean} [options.enabled=true] Determines whether the clipping planes are active. * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix specifying an additional transform relative to the clipping planes original coordinate system. - * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if included in any plane in the collection. Otherwise, the region to be clipped must intersect the regions defined by all planes in this collection. + * @param {Boolean} [options.unionClippingRegions=false] If true, a region will be clipped if it is on the outside of any plane in the collection. Otherwise, a region will only be clipped if it is on the outside of every plane. * @param {Color} [options.edgeColor=Color.WHITE] The color applied to highlight the edge along which an object is clipped. * @param {Number} [options.edgeWidth=0.0] The width, in pixels, of the highlight applied to the edge along which an object is clipped. * From a43ab57a2622bd5c3489c638fe87f8c6baaf0a02 Mon Sep 17 00:00:00 2001 From: Shehata Date: Fri, 21 Sep 2018 11:19:50 -0400 Subject: [PATCH 28/29] Fix edge color for union clipping planes --- Source/Scene/getClippingFunction.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Scene/getClippingFunction.js b/Source/Scene/getClippingFunction.js index c694f7648b26..23bab2675487 100644 --- a/Source/Scene/getClippingFunction.js +++ b/Source/Scene/getClippingFunction.js @@ -44,7 +44,7 @@ define([ ' vec4 position = czm_windowToEyeCoordinates(fragCoord);\n' + ' vec3 clipNormal = vec3(0.0);\n' + ' vec3 clipPosition = vec3(0.0);\n' + - ' float clipAmount = 0.0;\n' + + ' float clipAmount;\n' + // For union planes, we want to get the min distance. So we set the initial value to the first plane distance in the loop below. ' float pixelWidth = czm_metersPerPixel(position);\n' + ' bool breakAndDiscard = false;\n' + @@ -56,7 +56,7 @@ define([ ' clipPosition = -clippingPlane.w * clipNormal;\n' + ' float amount = dot(clipNormal, (position.xyz - clipPosition)) / pixelWidth;\n' + - ' clipAmount = max(amount, clipAmount);\n' + + ' clipAmount = czm_branchFreeTernary(i == 0, amount, min(amount, clipAmount));\n' + ' if (amount <= 0.0)\n' + ' {\n' + From 79a49e09a89141653bcd557ba5f9804aaa1caaa7 Mon Sep 17 00:00:00 2001 From: Shehata Date: Fri, 21 Sep 2018 11:59:00 -0400 Subject: [PATCH 29/29] Added terrain union example --- .../gallery/Terrain Clipping Planes.html | 25 ++++++++++++++++++- Source/Scene/ClippingPlaneCollection.js | 5 ++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html index d0347d0a1501..40ac90b42d79 100644 --- a/Apps/Sandcastle/gallery/Terrain Clipping Planes.html +++ b/Apps/Sandcastle/gallery/Terrain Clipping Planes.html @@ -52,7 +52,7 @@ }); var globe = viewer.scene.globe; -var exampleTypes = ['Cesium Man', 'St. Helens']; +var exampleTypes = ['Cesium Man', 'St. Helens', 'Grand Canyon Isolated']; var viewModel = { exampleTypes : exampleTypes, currentExampleType : exampleTypes[0], @@ -191,6 +191,27 @@ }); } +function loadGrandCanyon(){ + // Pick a position at the Grand Canyon + var position = Cesium.Cartographic.toCartesian(new Cesium.Cartographic.fromDegrees(-113.2665534, 36.0939345, 100)); + var distance = 3000.0; + var boundingSphere = new Cesium.BoundingSphere(position, distance); + + globe.clippingPlanes = new Cesium.ClippingPlaneCollection({ + modelMatrix : Cesium.Transforms.eastNorthUpToFixedFrame(position), + planes : [ + new Cesium.ClippingPlane(new Cesium.Cartesian3( 1.0, 0.0, 0.0), distance), + new Cesium.ClippingPlane(new Cesium.Cartesian3(-1.0, 0.0, 0.0), distance), + new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0, 1.0, 0.0), distance), + new Cesium.ClippingPlane(new Cesium.Cartesian3( 0.0, -1.0, 0.0), distance) + ], + unionClippingRegions : true + }); + + viewer.camera.viewBoundingSphere(boundingSphere, new Cesium.HeadingPitchRange(0.5, -0.5, boundingSphere.radius * 5.0)); + viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY); +} + Cesium.knockout.getObservable(viewModel, 'clippingPlanesEnabled').subscribe(function(value) { globe.clippingPlanes.enabled = value; clippingPlanesEnabled = value; @@ -207,6 +228,8 @@ loadCesiumMan(); } else if (newValue === exampleTypes[1]) { loadStHelens(); + } else if (newValue === exampleTypes[2]) { + loadGrandCanyon(); } }); diff --git a/Source/Scene/ClippingPlaneCollection.js b/Source/Scene/ClippingPlaneCollection.js index f5014202e174..31d9265dff91 100644 --- a/Source/Scene/ClippingPlaneCollection.js +++ b/Source/Scene/ClippingPlaneCollection.js @@ -199,8 +199,9 @@ define([ }, /** - * If true, a region will be clipped if included in any plane in the collection. Otherwise, the region - * to be clipped must intersect the regions defined by all planes in this collection. + * If true, a region will be clipped if it is on the outside of any plane in the + * collection. Otherwise, a region will only be clipped if it is on the + * outside of every plane. * * @memberof ClippingPlaneCollection.prototype * @type {Boolean}