Skip to content

Commit

Permalink
Merge pull request #752 from CesiumGS/quantized-and-implicit
Browse files Browse the repository at this point in the history
Expose implicit tiling related functionality
  • Loading branch information
j9liu authored Nov 15, 2023
2 parents 007fe0b + bf812c9 commit 36b8cae
Show file tree
Hide file tree
Showing 14 changed files with 1,501 additions and 480 deletions.
5 changes: 2 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@
- Added `transform` method to `CesiumGeometry::BoundingSphere`.
- Added `toSphere`, `fromSphere`, and `fromAxisAligned` methods to `CesiumGeometry::OrientedBoundingBox`.
- Added `TileTransform` class to `Cesium3DTilesContent`, making it easier to create a `glm::dmat4` from the `transform` property of a `Cesium3DTiles::Tile`.
- Added `ImplicitTilingUtilities` class to `Cesium3DTilesContent`.
- Added overloads of `isTileAvailable` and `isContentAvailable` on the `SubtreeAvailability` class that take the subtree root tile ID and the tile ID of interest, instead of a relative level and Morton index.

##### Fixes :wrench:

- Fixed a bug in `OrientedBoundingBox::contains` where it didn't account for the bounding box's center.

##### Fixes :wrench:

- Fixed compiler error when calling `PropertyAttributeView::forEachProperty`.

### v0.29.0 - 2023-11-01
Expand Down
6 changes: 6 additions & 0 deletions Cesium3DTilesContent/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ target_link_libraries(Cesium3DTilesContent
CesiumUtility
)

target_link_libraries_system(
Cesium3DTilesContent
PRIVATE
libmorton
)

