diff --git a/Cesium3DTilesContent/include/Cesium3DTilesContent/ImplicitTilingUtilities.h b/Cesium3DTilesContent/include/Cesium3DTilesContent/ImplicitTilingUtilities.h index 364c46487..8e943f28a 100644 --- a/Cesium3DTilesContent/include/Cesium3DTilesContent/ImplicitTilingUtilities.h +++ b/Cesium3DTilesContent/include/Cesium3DTilesContent/ImplicitTilingUtilities.h @@ -15,6 +15,7 @@ class S2CellBoundingVolume; namespace CesiumGeometry { class OrientedBoundingBox; +class BoundingCylinder; } namespace Cesium3DTiles { diff --git a/Cesium3DTilesContent/src/ImplicitTilingUtilities.cpp b/Cesium3DTilesContent/src/ImplicitTilingUtilities.cpp index b3c952ac4..f4d7e32c7 100644 --- a/Cesium3DTilesContent/src/ImplicitTilingUtilities.cpp +++ b/Cesium3DTilesContent/src/ImplicitTilingUtilities.cpp @@ -170,15 +170,16 @@ Cesium3DTiles::BoundingVolume computeBoundingVolumeInternal( } std::optional maybeCylinder = - TileBoundingVolumes::getBoundingCylinder(rootBoundingVolume, ellipsoid); + TileBoundingVolumes::getBoundingCylinder(rootBoundingVolume); if (maybeCylinder) { BoundingCylinder cylinder = - ImplicitTilingUtilities::computeBoundingVolume(*maybeCylinder tileID); - TileBoundingVolumes::setBoundingCylinder(result, maybeCylinder); + ImplicitTilingUtilities::computeBoundingVolume(*maybeCylinder, tileID); + TileBoundingVolumes::setBoundingCylinder(result, cylinder); } return result; } + } // namespace Cesium3DTiles::BoundingVolume ImplicitTilingUtilities::computeBoundingVolume( diff --git a/Cesium3DTilesSelection/src/ImplicitOctreeLoader.cpp b/Cesium3DTilesSelection/src/ImplicitOctreeLoader.cpp index e9b8d7d58..16537f3a6 100644 --- a/Cesium3DTilesSelection/src/ImplicitOctreeLoader.cpp +++ b/Cesium3DTilesSelection/src/ImplicitOctreeLoader.cpp @@ -29,6 +29,12 @@ struct BoundingVolumeSubdivision { return ImplicitTilingUtilities::computeBoundingVolume(obb, this->tileID); } + BoundingVolume operator()(const CesiumGeometry::BoundingCylinder& cylinder) { + return ImplicitTilingUtilities::computeBoundingVolume( + cylinder, + this->tileID); + } + const CesiumGeometry::OctreeTileID& tileID; const CesiumGeospatial::Ellipsoid& ellipsoid; }; diff --git a/Cesium3DTilesSelection/src/ImplicitOctreeLoader.h b/Cesium3DTilesSelection/src/ImplicitOctreeLoader.h index f11e7670e..199732fd0 100644 --- a/Cesium3DTilesSelection/src/ImplicitOctreeLoader.h +++ b/Cesium3DTilesSelection/src/ImplicitOctreeLoader.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -15,7 +16,8 @@ namespace Cesium3DTilesSelection { using ImplicitOctreeBoundingVolume = std::variant< CesiumGeospatial::BoundingRegion, - CesiumGeometry::OrientedBoundingBox>; + CesiumGeometry::OrientedBoundingBox, + CesiumGeometry::BoundingCylinder>; class ImplicitOctreeLoader : public TilesetContentLoader { public: diff --git a/Cesium3DTilesSelection/src/TilesetHeightQuery.cpp b/Cesium3DTilesSelection/src/TilesetHeightQuery.cpp index 65934d73e..00c4fa0da 100644 --- a/Cesium3DTilesSelection/src/TilesetHeightQuery.cpp +++ b/Cesium3DTilesSelection/src/TilesetHeightQuery.cpp @@ -52,6 +52,13 @@ bool boundingVolumeContainsCoordinate( return s2Cell.computeBoundingRegion(ellipsoid).getRectangle().contains( coordinate); } + + bool operator()(const BoundingCylinder& cylinder) noexcept { + std::optional t = IntersectionTests::rayOBBParametric( + ray, + OrientedBoundingBox::fromCylinder(cylinder)); + return t && t.value() >= 0; + } }; return std::visit(Operation{ray, coordinate, ellipsoid}, boundingVolume); diff --git a/Cesium3DTilesSelection/src/TilesetJsonLoader.cpp b/Cesium3DTilesSelection/src/TilesetJsonLoader.cpp index 0414e0261..97ead6f87 100644 --- a/Cesium3DTilesSelection/src/TilesetJsonLoader.cpp +++ b/Cesium3DTilesSelection/src/TilesetJsonLoader.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -295,6 +296,8 @@ void createImplicitOctreeLoader( std::get_if(&boundingVolume); const CesiumGeometry::OrientedBoundingBox* pBox = std::get_if(&boundingVolume); + const CesiumGeometry::BoundingCylinder* pCylinder = + std::get_if(&boundingVolume); // the implicit loader will be the child loader of this tileset json loader TilesetContentLoader* pImplicitLoader = nullptr; @@ -318,6 +321,16 @@ void createImplicitOctreeLoader( *pBox); pImplicitLoader = pLoader.get(); currentLoader.addChildLoader(std::move(pLoader)); + } else if (pCylinder) { + auto pLoader = std::make_unique( + currentLoader.getBaseUrl(), + contentUriTemplate, + subtreeUriTemplate, + subtreeLevels, + availableLevels, + *pCylinder); + pImplicitLoader = pLoader.get(); + currentLoader.addChildLoader(std::move(pLoader)); } // create an implicit root to associate with the above implicit loader diff --git a/Cesium3DTilesSelection/src/ViewState.cpp b/Cesium3DTilesSelection/src/ViewState.cpp index e72a8720e..c5b345814 100644 --- a/Cesium3DTilesSelection/src/ViewState.cpp +++ b/Cesium3DTilesSelection/src/ViewState.cpp @@ -120,6 +120,12 @@ bool ViewState::isBoundingVolumeVisible( s2Cell, viewState._cullingVolume); } + + bool operator()(const BoundingCylinder& cylinder) noexcept { + return Cesium3DTilesSelection::isBoundingVolumeVisible( + cylinder, + viewState._cullingVolume); + } }; return std::visit(Operation{*this}, boundingVolume); @@ -165,6 +171,10 @@ double ViewState::computeDistanceSquaredToBoundingVolume( double operator()(const S2CellBoundingVolume& s2Cell) noexcept { return s2Cell.computeDistanceSquaredToPosition(viewState._position); } + + double operator()(const BoundingCylinder& cylinder) noexcept { + return cylinder.computeDistanceSquaredToPosition(viewState._position); + } }; return std::visit(Operation{*this}, boundingVolume);