diff --git a/CHANGES.md b/CHANGES.md index 994759f22..44678254f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ##### Fixes :wrench: - Fixed a bug introduced in v0.7.0 where Bing credits were not being collected. +- Fixed a bug where disabling frustum culling caused external tilesets to not load. ### v0.7.0 - 2021-09-01 diff --git a/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tile.h b/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tile.h index 871aff6c5..56f7cded6 100644 --- a/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tile.h +++ b/Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tile.h @@ -12,8 +12,10 @@ #include "CesiumGeospatial/Projection.h" #include "CesiumUtility/DoublyLinkedList.h" #include +#include #include #include +#include #include #include #include @@ -294,6 +296,29 @@ class CESIUM3DTILESSELECTION_API Tile final { this->_geometricError = value; } + /** + * @brief Returns whether to unconditionally refine this tile. + * + * This is useful in cases such as with external tilesets, where instead of a + * tile having any content, it points to an external tileset's root. So the + * tile always needs to be refined otherwise the external tileset will not be + * displayed. + * + * @return Whether to uncoditionally refine this tile. + */ + bool getUnconditionallyRefine() const noexcept { + return glm::isinf(this->_geometricError); + } + + /** + * @brief Marks that this tile should be unconditionally refined. + * + * This function is not supposed to be called by clients. + */ + void setUnconditionallyRefine() noexcept { + this->_geometricError = std::numeric_limits::infinity(); + } + /** * @brief The refinement strategy of this tile. * diff --git a/Cesium3DTilesSelection/src/Tile.cpp b/Cesium3DTilesSelection/src/Tile.cpp index 8c362792e..adf97102f 100644 --- a/Cesium3DTilesSelection/src/Tile.cpp +++ b/Cesium3DTilesSelection/src/Tile.cpp @@ -629,12 +629,12 @@ void Tile::update( std::move(this->_pContent->pNewTileContext)); } - // If this tile has no model, set its geometric error very high so we - // refine past it. Note that "no" model is different from having a model, - // but it is blank. In the latter case, we'll happily render nothing in - // the space of this tile, which is sometimes useful. + // If this tile has no model, we want to unconditionally refine past it. + // Note that "no" model is different from having a model, but it is blank. + // In the latter case, we'll happily render nothing in the space of this + // tile, which is sometimes useful. if (!this->_pContent->model) { - this->setGeometricError(999999999.0); + this->setUnconditionallyRefine(); } // A new and improved bounding volume. diff --git a/Cesium3DTilesSelection/src/Tileset.cpp b/Cesium3DTilesSelection/src/Tileset.cpp index eeb15bb66..fd7ed4564 100644 --- a/Cesium3DTilesSelection/src/Tileset.cpp +++ b/Cesium3DTilesSelection/src/Tileset.cpp @@ -1682,11 +1682,13 @@ Tileset::TraversalDetails Tileset::_visitTile( return _renderLeaf(frameState, tile, distances, result); } + bool unconditionallyRefine = tile.getUnconditionallyRefine(); bool meetsSse = _meetsSse(frameState.frustums, tile, distances, culled); bool waitingForChildren = _queueLoadOfChildrenRequiredForRefinement(frameState, tile, distances); - if (meetsSse || ancestorMeetsSse || waitingForChildren) { + if (!unconditionallyRefine && + (meetsSse || ancestorMeetsSse || waitingForChildren)) { // This tile (or an ancestor) is the one we want to render this frame, but // we'll do different things depending on the state of this tile and on what // we did _last_ frame. diff --git a/Cesium3DTilesSelection/test/TestTilesetSelectionAlgorithm.cpp b/Cesium3DTilesSelection/test/TestTilesetSelectionAlgorithm.cpp index 0d07514f7..5e4dc1e4e 100644 --- a/Cesium3DTilesSelection/test/TestTilesetSelectionAlgorithm.cpp +++ b/Cesium3DTilesSelection/test/TestTilesetSelectionAlgorithm.cpp @@ -628,9 +628,8 @@ TEST_CASE("Test additive refinement") { "tileset3/tileset3.json") { REQUIRE(doesTileMeetSSE(viewState, child, tileset)); } else { - // external tileset has always geometric error over 999999, so it - // won't meet sse - REQUIRE(!doesTileMeetSSE(viewState, child, tileset)); + // external tilesets get unconditionally refined + REQUIRE(root->getUnconditionallyRefine()); // expect the children to meet sse and begin loading the content REQUIRE(child.getChildren().size() == 1);