install(TARGETS Cesium3DTilesContent
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/Cesium3DTilesContent
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,351 @@
#pragma once

#include <CesiumGeometry/OctreeTileID.h>
#include <CesiumGeometry/QuadtreeTileID.h>

#include <array>
#include <iterator>
#include <string>

namespace CesiumGeospatial {
class BoundingRegion;
class S2CellBoundingVolume;
} // namespace CesiumGeospatial

namespace CesiumGeometry {
class OrientedBoundingBox;
}

namespace Cesium3DTilesContent {

/**
* @brief A lightweight virtual container enumerating the quadtree IDs of the
* children of a given quadtree tile.
*/
class QuadtreeChildren {
public:
class iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = CesiumGeometry::QuadtreeTileID;
using difference_type = void;
using pointer = CesiumGeometry::QuadtreeTileID*;
using reference = CesiumGeometry::QuadtreeTileID&;

explicit iterator(
const CesiumGeometry::QuadtreeTileID& parentTileID,
bool isFirst) noexcept;

const CesiumGeometry::QuadtreeTileID& operator*() const {
return this->_current;
}
const CesiumGeometry::QuadtreeTileID* operator->() const {
return &this->_current;
}
iterator& operator++();
iterator operator++(int);

bool operator==(const iterator& rhs) const noexcept;
bool operator!=(const iterator& rhs) const noexcept;

private:
CesiumGeometry::QuadtreeTileID _current;
};

using const_iterator = iterator;

QuadtreeChildren(const CesiumGeometry::QuadtreeTileID& tileID) noexcept
: _tileID(tileID) {}
iterator begin() const noexcept;
iterator end() const noexcept;
constexpr int64_t size() const noexcept { return 4; }

private:
CesiumGeometry::QuadtreeTileID _tileID;
};

/**
* @brief A lightweight virtual container enumerating the octree IDs of the
* children of a given octree tile.
*/
class OctreeChildren {
public:
class iterator {
public:
using iterator_category = std::forward_iterator_tag;
using value_type = CesiumGeometry::OctreeTileID;
using difference_type = void;
using pointer = CesiumGeometry::OctreeTileID*;
using reference = CesiumGeometry::OctreeTileID&;

explicit iterator(
const CesiumGeometry::OctreeTileID& parentTileID,
bool isFirst) noexcept;

const CesiumGeometry::OctreeTileID& operator*() const {
return this->_current;
}
const CesiumGeometry::OctreeTileID* operator->() const {
return &this->_current;
}
iterator& operator++();
iterator operator++(int);

bool operator==(const iterator& rhs) const noexcept;
bool operator!=(const iterator& rhs) const noexcept;

private:
CesiumGeometry::OctreeTileID _current;
};

using const_iterator = iterator;

OctreeChildren(const CesiumGeometry::OctreeTileID& tileID) noexcept
: _tileID(tileID) {}
iterator begin() const noexcept;
iterator end() const noexcept;
constexpr int64_t size() const noexcept { return 8; }

private:
CesiumGeometry::OctreeTileID _tileID;
};

/**
* @brief Helper functions for working with 3D Tiles implicit tiling.
*/
class ImplicitTilingUtilities {
public:
/**
* @brief Resolves a templatized implicit tiling URL with a quadtree tile ID.
*
* @param baseUrl The base URL that is used to resolve the urlTemplate if it
* is a relative path.
* @param urlTemplate The templatized URL.
* @param quadtreeID The quadtree ID to use in resolving the parameters in the
* URL template.
* @return The resolved URL.
*/
static std::string resolveUrl(
const std::string& baseUrl,
const std::string& urlTemplate,
const CesiumGeometry::QuadtreeTileID& quadtreeID);

/**
* @brief Resolves a templatized implicit tiling URL with an octree tile ID.
*
* @param baseUrl The base URL that is used to resolve the urlTemplate if it
* is a relative path.
* @param urlTemplate The templatized URL.
* @param octreeID The octree ID to use in resolving the parameters in the
* URL template.
* @return The resolved URL.
*/
static std::string resolveUrl(
const std::string& baseUrl,
const std::string& urlTemplate,
const CesiumGeometry::OctreeTileID& octreeID);

/**
* @brief Computes the denominator for a given implicit tile level.
*
* Divide the root tile's geometric error by this value to get the standard
* geometric error for tiles on the level. Or divide each component of a
* bounding volume by this factor to get the size of the bounding volume along
* that axis for tiles of this level.
*
* @param level The tile level.
* @return The denominator for the level.
*/
static double computeLevelDenominator(uint32_t level) noexcept;

/**
* @brief Computes the Morton index for a given quadtree tile within its
* level.
*
* @param tileID The ID of the tile.
* @return The Morton index.
*/
static uint64_t
computeMortonIndex(const CesiumGeometry::QuadtreeTileID& tileID);

/**
* @brief Computes the Morton index for a given octree tile within its level.
*
* @param tileID The ID of the tile.
* @return The Morton index.
*/
static uint64_t
computeMortonIndex(const CesiumGeometry::OctreeTileID& tileID);

/**
* @brief Computes the relative Morton index for a given quadtree tile within
* its level of a subtree root at the tile with the given quadtree ID.
*
* @param subtreeID The ID of the subtree the contains the tile.
* @param tileID The ID of the tile.
* @return The relative Morton index.
*/
static uint64_t computeRelativeMortonIndex(
const CesiumGeometry::QuadtreeTileID& subtreeID,
const CesiumGeometry::QuadtreeTileID& tileID);

/**
* @brief Computes the relative Morton index for a given octree tile within
* its level of a subtree rooted at the tile with the given octree ID.
*
* @param subtreeID The ID of the subtree the contains the tile.
* @param tileID The ID of the tile.
* @return The relative Morton index.
*/
static uint64_t computeRelativeMortonIndex(
const CesiumGeometry::OctreeTileID& subtreeRootID,
const CesiumGeometry::OctreeTileID& tileID);

/**
* @brief Gets the ID of the root tile of the subtree that contains a given
* tile.
*
* @param subtreeLevels The number of levels in each sub-tree. For example, if
* this parameter is 4, then the first subtree starts at level 0 and
* contains tiles in levels 0 through 3, and the next subtree starts at
* level 4 and contains tiles in levels 4 through 7.
* @param tileID The tile ID for each to find the subtree root.
* @return The ID of the root tile of the subtree.
*/
static CesiumGeometry::QuadtreeTileID getSubtreeRootID(
uint32_t subtreeLevels,
const CesiumGeometry::QuadtreeTileID& tileID) noexcept;

/**
* @brief Gets the ID of the root tile of the subtree that contains a given
* tile.
*
* @param subtreeLevels The number of levels in each sub-tree. For example, if
* this parameter is 4, then the first subtree starts at level 0 and
* contains tiles in levels 0 through 3, and the next subtree starts at
* level 4 and contains tiles in levels 4 through 7.
* @param tileID The tile ID for each to find the subtree root.
* @return The ID of the root tile of the subtree.
*/
static CesiumGeometry::OctreeTileID getSubtreeRootID(
uint32_t subtreeLevels,
const CesiumGeometry::OctreeTileID& tileID) noexcept;

/**
* @brief Converts an absolute tile ID to a tile ID relative to a given root
* tile.
*
* For example, if `rootID` and `tileID` are the same, this method returns
* `QuadtreeTileID(0, 0, 0)`.
*
* @param rootID The ID of the root tile that the returned ID should be
* relative to.
* @param tileID The absolute ID of the tile to compute a relative ID for.
* @return The relative tile ID.
*/
static CesiumGeometry::QuadtreeTileID absoluteTileIDToRelative(
const CesiumGeometry::QuadtreeTileID& rootID,
const CesiumGeometry::QuadtreeTileID& tileID) noexcept;

/**
* @brief Converts an absolute tile ID to a tile ID relative to a given root
* tile.
*
* For example, if `rootID` and `tileID` are the same, this method returns
* `OctreeTileID(0, 0, 0, 0)`.
*
* @param rootID The ID of the root tile that the returned ID should be
* relative to.
* @param tileID The absolute ID of the tile to compute a relative ID for.
* @return The relative tile ID.
*/
static CesiumGeometry::OctreeTileID absoluteTileIDToRelative(
const CesiumGeometry::OctreeTileID& rootID,
const CesiumGeometry::OctreeTileID& tileID) noexcept;

/**
* @brief Gets a lightweight virtual container for enumerating the quadtree
* IDs of the children of a given quadtree tile.
*
* @param tileID The tile ID of the parent tile for which to get children.
* @return The children.
*/
static QuadtreeChildren
getChildren(const CesiumGeometry::QuadtreeTileID& tileID) noexcept {
return QuadtreeChildren{tileID};
}

/**
* @brief Gets a lightweight virtual container for enumerating the octree
* IDs of the children of a given octree tile.
*
* @param tileID The tile ID of the parent tile for which to get children.
* @return The children.
*/
static OctreeChildren
getChildren(const CesiumGeometry::OctreeTileID& tileID) noexcept {
return OctreeChildren{tileID};
}

/**
* @brief Computes the bounding volume for an implicit quadtree tile with the
* given ID as a bounding region.
*
* @param rootBoundingVolume The bounding region of the root tile.
* @param tileID The tile ID for which to compute the bounding region.
* @return The bounding region for the given implicit tile.
*/
static CesiumGeospatial::BoundingRegion computeBoundingVolume(
const CesiumGeospatial::BoundingRegion& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID) noexcept;

/**
* @brief Computes the bounding volume for an implicit octree tile with the
* given ID as a bounding region.
*
* @param rootBoundingVolume The bounding region of the root tile.
* @param tileID The tile ID for which to compute the bounding region.
* @return The bounding region for the given implicit tile.
*/
static CesiumGeospatial::BoundingRegion computeBoundingVolume(
const CesiumGeospatial::BoundingRegion& rootBoundingVolume,
const CesiumGeometry::OctreeTileID& tileID) noexcept;

/**
* @brief Computes the bounding volume for an implicit quadtree tile
* with the given ID as an oriented bounding box.
*
* @param rootBoundingVolume The oriented bounding box of the root tile.
* @param tileID The tile ID for which to compute the oriented bounding box.
* @return The oriented bounding box for the given implicit tile.
*/
static CesiumGeometry::OrientedBoundingBox computeBoundingVolume(
const CesiumGeometry::OrientedBoundingBox& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID) noexcept;

/**
* @brief Computes the bounding volume for an implicit octree tile with
* the given ID as an oriented bounding box.
*
* @param rootBoundingVolume The oriented bounding box of the root tile.
* @param tileID The tile ID for which to compute the oriented bounding box.
* @return The oriented bounding box for the given implicit tile.
*/
static CesiumGeometry::OrientedBoundingBox computeBoundingVolume(
const CesiumGeometry::OrientedBoundingBox& rootBoundingVolume,
const CesiumGeometry::OctreeTileID& tileID) noexcept;

/**
* @brief Computes the bounding volume for an implicit quadtree tile
* with the given ID as an S2 cell bounding volume.
*
* @param rootBoundingVolume The S2 cell bounding volume of the root tile.
* @param tileID The tile ID for which to compute the S2 cell bounding volume.
* @return The S2 cell bounding volume for the given implicit tile.
*/
static CesiumGeospatial::S2CellBoundingVolume computeBoundingVolume(
const CesiumGeospatial::S2CellBoundingVolume& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID) noexcept;
};

} // namespace Cesium3DTilesContent
Loading

0 comments on commit 36b8cae

Please sign in to comment.