Files
BXSSP_Andriod/Plugins/CesiumForUnreal/Source/ThirdParty/include/Cesium3DTilesContent/GltfConverters.h

268 lines
9.9 KiB
C
Raw Normal View History

2025-10-14 11:14:54 +08:00
#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