初始提交: UE5.3项目基础框架

This commit is contained in:
2025-10-14 11:14:54 +08:00
commit 721d9fd98e
5334 changed files with 316782 additions and 0 deletions

View File

@ -0,0 +1,36 @@
#pragma once
#include "GltfConverterResult.h"
#include <CesiumAsync/Future.h>
#include <CesiumGltf/Model.h>
#include <CesiumGltfReader/GltfReader.h>
#include <optional>
#include <span>
namespace Cesium3DTilesContent {
struct AssetFetcher;
/**
* @brief Converts a b3dm (Batched 3D Model) file to a glTF.
*
* For more information on the b3dm format, see
* https://github.com/CesiumGS/3d-tiles/blob/main/specification/TileFormats/Batched3DModel/README.adoc
*/
struct B3dmToGltfConverter {
/**
* @brief Converts a b3dm binary file to a glTF model.
*
* @param b3dmBinary The bytes loaded for the b3dm model.
* @param options Options for how the glTF should be loaded.
* @param assetFetcher The \ref AssetFetcher containing information used by
* loaded assets.
* @returns A future that resolves to a \ref GltfConverterResult.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& b3dmBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,39 @@
#pragma once
#include <Cesium3DTilesContent/GltfConverterResult.h>
#include <CesiumAsync/Future.h>
#include <CesiumGltfReader/GltfReader.h>
#include <cstddef>
#include <span>
namespace Cesium3DTilesContent {
struct AssetFetcher;
/**
* @brief Converts a binary glTF model (glb) to a \ref CesiumGltf::Model.
*/
struct BinaryToGltfConverter {
public:
/**
* @brief Converts a glb binary file to a glTF model.
*
* @param gltfBinary The bytes loaded for the glb model.
* @param options Options for how the glTF should be loaded.
* @param assetFetcher The \ref AssetFetcher containing information used by
* loaded assets.
* @returns A future that resolves to a \ref GltfConverterResult.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& gltfBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
private:
static GltfConverterResult convertImmediate(
const std::span<const std::byte>& gltfBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
static CesiumGltfReader::GltfReader _gltfReader;
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,34 @@
#pragma once
#include <Cesium3DTilesContent/GltfConverterResult.h>
#include <CesiumAsync/Future.h>
#include <CesiumGltfReader/GltfReader.h>
#include <cstddef>
#include <span>
namespace Cesium3DTilesContent {
struct AssetFetcher;
/**
* @brief Converts a cmpt (Composite) file into a glTF model.
*
* For more information on the Composite format, see
* https://github.com/CesiumGS/3d-tiles/blob/main/specification/TileFormats/Composite/README.adoc
*/
struct CmptToGltfConverter {
/**
* @brief Converts a cmpt binary file to a glTF model.
*
* @param cmptBinary The bytes loaded for the cmpt model.
* @param options Options for how the glTF should be loaded.
* @param assetFetcher The \ref AssetFetcher containing information used by
* loaded assets.
* @returns A future that resolves to a \ref GltfConverterResult.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& cmptBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,35 @@
#pragma once
#include "Library.h"
#include <CesiumGltf/Model.h>
#include <CesiumUtility/ErrorList.h>
#include <glm/common.hpp>
#include <optional>
#include <string>
#include <vector>
namespace Cesium3DTilesContent {
/**
* @brief The result of converting a binary content to gltf model.
*
* Instances of this structure are created internally, by the
* {@link GltfConverters}, when the response to a network request for
* loading the tile content was received.
*/
struct CESIUM3DTILESCONTENT_API GltfConverterResult {
/**
* @brief The gltf model converted from a binary content. This is empty if
* there are errors during the conversion
*/
std::optional<CesiumGltf::Model> model;
/**
* @brief The error and warning list when converting a binary content to gltf
* model. This is empty if there are no errors during the conversion
*/
CesiumUtility::ErrorList errors;
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,132 @@
#pragma once
#include <Cesium3DTilesContent/GltfConverters.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumAsync/IAssetRequest.h>
#include <CesiumGltf/AccessorView.h>
#include <CesiumGltf/PropertyTransformations.h>
#include <CesiumUtility/ErrorList.h>
#include <glm/fwd.hpp>
#include <rapidjson/document.h>
#include <cstdint>
#include <optional>
#include <vector>
namespace CesiumGltf {
struct Model;
struct Buffer;
} // namespace CesiumGltf
namespace Cesium3DTilesContent {
namespace GltfConverterUtility {
std::optional<uint32_t> parseOffsetForSemantic(
const rapidjson::Document& document,
const char* semantic,
CesiumUtility::ErrorList& errorList);
typedef bool (rapidjson::Value::*ValuePredicate)() const;
template <typename T> bool isValue(const rapidjson::Value& value);
template <typename T> T getValue(const rapidjson::Value& value);
template <typename T>
std::optional<T> getOptional(const rapidjson::Value& value) {
if (isValue<T>(value)) {
return std::make_optional(getValue<T>(value));
}
return {};
}
template <typename T>
std::optional<T>
getValue(const rapidjson::Document& document, const char* semantic) {
const auto valueIt = document.FindMember(semantic);
if (valueIt == document.MemberEnd() || !isValue<T>(valueIt->value)) {
return {};
}
return std::make_optional(getValue<T>(valueIt->value));
}
template <> inline bool isValue<bool>(const rapidjson::Value& value) {
return value.IsBool();
}
template <> inline bool getValue<bool>(const rapidjson::Value& value) {
return value.GetBool();
}
template <> inline bool isValue<uint32_t>(const rapidjson::Value& value) {
return value.IsUint();
}
template <> inline uint32_t getValue<uint32_t>(const rapidjson::Value& value) {
return value.GetUint();
}
bool validateJsonArrayValues(
const rapidjson::Value& arrayValue,
uint32_t expectedLength,
ValuePredicate predicate);
std::optional<glm::dvec3>
parseArrayValueDVec3(const rapidjson::Value& arrayValue);
std::optional<glm::dvec3>
parseArrayValueDVec3(const rapidjson::Document& document, const char* name);
int32_t
createBufferInGltf(CesiumGltf::Model& gltf, std::vector<std::byte> buffer = {});
int32_t createBufferViewInGltf(
CesiumGltf::Model& gltf,
const int32_t bufferId,
const int64_t byteLength,
const int64_t byteStride);
int32_t createAccessorInGltf(
CesiumGltf::Model& gltf,
const int32_t bufferViewId,
const int32_t componentType,
const int64_t count,
const std::string type);
/**
* Applies the given relative-to-center (RTC) translation to the transforms of
* all nodes in the glTF. This is useful in converting i3dm files, where the RTC
* translation must be applied to the model before the i3dm instance
* transform. It's also the 3D Tiles 1.1 "way" to do away with RTC and encode it
* directly in the glTF.
*/
void applyRtcToNodes(CesiumGltf::Model& gltf, const glm::dvec3& rtc);
template <typename GlmType, typename GLTFType>
GlmType toGlm(const GLTFType& gltfVal);
template <typename GlmType, typename ComponentType>
GlmType toGlm(const CesiumGltf::AccessorTypes::VEC3<ComponentType>& gltfVal) {
return GlmType(gltfVal.value[0], gltfVal.value[1], gltfVal.value[2]);
}
template <typename GlmType, typename ComponentType>
GlmType
toGlmQuat(const CesiumGltf::AccessorTypes::VEC4<ComponentType>& gltfVal) {
if constexpr (std::is_same<ComponentType, float>()) {
return GlmType(
gltfVal.value[3],
gltfVal.value[0],
gltfVal.value[1],
gltfVal.value[2]);
} else {
return GlmType(
CesiumGltf::normalize(gltfVal.value[3]),
CesiumGltf::normalize(gltfVal.value[0]),
CesiumGltf::normalize(gltfVal.value[1]),
CesiumGltf::normalize(gltfVal.value[2]));
}
}
} // namespace GltfConverterUtility
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,267 @@
#pragma once
#include "Library.h"
#include <Cesium3DTilesContent/GltfConverterResult.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <CesiumGeometry/Axis.h>
#include <CesiumGltfReader/GltfReader.h>
#include <optional>
#include <span>
#include <string>
#include <string_view>
namespace Cesium3DTilesContent {
/**
* @brief The result of an \ref AssetFetcher::get call.
*/
struct AssetFetcherResult {
/**
* @brief The byte buffer obtained from a URL. This will be empty if fetching
* the asset failed.
*/
std::vector<std::byte> bytes;
/**
* @brief The errors and warnings reported while fetching the asset.
*/
CesiumUtility::ErrorList errorList;
};
/**
* Object that makes a recursive request to fetch an asset, mostly for the
* benefit of i3dm files.
*/
struct CESIUM3DTILESCONTENT_API AssetFetcher {
/**
* @brief Creates an \ref AssetFetcher with the given base URL and settings.
*
* @param asyncSystem_ The \ref CesiumAsync::AsyncSystem used for fetching
* assets asynchronously.
* @param pAssetAccessor_ The \ref CesiumAsync::IAssetAccessor providing the
* implementation for fetching assets from a remote server.
* @param baseUrl_ The base URL that relative URLs passed to \ref get will be
* relative to.
* @param tileTransform_ A transformation matrix applied to this tile.
* @param requestHeaders_ The headers to be used for a request made with the
* \ref AssetFetcher.
* @param upAxis_ The `gltfUpAxis` property to be set on loaded glTFs.
*/
AssetFetcher(
const CesiumAsync::AsyncSystem& asyncSystem_,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor_,
const std::string& baseUrl_,
const glm::dmat4 tileTransform_,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& requestHeaders_,
CesiumGeometry::Axis upAxis_)
: asyncSystem(asyncSystem_),
pAssetAccessor(pAssetAccessor_),
baseUrl(baseUrl_),
tileTransform(tileTransform_),
requestHeaders(requestHeaders_),
upAxis(upAxis_) {}
/**
* @brief Gets a buffer of bytes from the given relative URL.
*
* @param relativeUrl The URL of the asset to fetch, relative to the \ref
* baseUrl property.
* @returns A future that resolves into an \ref AssetFetcherResult.
*/
CesiumAsync::Future<AssetFetcherResult>
get(const std::string& relativeUrl) const;
/**
* @brief The \ref CesiumAsync::AsyncSystem used for this \ref AssetFetcher.
*/
CesiumAsync::AsyncSystem asyncSystem;
/**
* @brief The \ref CesiumAsync::IAssetAccessor used for this \ref
* AssetFetcher.
*/
std::shared_ptr<CesiumAsync::IAssetAccessor> pAssetAccessor;
/**
* @brief The base URL that this \ref AssetFetcher's requests will be relative
* to.
*/
std::string baseUrl;
/**
* @brief The transformation matrix applied to this tile. Used for
* East-North-Up transforms in i3dm.
*/
glm::dmat4 tileTransform;
/**
* @brief Headers that will be attached to each request made with this \ref
* AssetFetcher.
*/
std::vector<CesiumAsync::IAssetAccessor::THeader> requestHeaders;
/**
* @brief The `gltfUpAxis` property that will be specified for loaded assets.
*/
CesiumGeometry::Axis upAxis;
};
/**
* @brief Creates {@link GltfConverterResult} objects from a
* a binary content.
*
* The class offers a lookup functionality for registering
* {@link ConverterFunction} instances that can create
* {@link GltfConverterResult} instances from a binary content.
*
* The loaders are registered based on the magic header or the file extension
* of the input data. The binary data is usually received as a response to a
* network request, and the first four bytes of the raw data form the magic
* header. Based on this header or the file extension of the network response,
* the loader that will be used for processing the input can be looked up.
*/
class CESIUM3DTILESCONTENT_API GltfConverters {
public:
/**
* @brief A function pointer that can create a {@link GltfConverterResult} from a
* tile binary content.
*/
using ConverterFunction = CesiumAsync::Future<GltfConverterResult> (*)(
const std::span<const std::byte>& content,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& subprocessor);
/**
* @brief Register the given function for the given magic header.
*
* The given magic header is a 4-character string. It will be compared
* to the first 4 bytes of the raw input data, to decide whether the
* given factory function should be used to create the
* {@link GltfConverterResult} from the input data.
*
* @param magic The string describing the magic header.
* @param converter The converter that will be used to create the tile gltf
* content.
*/
static void
registerMagic(const std::string& magic, ConverterFunction converter);
/**
* @brief Register the given function for the given file extension.
*
* The given string is a file extension including the "." (e.g. ".ext"). It
* is used for deciding whether the given factory function should be used to
* create the
* {@link GltfConverterResult} from the input data with the
* same file extension in its url.
*
* @param fileExtension The file extension.
* @param converter The converter that will be used to create the tile gltf
* content
*/
static void registerFileExtension(
const std::string& fileExtension,
ConverterFunction converter);
/**
* @brief Retrieve the converter function that is already registered for the
* given file extension. If no such function is found, nullptr will be
* returned
*
* @param filePath The file path that contains the file extension.
* @return The {@link ConverterFunction} that is registered with the file extension.
*/
static ConverterFunction
getConverterByFileExtension(const std::string& filePath);
/**
* @brief Retrieve the converter function that is registered for the given
* magic header. If no such function is found, nullptr will be returned
*
* The given magic header is a 4-character string. It will be compared
* to the first 4 bytes of the raw input data, to decide whether the
* given factory function should be used to create the
* {@link GltfConverterResult} from the input data.
*
* @param content The binary tile content that contains the magic header.
* @return The {@link ConverterFunction} that is registered with the magic header.
*/
static ConverterFunction
getConverterByMagic(const std::span<const std::byte>& content);
/**
* @brief Creates the {@link GltfConverterResult} from the given
* binary content.
*
* This will look up the {@link ConverterFunction} that can be used to
* process the given input data, based on all loaders that
* have been registered with {@link GltfConverters::registerMagic}
* or {@link GltfConverters::registerFileExtension}.
*
* It will first try to find a loader based on the magic header
* of the `content` in the given input. If no matching loader is found, then
* it will look up a loader based on the file extension of `filePath` of the
* given input.
*
* If no such loader is found then an empty `GltfConverterResult` is returned.
*
* If a matching loader is found, it will be applied to the given
* input, and the result will be returned.
*
* @param filePath The file path that contains the file extension to look up
* the converter.
* @param content The tile binary content that may contains the magic header
* to look up the converter and is used to convert to gltf model.
* @param options The {@link CesiumGltfReader::GltfReaderOptions} for how to
* read a glTF.
* @param assetFetcher An object that can perform recursive asset requests.
* @return The {@link GltfConverterResult} that stores the gltf model converted from the binary data.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::string& filePath,
const std::span<const std::byte>& content,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
/**
* @brief Creates the {@link GltfConverterResult} from the given
* binary content.
*
* This will look up the {@link ConverterFunction} that can be used to
* process the given input data, based on all loaders that
* have been registered with {@link GltfConverters::registerMagic}.
*
* It will try to find a loader based on the magic header
* of the `content` in the given input. If no such loader is found then an
* empty `GltfConverterResult` is returned.
*
* If a matching loader is found, it will be applied to the given
* input, and the result will be returned.
*
* @param content The tile binary content that may contains the magic header
* to look up the converter and is used to convert to gltf model.
* @param options The {@link CesiumGltfReader::GltfReaderOptions} for how to
* read a glTF.
* @param assetFetcher An object that can perform recursive asset requests.
* @return The {@link GltfConverterResult} that stores the gltf model converted from the binary data.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& content,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
private:
static std::string toLowerCase(const std::string_view& str);
static std::string getFileExtension(const std::string_view& filePath);
static ConverterFunction getConverterByFileExtension(
const std::string& filePath,
std::string& fileExtension);
static ConverterFunction getConverterByMagic(
const std::span<const std::byte>& content,
std::string& magic);
static std::unordered_map<std::string, ConverterFunction> _loadersByMagic;
static std::unordered_map<std::string, ConverterFunction>
_loadersByFileExtension;
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,35 @@
#pragma once
#include <Cesium3DTilesContent/GltfConverterResult.h>
#include <CesiumAsync/Future.h>
#include <CesiumGltf/Model.h>
#include <CesiumGltfReader/GltfReader.h>
#include <optional>
#include <span>
namespace Cesium3DTilesContent {
struct AssetFetcher;
/**
* @brief Converts an i3dm (Instanced 3D Model) file to a glTF model.
*
* For more information on the i3dm format, see
* https://github.com/CesiumGS/3d-tiles/blob/main/specification/TileFormats/Instanced3DModel/README.adoc
*/
struct I3dmToGltfConverter {
/**
* @brief Converts an i3dm binary file to a glTF model.
*
* @param instancesBinary The bytes loaded for the i3dm model.
* @param options Options for how the glTF should be loaded.
* @param assetFetcher The \ref AssetFetcher containing information used by
* loaded assets.
* @returns A future that resolves to a \ref GltfConverterResult.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& instancesBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,523 @@
#pragma once
#include <CesiumGeometry/OctreeTileID.h>
#include <CesiumGeometry/QuadtreeTileID.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <array>
#include <iterator>
#include <string>
namespace CesiumGeospatial {
class BoundingRegion;
class S2CellBoundingVolume;
} // namespace CesiumGeospatial
namespace CesiumGeometry {
class OrientedBoundingBox;
}
namespace Cesium3DTiles {
struct BoundingVolume;
}
namespace Cesium3DTilesContent {
/**
* @brief A lightweight virtual container enumerating the quadtree IDs of the
* children of a given quadtree tile.
*/
class QuadtreeChildren {
public:
/**
* @brief An STL-compatible iterator over the children of a quadtree tile.
*/
class iterator {
public:
/**
* @brief The iterator category tag denoting this is a forward iterator.
*/
using iterator_category = std::forward_iterator_tag;
/**
* @brief The type of value that is being iterated over.
*/
using value_type = CesiumGeometry::QuadtreeTileID;
/**
* @brief The type used to identify distance between iterators.
*
* This is `void` as the distance between two QuadtreeTileIDs isn't
* particularly useful.
*/
using difference_type = void;
/**
* @brief A pointer to the type being iterated over.
*/
using pointer = CesiumGeometry::QuadtreeTileID*;
/**
* @brief A reference to the type being iterated over.
*/
using reference = CesiumGeometry::QuadtreeTileID&;
/**
* @brief Creates a new iterator over the children of a quadtree tile.
*
* @param parentTileID The \ref CesiumGeometry::QuadtreeTileID of the parent
* tile whose children will be iterated over.
* @param isEnd If true, this iterator will start at the end of the data
* it's iterating over.
*/
explicit iterator(
const CesiumGeometry::QuadtreeTileID& parentTileID,
bool isEnd) noexcept;
/**
* @brief Returns a reference to the current \ref
* CesiumGeometry::QuadtreeTileID being iterated.
*/
const CesiumGeometry::QuadtreeTileID& operator*() const {
return this->_current;
}
/**
* @brief Returns a pointer to the current \ref
* CesiumGeometry::QuadtreeTileID being iterated.
*/
const CesiumGeometry::QuadtreeTileID* operator->() const {
return &this->_current;
}
/**
* @brief Advances the iterator to the next child.
*/
iterator& operator++();
/**
* @brief Advances the iterator to the next child.
*/
iterator operator++(int);
/** @brief Checks if two iterators are at the same child. */
bool operator==(const iterator& rhs) const noexcept;
/** @brief Checks if two iterators are NOT at the same child. */
bool operator!=(const iterator& rhs) const noexcept;
private:
CesiumGeometry::QuadtreeTileID _current;
};
/** @brief A const equivalent to `iterator`. */
using const_iterator = iterator;
/**
* @brief Creates a \ref QuadtreeChildren instance from the provided parent
* tile.
*/
QuadtreeChildren(const CesiumGeometry::QuadtreeTileID& tileID) noexcept
: _tileID(tileID) {}
/** @brief Returns an iterator starting at the first child. */
iterator begin() const noexcept;
/** @brief Returns an iterator starting at the last child. */
iterator end() const noexcept;
/**
* @brief Returns the total number of \ref CesiumGeometry::QuadtreeTileID
* children for this tile, which will always be four.
*/
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:
/**
* @brief An STL-compatible iterator over the children of an octree tile.
*/
class iterator {
public:
/**
* @brief The iterator category tag denoting this is a forward iterator.
*/
using iterator_category = std::forward_iterator_tag;
/**
* @brief The type of value that is being iterated over.
*/
using value_type = CesiumGeometry::OctreeTileID;
/**
* @brief The type used to identify distance between iterators.
*
* This is `void` as the distance between two OctreeTileIDs isn't
* particularly useful.
*/
using difference_type = void;
/**
* @brief A pointer to the type being iterated over.
*/
using pointer = CesiumGeometry::OctreeTileID*;
/**
* @brief A reference to the type being iterated over.
*/
using reference = CesiumGeometry::OctreeTileID&;
/**
* @brief Creates a new iterator over the children of a octree tile.
*
* @param parentTileID The \ref CesiumGeometry::OctreeTileID of the parent
* tile whose children will be iterated over.
* @param isEnd If true, this iterator will start at the end of the data
* it's iterating over.
*/
explicit iterator(
const CesiumGeometry::OctreeTileID& parentTileID,
bool isEnd) noexcept;
/**
* @brief Returns a reference to the current \ref
* CesiumGeometry::OctreeTileID being iterated.
*/
const CesiumGeometry::OctreeTileID& operator*() const {
return this->_current;
}
/**
* @brief Returns a pointer to the current \ref
* CesiumGeometry::OctreeTileID being iterated.
*/
const CesiumGeometry::OctreeTileID* operator->() const {
return &this->_current;
}
/**
* @brief Advances the iterator to the next child.
*/
iterator& operator++();
/**
* @brief Advances the iterator to the next child.
*/
iterator operator++(int);
/** @brief Checks if two iterators are at the same child. */
bool operator==(const iterator& rhs) const noexcept;
/** @brief Checks if two iterators are NOT at the same child. */
bool operator!=(const iterator& rhs) const noexcept;
private:
CesiumGeometry::OctreeTileID _current;
};
/** @brief A const equivalent to `iterator`. */
using const_iterator = iterator;
/**
* @brief Creates a \ref OctreeChildren instance from the provided parent
* tile.
*/
OctreeChildren(const CesiumGeometry::OctreeTileID& tileID) noexcept
: _tileID(tileID) {}
/** @brief Returns an iterator starting at the first child. */
iterator begin() const noexcept;
/** @brief Returns an iterator starting at the last child. */
iterator end() const noexcept;
/**
* @brief Returns the total number of \ref CesiumGeometry::OctreeTileID
* children for this tile, which will always be eight.
*/
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 subtreeRootID 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 {@link Cesium3DTiles::BoundingVolume}.
*
* @param rootBoundingVolume The bounding volume of the root tile.
* @param tileID The tile ID for which to compute the bounding volume.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The bounding volume for the given implicit tile.
*/
static Cesium3DTiles::BoundingVolume computeBoundingVolume(
const Cesium3DTiles::BoundingVolume& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
/**
* @brief Computes the bounding volume for an implicit octree tile with the
* given ID as a {@link Cesium3DTiles::BoundingVolume}.
*
* @param rootBoundingVolume The bounding volume of the root tile.
* @param tileID The tile ID for which to compute the bounding volume.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The bounding volume for the given implicit tile.
*/
static Cesium3DTiles::BoundingVolume computeBoundingVolume(
const Cesium3DTiles::BoundingVolume& rootBoundingVolume,
const CesiumGeometry::OctreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
/**
* @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.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The bounding region for the given implicit tile.
*/
static CesiumGeospatial::BoundingRegion computeBoundingVolume(
const CesiumGeospatial::BoundingRegion& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) 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.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The bounding region for the given implicit tile.
*/
static CesiumGeospatial::BoundingRegion computeBoundingVolume(
const CesiumGeospatial::BoundingRegion& rootBoundingVolume,
const CesiumGeometry::OctreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) 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.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The S2 cell bounding volume for the given implicit tile.
*/
static CesiumGeospatial::S2CellBoundingVolume computeBoundingVolume(
const CesiumGeospatial::S2CellBoundingVolume& rootBoundingVolume,
const CesiumGeometry::QuadtreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
/**
* @brief Computes the bounding volume for an implicit octree 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.
* @param ellipsoid The ellipsoid to use for this calculation.
* @return The S2 cell bounding volume for the given implicit tile.
*/
static CesiumGeospatial::S2CellBoundingVolume computeBoundingVolume(
const CesiumGeospatial::S2CellBoundingVolume& rootBoundingVolume,
const CesiumGeometry::OctreeTileID& tileID,
const CesiumGeospatial::Ellipsoid& ellipsoid
CESIUM_DEFAULT_ELLIPSOID) noexcept;
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,18 @@
#pragma once
/**
* @brief Classes that support loading and converting 3D Tiles tile content.
*
* @mermaid-interactive{dependencies/Cesium3DTilesContent}
*/
namespace Cesium3DTilesContent {}
#if defined(_WIN32) && defined(CESIUM_SHARED)
#ifdef CESIUM3DTILESCONTENT_BUILDING
#define CESIUM3DTILESCONTENT_API __declspec(dllexport)
#else
#define CESIUM3DTILESCONTENT_API __declspec(dllimport)
#endif
#else
#define CESIUM3DTILESCONTENT_API
#endif

View File

@ -0,0 +1,36 @@
#pragma once
#include "GltfConverterResult.h"
#include <CesiumAsync/Future.h>
#include <CesiumGltf/Model.h>
#include <CesiumGltfReader/GltfReader.h>
#include <optional>
#include <span>
namespace Cesium3DTilesContent {
struct AssetFetcher;
/**
* @brief Converts a pnts (Point Cloud) file to a glTF model.
*
* For more information on the pnts format, see
* https://github.com/CesiumGS/3d-tiles/blob/main/specification/TileFormats/PointCloud/README.adoc
*/
struct PntsToGltfConverter {
/**
* @brief Converts an pnts binary file to a glTF model.
*
* @param pntsBinary The bytes loaded for the pnts model.
* @param options Options for how the glTF should be loaded.
* @param assetFetcher The \ref AssetFetcher containing information used by
* loaded assets.
* @returns A future that resolves to a \ref GltfConverterResult.
*/
static CesiumAsync::Future<GltfConverterResult> convert(
const std::span<const std::byte>& pntsBinary,
const CesiumGltfReader::GltfReaderOptions& options,
const AssetFetcher& assetFetcher);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,442 @@
#pragma once
#include <Cesium3DTiles/Subtree.h>
#include <CesiumAsync/Future.h>
#include <CesiumAsync/IAssetAccessor.h>
#include <optional>
namespace CesiumGeometry {
struct QuadtreeTileID;
struct OctreeTileID;
} // namespace CesiumGeometry
namespace Cesium3DTiles {
struct ImplicitTiling;
} // namespace Cesium3DTiles
namespace Cesium3DTilesContent {
/**
* @brief Indicates how an implicit tile is subdivided.
*/
enum class ImplicitTileSubdivisionScheme {
/**
* @brief Implicit tiles are divided into four children, forming a quadree.
*/
Quadtree,
/**
* @brief Implicit tiles are divided into eight children, forming an octree.
*/
Octree
};
/**
* @brief Supports querying and modifying the various types of availablity
* information included in a {@link Cesium3DTiles::Subtree}.
*/
class SubtreeAvailability {
public:
/**
* @brief Creates an instance from a `Subtree`.
*
* @param subdivisionScheme The subdivision scheme of the subtree (quadtree or
* octree).
* @param levelsInSubtree The number of levels in this subtree.
* @param subtree The subtree.
* @return The subtree availability, or std::nullopt if the subtree definition
* is invalid.
*/
static std::optional<SubtreeAvailability> fromSubtree(
ImplicitTileSubdivisionScheme subdivisionScheme,
uint32_t levelsInSubtree,
Cesium3DTiles::Subtree&& subtree) noexcept;
/**
* @brief Creates an empty instance with all tiles initially available, while
* all content and subtrees are initially unavailable.
*
* @param subdivisionScheme The subdivision scheme of the subtree (quadtree or
* octree).
* @param levelsInSubtree The number of levels in this subtree.
* @return The subtree availability, or std::nullopt if the subtree definition
* is invalid.
*/
static std::optional<SubtreeAvailability> createEmpty(
ImplicitTileSubdivisionScheme subdivisionScheme,
uint32_t levelsInSubtree) noexcept;
/**
* @brief Asynchronously loads a subtree from a URL. The resource downloaded
* from the URL may be either a JSON or a binary subtree file.
*
* @param subdivisionScheme The subdivision scheme of the subtree (quadtree or
* octree).
* @param levelsInSubtree The number of levels in this subtree.
* @param asyncSystem The async system with which to do background work.
* @param pAssetAccessor The asset accessor to use to retrieve the subtree
* resource from the URL.
* @param pLogger The logger to which to load errors and warnings that occur
* during subtree load.
* @param subtreeUrl The URL from which to retrieve the subtree file.
* @param requestHeaders HTTP headers to include in the request for the
* subtree file.
* @return A future that resolves to a `SubtreeAvailability` instance for the
* subtree file, or std::nullopt if something goes wrong.
*/
static CesiumAsync::Future<std::optional<SubtreeAvailability>> loadSubtree(
ImplicitTileSubdivisionScheme subdivisionScheme,
uint32_t levelsInSubtree,
const CesiumAsync::AsyncSystem& asyncSystem,
const std::shared_ptr<CesiumAsync::IAssetAccessor>& pAssetAccessor,
const std::shared_ptr<spdlog::logger>& pLogger,
const std::string& subtreeUrl,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& requestHeaders);
/**
* @brief An AvailibilityView that indicates that either all tiles are
* available or all tiles are unavailable.
*/
struct SubtreeConstantAvailability {
/**
* @brief True if all tiles are availabile, false if all tiles are
* unavailable.
*/
bool constant;
};
/**
* @brief An AvailabilityView that accesses availability information from a
* bitstream.
*/
struct SubtreeBufferViewAvailability {
/**
* @brief The buffer from which to read and write availability information.
*/
std::span<std::byte> view;
};
/**
* @brief A mechanism for accessing availability information. It may be a
* constant value, or it may be read from a bitstream.
*/
using AvailabilityView =
std::variant<SubtreeConstantAvailability, SubtreeBufferViewAvailability>;
/**
* @brief Constructs a new instance.
*
* @param subdivisionScheme The subdivision scheme of the subtree (quadtree or
* octree).
* @param levelsInSubtree The number of levels in this subtree.
* @param tileAvailability A view on the tile availability. If backed by a
* buffer, the buffer is expected to be in `subtree`.
* @param subtreeAvailability A view on the subtree availability. If backed by
* a buffer, the buffer is expected to be in `subtree`.
* @param contentAvailability A view on the content availability. If backed by
* a buffer, the buffer is expected to be in `subtree`.
* @param subtree The subtree with which this instance queries and modifies
* availability information.
*/
SubtreeAvailability(
ImplicitTileSubdivisionScheme subdivisionScheme,
uint32_t levelsInSubtree,
AvailabilityView tileAvailability,
AvailabilityView subtreeAvailability,
std::vector<AvailabilityView>&& contentAvailability,
Cesium3DTiles::Subtree&& subtree);
/**
* @brief Determines if a given tile in the quadtree is available.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile to query.
* @return True if the tile is available; otherwise, false.
*/
bool isTileAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId) const noexcept;
/**
* @brief Determines if a given tile in the octree is available.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile to query.
* @return True if the tile is available; otherwise, false.
*/
bool isTileAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId) const noexcept;
/**
* @brief Determines if a given tile in the subtree is available.
*
* @param relativeTileLevel The level of the tile to query, relative to the
* root of the subtree.
* @param relativeTileMortonId The Morton ID of the tile to query. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @return True if the tile is available; otherwise, false.
*/
bool isTileAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId) const noexcept;
/**
* @brief Sets the availability state of a given tile in the quadtree.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile for which to set availability.
* @param isAvailable The new availability state for the tile.
*/
void setTileAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of a given tile in the octree.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile for which to set availability.
* @param isAvailable The new availability state for the tile.
*/
void setTileAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of a given tile in the subtree.
*
* @param relativeTileLevel The level of the tile for which to set
* availability, relative to the root of the subtree.
* @param relativeTileMortonId The Morton ID of the tile for which to set
* availability. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @param isAvailable The new availability state of the tile.
*/
void setTileAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
bool isAvailable) noexcept;
/**
* @brief Determines if content for a given tile in the quadtree is available.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile to query.
* @param contentId The ID of the content to query.
* @return True if the tile's content is available; otherwise, false.
*/
bool isContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId) const noexcept;
/**
* @brief Determines if content for a given tile in the octree is available.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile to query.
* @param contentId The ID of the content to query.
* @return True if the tile's content is available; otherwise, false.
*/
bool isContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId) const noexcept;
/**
* @brief Determines if content for a given tile in the subtree is available.
*
* @param relativeTileLevel The level of the tile to query, relative to the
* root of the subtree.
* @param relativeTileMortonId The Morton ID of the tile to query. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @param contentId The ID of the content to query.
* @return True if the tile's content is available; otherwise, false.
*/
bool isContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId) const noexcept;
/**
* @brief Sets the availability state of the content for a given tile in the
* quadtree.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile for which to set content availability.
* @param contentId The ID of the content to query.
* @param isAvailable The new availability state for the tile's content.
*/
void setContentAvailable(
const CesiumGeometry::QuadtreeTileID& subtreeId,
const CesiumGeometry::QuadtreeTileID& tileId,
uint64_t contentId,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of the content for a given tile in the
* octree.
*
* @param subtreeId The ID of the root tile of the subtree.
* @param tileId The ID of the tile for which to set content availability.
* @param contentId The ID of the content to query.
* @param isAvailable The new availability state for the tile's content.
*/
void setContentAvailable(
const CesiumGeometry::OctreeTileID& subtreeId,
const CesiumGeometry::OctreeTileID& tileId,
uint64_t contentId,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of the content for a given tile in the
* subtree.
*
* @param relativeTileLevel The level of the tile for which to set
* content availability, relative to the root of the subtree.
* @param relativeTileMortonId The Morton ID of the tile for which to set
* content availability. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @param contentId The ID of the content to query.
* @param isAvailable The new availability state for the tile's content.
*/
void setContentAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
uint64_t contentId,
bool isAvailable) noexcept;
/**
* @brief Determines if the subtree rooted at the given tile is available.
*
* The provided `checkSubtreeID` must be a child of the leaves of this
* subtree.
*
* @param thisSubtreeID The ID of the root tile of this subtree.
* @param checkSubtreeID The ID of the tile to query to see if its subtree is
* available.
* @return True if the subtree is available; otherwise, false.
*/
bool isSubtreeAvailable(
const CesiumGeometry::QuadtreeTileID& thisSubtreeID,
const CesiumGeometry::QuadtreeTileID& checkSubtreeID) const noexcept;
/**
* @brief Determines if the subtree rooted at the given tile is available.
*
* The provided `checkSubtreeID` must be a child of the leaves of this
* subtree.
*
* @param thisSubtreeID The ID of the root tile of this subtree.
* @param checkSubtreeID The ID of the tile to query to see if its subtree is
* available.
* @return True if the subtree is available; otherwise, false.
*/
bool isSubtreeAvailable(
const CesiumGeometry::OctreeTileID& thisSubtreeID,
const CesiumGeometry::OctreeTileID& checkSubtreeID) const noexcept;
/**
* @brief Determines if the subtree rooted at the given tile is available.
*
* The provided `relativeSubtreeMortonId` must refer to a child of the leaves
* of this subtree.
*
* @param relativeSubtreeMortonId The Morton ID of the tile for which to check
* subtree availability. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @return True if the subtree is available; otherwise, false.
*/
bool isSubtreeAvailable(uint64_t relativeSubtreeMortonId) const noexcept;
/**
* @brief Sets the availability state of the child quadtree rooted at the
* given tile.
*
* The provided `setSubtreeID` must be a child of the leaves of this
* subtree.
*
* @param thisSubtreeID The ID of the root tile of this subtree.
* @param setSubtreeID The ID of the tile to query to see if its subtree is
* available.
* @param isAvailable The new availability state for the subtree.
*/
void setSubtreeAvailable(
const CesiumGeometry::QuadtreeTileID& thisSubtreeID,
const CesiumGeometry::QuadtreeTileID& setSubtreeID,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of the child octree rooted at the given
* tile.
*
* The provided `setSubtreeID` must be a child of the leaves of this
* subtree.
*
* @param thisSubtreeID The ID of the root tile of this subtree.
* @param setSubtreeID The ID of the tile to query to see if its subtree is
* available.
* @param isAvailable The new availability state for the subtree.
*/
void setSubtreeAvailable(
const CesiumGeometry::OctreeTileID& thisSubtreeID,
const CesiumGeometry::OctreeTileID& setSubtreeID,
bool isAvailable) noexcept;
/**
* @brief Sets the availability state of the child subtree rooted at the given
* tile.
*
* The provided `relativeSubtreeMortonId` must refer to a child of the leaves
* of this subtree.
*
* @param relativeSubtreeMortonId The Morton ID of the tile for which to set
* subtree availability. See
* {@link ImplicitTilingUtilities::computeRelativeMortonIndex}.
* @param isAvailable The new availability state.
*/
void setSubtreeAvailable(
uint64_t relativeSubtreeMortonId,
bool isAvailable) noexcept;
/**
* @brief Gets the subtree that this instance queries and modifies.
*/
const Cesium3DTiles::Subtree& getSubtree() const noexcept {
return this->_subtree;
}
private:
bool isAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
const AvailabilityView& availabilityView) const noexcept;
void setAvailable(
uint32_t relativeTileLevel,
uint64_t relativeTileMortonId,
AvailabilityView& availabilityView,
bool isAvailable) noexcept;
bool isAvailableUsingBufferView(
uint64_t numOfTilesFromRootToParentLevel,
uint64_t relativeTileMortonId,
const AvailabilityView& availabilityView) const noexcept;
void setAvailableUsingBufferView(
uint64_t numOfTilesFromRootToParentLevel,
uint64_t relativeTileMortonId,
AvailabilityView& availabilityView,
bool isAvailable) noexcept;
uint32_t _powerOf2;
uint32_t _levelsInSubtree;
Cesium3DTiles::Subtree _subtree;
uint32_t _childCount;
AvailabilityView _tileAvailability;
AvailabilityView _subtreeAvailability;
std::vector<AvailabilityView> _contentAvailability;
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,129 @@
#pragma once
#include <CesiumGeometry/BoundingSphere.h>
#include <CesiumGeometry/OrientedBoundingBox.h>
#include <CesiumGeospatial/BoundingRegion.h>
#include <CesiumGeospatial/S2CellBoundingVolume.h>
#include <optional>
namespace Cesium3DTiles {
struct BoundingVolume;
}
namespace Cesium3DTilesContent {
/**
* @brief Provides functions for extracting bounding volumes types from the
* vectors stored in {@link Cesium3DTiles::BoundingVolume}.
*/
class TileBoundingVolumes {
public:
/**
* @brief Gets the bounding box defined in a
* {@link Cesium3DTiles::BoundingVolume}, if any.
*
* @param boundingVolume The bounding volume from which to get the box.
* @return The box, or `std::nullopt` if the bounding volume does not
* define a box. The box is defined in the tile's coordinate system.
*/
static std::optional<CesiumGeometry::OrientedBoundingBox>
getOrientedBoundingBox(const Cesium3DTiles::BoundingVolume& boundingVolume);
/**
* @brief Sets the `box` property in a {@link Cesium3DTiles::BoundingVolume}
* based on an {@link CesiumGeometry::OrientedBoundingBox}.
*
* Other bounding volume types, if any, are not modified.
*
* @param boundingVolume The bounding volume to set.
* @param boundingBox The bounding box with which to set the property.
*/
static void setOrientedBoundingBox(
Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeometry::OrientedBoundingBox& boundingBox);
/**
* @brief Gets the bounding region defined in a
* {@link Cesium3DTiles::BoundingVolume}, if any.
*
* @param boundingVolume The bounding volume from which to get the region.
* @param ellipsoid The ellipsoid on which the region should be defined.
* @return The region, or `std::nullopt` if the bounding volume does not
* define a region. The region is defined in geographic coordinates.
*/
static std::optional<CesiumGeospatial::BoundingRegion> getBoundingRegion(
const Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);
/**
* @brief Sets the `region` property in a {@link Cesium3DTiles::BoundingVolume}
* based on a {@link CesiumGeospatial::BoundingRegion}.
*
* Other bounding volume types, if any, are not modified.
*
* @param boundingVolume The bounding volume to set.
* @param boundingRegion The bounding region with which to set the property.
*/
static void setBoundingRegion(
Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeospatial::BoundingRegion& boundingRegion);
/**
* @brief Gets the bounding sphere defined in a
* {@link Cesium3DTiles::BoundingVolume}, if any.
*
* @param boundingVolume The bounding volume from which to get the sphere.
* @return The sphere, or `std::nullopt` if the bounding volume does not
* define a sphere. The sphere is defined in the tile's coordinate system.
*/
static std::optional<CesiumGeometry::BoundingSphere>
getBoundingSphere(const Cesium3DTiles::BoundingVolume& boundingVolume);
/**
* @brief Sets the `sphere` property in a {@link Cesium3DTiles::BoundingVolume}
* based on a {@link CesiumGeometry::BoundingSphere}.
*
* Other bounding volume types, if any, are not modified.
*
* @param boundingVolume The bounding volume to set.
* @param boundingSphere The bounding sphere with which to set the property.
*/
static void setBoundingSphere(
Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeometry::BoundingSphere& boundingSphere);
/**
* @brief Gets the S2 cell bounding volume defined in the
* `3DTILES_bounding_volume_S2` extension of a
* {@link Cesium3DTiles::BoundingVolume}, if any.
*
* @param boundingVolume The bounding volume from which to get the S2 cell
* bounding volume.
* @param ellipsoid The ellipsoid on which the S2 cell should be defined.
* @return The S2 cell bounding volume, or `std::nullopt` if the bounding
* volume does not define an S2 cell bounding volume. The S2 cell bounding
* volume is defined in geographic coordinates.
*/
static std::optional<CesiumGeospatial::S2CellBoundingVolume>
getS2CellBoundingVolume(
const Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);
/**
* @brief Adds the `3DTILES_bounding_volume_S2` extension to a
* {@link Cesium3DTiles::BoundingVolume} based on a
* {@link CesiumGeospatial::S2CellBoundingVolume}.
*
* Other bounding volume types, if any, are not modified.
*
* @param boundingVolume The bounding volume to set.
* @param s2BoundingVolume The S2 bounding volume with which to set the
* property.
*/
static void setS2CellBoundingVolume(
Cesium3DTiles::BoundingVolume& boundingVolume,
const CesiumGeospatial::S2CellBoundingVolume& s2BoundingVolume);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,44 @@
#pragma once
#include <glm/fwd.hpp>
#include <optional>
namespace Cesium3DTiles {
struct Tile;
}
namespace Cesium3DTilesContent {
/**
* @brief Convenience functions for getting and setting
* {@link Cesium3DTiles::Tile::transform} as a `glm::dmat4`.
*/
class TileTransform {
public:
/**
* @brief Gets the tile's transform as a `glm::dmat4`.
*
* If the tile's transform array has more than 16 elements, the extras are
* silently ignored.
*
* @param tile The tile from which to get the transform.
* @return The transform, or `std::nullopt` if the
* {@link Cesium3DTiles::Tile::transform} has less than 16 elements.
*/
static std::optional<glm::dmat4>
getTransform(const Cesium3DTiles::Tile& tile);
/**
* @brief Sets the tile's transform using the values of a `glm::dmat4`.
*
* The existing value of the tile's transform property, if any, is replaced.
*
* @param tile The tile on which to set the transform.
* @param newTransform The new transform.
*/
static void
setTransform(Cesium3DTiles::Tile& tile, const glm::dmat4& newTransform);
};
} // namespace Cesium3DTilesContent

View File

@ -0,0 +1,15 @@
#include "Library.h"
namespace Cesium3DTilesContent {
/**
* @brief Register all \ref Cesium3DTilesSelection::Tile "Tile" content types
* that can be loaded.
*
* This is supposed to be called during the initialization, before
* any \ref Cesium3DTilesSelection::Tileset "Tileset" is loaded. It will
* register loaders for the different types of tiles that can be encountered.
*/
CESIUM3DTILESCONTENT_API void registerAllTileContentTypes();
} // namespace Cesium3DTilesContent