初始提交: 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,344 @@
#pragma once
#include "Library.h"
#include <CesiumGeospatial/BoundingRegion.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/GlobeRectangle.h>
#include <glm/fwd.hpp>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
namespace CesiumGltf {
struct Buffer;
struct Model;
struct Node;
} // namespace CesiumGltf
namespace CesiumGeometry {
class Ray;
} // namespace CesiumGeometry
namespace CesiumGltfContent {
/**
* A collection of utility functions that are used to process and transform a
* gltf model
*/
struct CESIUMGLTFCONTENT_API GltfUtilities {
/**
* @brief Gets the transformation matrix for a given node.
*
* This returns the node's local transform as-is. It does not incorporate
* transforms from any of the node's ancestors.
*
* @param node The node from which to get the transformation matrix.
* @return The transformation matrix, or std::nullopt if the node's
* transformation is invalid, .e.g, because it has a matrix with fewer than
* 16 elements in it.
*/
static std::optional<glm::dmat4x4>
getNodeTransform(const CesiumGltf::Node& node);
/**
* @brief Sets the transformation matrix for a given node.
*
* This sets only the local transform of the node. It does not affect the
* transforms of any ancestor or descendant nodes, if present.
*
* @param node The node on which to set the transformation matrix.
* @param newTransform The new transformation matrix.
*/
static void
setNodeTransform(CesiumGltf::Node& node, const glm::dmat4x4& newTransform);
/**
* @brief Applies the glTF's RTC_CENTER, if any, to the given transform.
*
* If the glTF has a `CESIUM_RTC` extension, this function will multiply the
* given matrix with the (translation) matrix that is created from the
* `RTC_CENTER` in the. If the given model does not have this extension, then
* this function will return the `rootTransform` unchanged.
*
* @param gltf The glTF model
* @param rootTransform The matrix that will be multiplied with the transform
* @return The result of multiplying the `RTC_CENTER` with the
* `rootTransform`.
*/
static glm::dmat4x4 applyRtcCenter(
const CesiumGltf::Model& gltf,
const glm::dmat4x4& rootTransform);
/**
* @brief Applies the glTF's `gltfUpAxis`, if any, to the given transform.
*
* By default, the up-axis of a glTF model will the the Y-axis.
*
* If the tileset that contained the model had the `asset.gltfUpAxis` string
* property, then the information about the up-axis has been stored in as a
* number property called `gltfUpAxis` in the `extras` of the given model.
*
* Depending on whether this value is `CesiumGeometry::Axis::X`, `Y`, or `Z`,
* the given matrix will be multiplied with a matrix that converts the
* respective axis to be the Z-axis, as required by the 3D Tiles standard.
*
* @param model The glTF model
* @param rootTransform The matrix that will be multiplied with the transform
* @return The result of multiplying the `rootTransform` with the
* `gltfUpAxis`.
*/
static glm::dmat4x4 applyGltfUpAxisTransform(
const CesiumGltf::Model& model,
const glm::dmat4x4& rootTransform);
/**
* @brief Computes a bounding region from the vertex positions in a glTF
* model.
*
* If the glTF model spans the anti-meridian, the west and east longitude
* values will be in the usual -PI to PI range, but east will have a smaller
* value than west.
*
* If the glTF contains no geometry, the returned region's rectangle
* will be {@link CesiumGeospatial::GlobeRectangle::EMPTY}, its minimum height will be 1.0, and
* its maximum height will be -1.0 (the minimum will be greater than the
* maximum).
*
* @param gltf The model.
* @param transform The transform from model coordinates to ECEF coordinates.
* @param ellipsoid The {@link CesiumGeospatial::Ellipsoid}.
* @return The computed bounding region.
*/
static CesiumGeospatial::BoundingRegion computeBoundingRegion(
const CesiumGltf::Model& gltf,
const glm::dmat4& transform,
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);
/**
* @brief Parse the copyright field of a glTF model and return the individual
* credits.
*
* Credits are read from the glTF's asset.copyright field. This method assumes
* that individual credits are separated by semicolons.
*
* @param gltf The model.
* @return The credits from the glTF.
*/
static std::vector<std::string_view>
parseGltfCopyright(const CesiumGltf::Model& gltf);
/**
* @brief Merges all of the glTF's buffers into a single buffer (the first
* one).
*
* This is useful when writing the glTF as a GLB, which supports only a single
* embedded buffer.
*
* @param gltf The glTF in which to merge buffers.
*/
static void collapseToSingleBuffer(CesiumGltf::Model& gltf);
/**
* @brief Copies the content of one {@link CesiumGltf::Buffer} to the end of another,
* updates all {@link CesiumGltf::BufferView} instances to refer to the destination
* buffer, and clears the contents of the original buffer.
*
* The source buffer is not removed, but it has a `byteLength` of zero after
* this function completes.
*
* @param gltf The glTF model to modify.
* @param destination The destination Buffer into which to move content.
* @param source The source Buffer from which to move content.
*/
static void moveBufferContent(
CesiumGltf::Model& gltf,
CesiumGltf::Buffer& destination,
CesiumGltf::Buffer& source);
/**
* @brief Removes unused textures from the given glTF model.
*
* @param gltf The glTF to remove unused textures from.
* @param extraUsedTextureIndices Indices of textures that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedTextures(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedTextureIndices = {});
/**
* @brief Removes unused samplers from the given glTF model.
*
* @param gltf The glTF to remove unused samplers from.
* @param extraUsedSamplerIndices Indices of samplers that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedSamplers(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedSamplerIndices = {});
/**
* @brief Removes unused images from the given glTF model.
*
* @param gltf The glTF to remove unused images from.
* @param extraUsedImageIndices Indices of images that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedImages(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedImageIndices = {});
/**
* @brief Removes unused accessors from the given glTF model.
*
* @param gltf The glTF to remove unused accessors from.
* @param extraUsedAccessorIndices Indices of accessors that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedAccessors(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedAccessorIndices = {});
/**
* @brief Removes unused buffer views from the given glTF model.
*
* @param gltf The glTF to remove unused buffer views from.
* @param extraUsedBufferViewIndices Indices of buffer views that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedBufferViews(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedBufferViewIndices = {});
/**
* @brief Removes unused buffers from the given glTF model.
*
* @param gltf The glTF to remove unused buffers from.
* @param extraUsedBufferIndices Indices of buffers that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedBuffers(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedBufferIndices = {});
/**
* @brief Removes unused meshes from the given glTF model.
*
* @param gltf The glTF to remove unused meshes from.
* @param extraUsedMeshIndices Indices of meshes that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedMeshes(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedMeshIndices = {});
/**
* @brief Removes unused materials from the given glTF model.
*
* @param gltf The glTF to remove unused materials from.
* @param extraUsedMaterialIndices Indices of materials that should be
* considered "used" even if they're not referenced by anything else in the
* glTF.
*/
static void removeUnusedMaterials(
CesiumGltf::Model& gltf,
const std::vector<int32_t>& extraUsedMaterialIndices = {});
/**
* @brief Shrink buffers by removing any sections that are not referenced by
* any BufferView.
*
* @param gltf The glTF to modify.
*/
static void compactBuffers(CesiumGltf::Model& gltf);
/**
* @brief Shrink a buffer by removing any sections that are not referenced by
* any BufferView.
*
* @param gltf The glTF to modify.
* @param bufferIndex The index of the buffer to compact.
*/
static void compactBuffer(CesiumGltf::Model& gltf, int32_t bufferIndex);
/**
* @brief Data describing a hit from a ray / gltf intersection test
*/
struct RayGltfHit {
/**
* @brief Hit point in primitive space
*/
glm::dvec3 primitivePoint = {};
/**
* @brief Transformation from primitive to world space
*/
glm::dmat4x4 primitiveToWorld = {};
/**
* @brief Hit point in world space
*/
glm::dvec3 worldPoint = {};
/**
* @brief Square dist from intersection ray origin to world point
*/
double rayToWorldPointDistanceSq = -1.0;
/**
* @brief ID of the glTF mesh that was hit
*/
int32_t meshId = -1;
/**
* @brief ID of the glTF primitive that was hit
*/
int32_t primitiveId = -1;
};
/**
* @brief Hit result data for intersectRayGltfModel
*/
struct IntersectResult {
/**
* @brief Optional hit result, if an intersection occurred
*/
std::optional<RayGltfHit> hit;
/**
* @brief Warnings encountered when traversing the glTF model
*/
std::vector<std::string> warnings{};
};
/**
* @brief Intersects a ray with a glTF model and returns the first
* intersection point.
*
* Supports all mesh primitive modes.
* Points and lines are assumed to have no area, and are ignored
*
* @param ray A ray in world space.
* @param gltf The glTF model to intersect.
* @param cullBackFaces Ignore triangles that face away from ray. Front faces
* use CCW winding order.
* @param gltfTransform Optional matrix to apply to entire gltf model.
* @returns IntersectResult describing outcome
*/
static IntersectResult intersectRayGltfModel(
const CesiumGeometry::Ray& ray,
const CesiumGltf::Model& gltf,
bool cullBackFaces = true,
const glm::dmat4x4& gltfTransform = glm::dmat4(1.0));
};
} // namespace CesiumGltfContent

View File

@ -0,0 +1,123 @@
#pragma once
#include "Library.h"
#include <cstddef>
#include <cstdint>
// Forward declarations
namespace CesiumGltf {
struct ImageAsset;
}
namespace CesiumGltfContent {
/**
* @brief Specifies a rectangle of pixels in an image.
*/
struct PixelRectangle {
/**
* @brief The X coordinate of the top-left corner of the rectangle.
*/
int32_t x;
/**
* @brief The Y coordinate of the top-left corner of the rectangle.
*/
int32_t y;
/**
* @brief The total number of pixels in the horizontal direction.
*/
int32_t width;
/**
* @brief The total number of pixels in the vertical direction.
*/
int32_t height;
};
/**
* @brief A collection of utility functions for image manipulation operations.
*/
class CESIUMGLTFCONTENT_API ImageManipulation {
public:
/**
* @brief Directly copies pixels from a source to a target, without validating
* the provided pointers or ranges.
*
* @param pTarget The pointer at which to start writing pixels.
* @param targetRowStride The number of bytes between rows in the target
* image.
* @param pSource The pointer at which to start reading pixels.
* @param sourceRowStride The number of bytes between rows in the source
* image.
* @param sourceWidth The number of pixels to copy in the horizontal
* direction.
* @param sourceHeight The number of pixels to copy in the vertical direction.
* @param bytesPerPixel The number of bytes used to represent each pixel.
*/
static void unsafeBlitImage(
std::byte* pTarget,
size_t targetRowStride,
const std::byte* pSource,
size_t sourceRowStride,
size_t sourceWidth,
size_t sourceHeight,
size_t bytesPerPixel);
/**
* @brief Copies pixels from a source image to a target image.
*
* If the source and target dimensions are the same, the source pixels are
* copied exactly into the target. If not, the source image is scaled to fit
* the target rectangle.
*
* The filtering algorithm for scaling is not specified, but can be assumed
* to provide reasonably good quality.
*
* The source and target images must have the same number of channels and same
* bytes per channel. If scaling is required, they must also use exactly 1
* byte per channel. If any of these requirements are violated, this function
* will return false and will not change any target pixels.
*
* The provided rectangles are validated to ensure that they fall within the
* range of the images. If they do not, this function will return false and
* will not change any pixels.
*
* @param target The image in which to write pixels.
* @param targetPixels The pixels to write in the target.
* @param source The image from which to read pixels.
* @param sourcePixels The pixels to read from the target.
* @returns True if the source image was blitted successfully into the target,
* or false if the blit could not be completed due to invalid ranges or
* incompatible formats.
*/
static bool blitImage(
CesiumGltf::ImageAsset& target,
const PixelRectangle& targetPixels,
const CesiumGltf::ImageAsset& source,
const PixelRectangle& sourcePixels);
/**
* @brief Saves an image to a new byte buffer in PNG format.
*
* @param image The image to save.
* @return The byte buffer containing the image. If the buffer is empty, the
* image could not be written.
*/
static std::vector<std::byte> savePng(const CesiumGltf::ImageAsset& image);
/**
* @brief Saves an image to an existing byte buffer in PNG format.
*
* @param image The image to save.
* @param output The buffer in which to store the PNG. The image is written to
* the end of the buffer. If the buffer size is unchanged on return the image
* could not be written.
*/
static void
savePng(const CesiumGltf::ImageAsset& image, std::vector<std::byte>& output);
};
} // namespace CesiumGltfContent

View File

@ -0,0 +1,18 @@
#pragma once
/**
* @brief Classes that support manipulating the content of a glTF.
*
* @mermaid-interactive{dependencies/CesiumGltfContent}
*/
namespace CesiumGltfContent {}
#if defined(_WIN32) && defined(CESIUM_SHARED)
#ifdef CESIUMGLTFCONTENT_BUILDING
#define CESIUMGLTFCONTENT_API __declspec(dllexport)
#else
#define CESIUMGLTFCONTENT_API __declspec(dllimport)
#endif
#else
#define CESIUMGLTFCONTENT_API
#endif

View File

@ -0,0 +1,112 @@
#include <CesiumUtility/JsonValue.h>
#include <glm/vec3.hpp>
#include <optional>
namespace CesiumGltfContent {
/**
* @brief Metadata obtained from a glTF that describes the skirts present on the
* mesh.
*
* @remarks Skirts are a technique for hiding cracks between adjacent tiles
* where the geometry at the edges of tiles is extended downwards, like the
* edges of a tablecloth hanging off of a table. These skirts are included in
* the glTF when they're generated, in the case of 3D Tiles, or they are
* generated by Cesium Native when terrain is loaded, in the case of Quantized
* Mesh terrain. `SkirtMeshMetadata` is attached to the glTF to allow Cesium
* Native to know which parts of the mesh are original and which contain the
* generated skirts, for operations such as creating texture coordinates for
* raster overlays.
*/
struct SkirtMeshMetadata {
/**
* @brief Creates a new `SkirtMeshMetadata` with zeroes in all fields.
*/
SkirtMeshMetadata() noexcept
: noSkirtIndicesBegin{0},
noSkirtIndicesCount{0},
noSkirtVerticesBegin{0},
noSkirtVerticesCount{0},
meshCenter{0.0, 0.0, 0.0},
skirtWestHeight{0.0},
skirtSouthHeight{0.0},
skirtEastHeight{0.0},
skirtNorthHeight{0.0} {}
/**
* @brief Parses `SkirtMeshMetadata` from the `extras` field of a glTF mesh,
* if present.
*
* @param extras The extras field of the glTF mesh.
* @returns An optional containing the `SkirtMeshMetadata` if it was present
* on the mesh.
*/
static std::optional<SkirtMeshMetadata>
parseFromGltfExtras(const CesiumUtility::JsonValue::Object& extras);
/**
* @brief Creates a glTF mesh extras value from the provided
* `SkirtMeshMetadata`.
*
* This might be used when generating a glTF at runtime, in order to provide
* information on the mesh's skirts to the rest of Cesium Native.
*
* @param skirt The skirt to create the glTF extras object from.
* @returns An object representing the value of a glTF extras field containing
* the skirt metadata.
*/
static CesiumUtility::JsonValue::Object
createGltfExtras(const SkirtMeshMetadata& skirt);
/**
* @brief The start index of the range of a glTF mesh's indices buffer that
* should \b NOT be considered part of the skirt.
*/
uint32_t noSkirtIndicesBegin;
/**
* @brief The length of the range of a glTF mesh's indices buffer that should
* \b NOT be considered part of the skirt.
*
* Any indices outside of the range `(noSkirtIndicesBegin,
* noSkirtIndicesBegin + noSkirtIndicesCount)` will be considered part of the
* skirt.
*/
uint32_t noSkirtIndicesCount;
/**
* @brief The start index of the range of a glTF mesh's vertices buffer that
* should \b NOT be considered part of the skirt.
*/
uint32_t noSkirtVerticesBegin;
/**
* @brief The length of the range of a glTF mesh's vertices buffer that should
* \b NOT be considered part of the skirt.
*
* Any vertices outside of the range `(noSkirtVerticesBegin,
* noSkirtVerticesBegin + noSkirtVerticesCount)` will be considered part of
* the skirt.
*/
uint32_t noSkirtVerticesCount;
/**
* @brief The center coordinates of the mesh, in \ref glossary-ecef.
*/
glm::dvec3 meshCenter;
/**
* @brief The height of the skirt on the western edge of the mesh.
*/
double skirtWestHeight;
/**
* @brief The height of the skirt on the southern edge of the mesh.
*/
double skirtSouthHeight;
/**
* @brief The height of the skirt on the eastern edge of the mesh.
*/
double skirtEastHeight;
/**
* @brief The height of the skirt on the northern edge of the mesh.
*/
double skirtNorthHeight;
};
} // namespace CesiumGltfContent