Files
BXSSP_Andriod/Plugins/CesiumForUnreal/Source/ThirdParty/include/CesiumRasterOverlays/RasterOverlayUtilities.h

195 lines
8.9 KiB
C++

#pragma once
#include "Library.h"
#include "RasterOverlayDetails.h"
#include <CesiumGeometry/QuadtreeTileID.h>
#include <CesiumGeospatial/Ellipsoid.h>
#include <CesiumGeospatial/Projection.h>
#include <glm/fwd.hpp>
#include <optional>
#include <string_view>
#include <vector>
namespace CesiumGltf {
struct Model;
}
namespace CesiumRasterOverlays {
/**
* @brief A collection of utilities useful for operations involving raster
* overlay tiles.
*/
struct CESIUMRASTEROVERLAYS_API RasterOverlayUtilities {
/**
* @brief Texture coordinates will be stored in the glTF under the following
* name, appended with a number. See \ref
* createRasterOverlayTextureCoordinates.
*/
static constexpr std::string_view DEFAULT_TEXTURE_COORDINATE_BASE_NAME =
"_CESIUMOVERLAY_";
/**
* @brief Creates texture coordinates for mapping {@link RasterOverlay} tiles
* to a glTF model.
*
* Generates new texture coordinates for the `gltf` using the given
* `projections`. The first new texture coordinate (`u` or `s`) will be 0.0 at
* the `minimumX` of the given `rectangle` and 1.0 at the `maximumX`. The
* second texture coordinate (`v` or `t`) will be 0.0 at the `minimumY` of
* the given `rectangle` and 1.0 at the `maximumY`.
*
* Coordinate values for vertices in between these extremes are determined by
* projecting the vertex position with the `projection` and then computing the
* fractional distance of that projected position between the minimum and
* maximum.
*
* Projected positions that fall outside the `globeRectangle` will be clamped
* to the edges, so the coordinate values will never be less then 0.0 or
* greater than 1.0.
*
* These texture coordinates are stored in the provided glTF, and a new
* primitive attribute is added to each primitive for each projection. The new
* primitive attributes are named with `textureCoordinateAttributeBaseName`
* followed by a number, starting with `firstTextureCoordinateID` and
* incrementing for each projection. For example, if
* `textureCoordinateAttributeBaseName` is
* `_CESIUMOVERLAY_` and `firstTextureCoordinateID` is 0 (the defaults), then
* the texture coordinates for the first projection will be stored in an
* attribute named `_CESIUMOVERLAY_0`, the second will be in
* `_CESIUMOVERLAY_1`, and so on.
*
* @param gltf The glTF model.
* @param modelToEcefTransform The transformation of this glTF to ECEF
* coordinates.
* @param globeRectangle The rectangle that all projected vertex positions are
* expected to lie within. If this parameter is std::nullopt, it is computed
* from the vertices.
* @param projections The projections for which to generate texture
* coordinates. There is a linear relationship between the coordinates of this
* projection and the generated texture coordinates.
* @param invertVCoordinate True if the V texture coordinate should be
* inverted so that it is 1.0 at the Southern end of the rectangle and 0.0 at
* the Northern end. This is useful with images that use the typical North-up
* orientation.
* @param textureCoordinateAttributeBaseName The base name to use for the
* texture coordinate attributes, without a number on the end. Defaults to
* {@link DEFAULT_TEXTURE_COORDINATE_BASE_NAME}.
* @param firstTextureCoordinateID The texture coordinate ID of the first
* projection.
* @return The details of the generated texture coordinates.
*/
static std::optional<RasterOverlayDetails>
createRasterOverlayTextureCoordinates(
CesiumGltf::Model& gltf,
const glm::dmat4& modelToEcefTransform,
const std::optional<CesiumGeospatial::GlobeRectangle>& globeRectangle,
std::vector<CesiumGeospatial::Projection>&& projections,
bool invertVCoordinate = false,
const std::string_view& textureCoordinateAttributeBaseName =
DEFAULT_TEXTURE_COORDINATE_BASE_NAME,
int32_t firstTextureCoordinateID = 0);
/**
* @brief Creates a new glTF model from one of the quadtree children of the
* given parent model.
*
* The parent model subdivision is guided by texture coordinates. These
* texture coordinates must follow a map projection, and the parent tile is
* divided into quadrants as divided by this map projection. To create the
* necessary texture coordinates, use
* {@link createRasterOverlayTextureCoordinates}.
*
* @param parentModel The parent model to upsample.
* @param childID The quadtree tile ID of the child model. This is used to
* determine which of the four children of the parent tile to generate.
* @param hasInvertedVCoordinate True if the V texture coordinate has 0.0 as
* the Northern-most coordinate; False if the V texture coordinate has 0.0 as
* the Southern-most coordiante.
* @param textureCoordinateAttributeBaseName The base name of the attribute
* that holds the projected texture coordinates. The `textureCoordinateIndex`
* is appended to this name. Defaults to
* {@link DEFAULT_TEXTURE_COORDINATE_BASE_NAME}.
* @param textureCoordinateIndex The index of the texture coordinate set to
* use. For example, if `textureCoordinateAttributeBaseName` is
* `_CESIUMOVERLAY_` and this parameter is 0 (the defaults), then the texture
* coordinates are read from a vertex attribute named `_CESIUMOVERLAY_0`.
* @param ellipsoid The {@link CesiumGeospatial::Ellipsoid}.
* @return The upsampled model.
*/
static std::optional<CesiumGltf::Model> upsampleGltfForRasterOverlays(
const CesiumGltf::Model& parentModel,
CesiumGeometry::UpsampledQuadtreeNode childID,
bool hasInvertedVCoordinate = false,
const std::string_view& textureCoordinateAttributeBaseName =
DEFAULT_TEXTURE_COORDINATE_BASE_NAME,
int32_t textureCoordinateIndex = 0,
const CesiumGeospatial::Ellipsoid& ellipsoid =
CesiumGeospatial::Ellipsoid::WGS84);
/**
* @brief Computes the desired screen pixels for a raster overlay texture.
*
* This method is used to determine the appropriate number of "screen pixels"
* to use for a raster overlay texture to be attached to a glTF (which is
* usually a 3D Tiles tile). In other words, how detailed should the texture
* be? The answer depends, of course, on how close we'll get to the model. If
* we're going to get very close, we'll need a higher-resolution raster
* overlay texture than if we will stay far away from it.
*
* In 3D Tiles, we can only get so close to a model before it switches to the
* next higher level-of-detail by showing its children instead. The switch
* distance is controlled by the `geometric error` of the tile, as well as by
* the `maximum screen space error` of the tileset. So this method requires
* both of those parameters.
*
* The answer also depends on the size of the model on the screen at this
* switch distance. To determine that, this method takes a projection and a
* rectangle that bounds the tile, expressed in that projection. This
* rectangle is projected onto the screen at the switch distance, and the size
* of that rectangle on the screen is the `target screen pixels` returned by
* this method.
*
* The `target screen pixels` returned here may be further modified by the
* raster overlay's {@link RasterOverlayTileProvider::getTile} method. In particular, it
* will usually be divided by the raster overlay's `maximum screen space
* error` of the raster overlay (not to be confused with the `maximum screen
* space error` of the tileset, mentioned above).
*
* @param geometricError The geometric error of the tile.
* @param maximumScreenSpaceError The maximum screen-space error used to
* render the tileset.
* @param projection The projection in which the `rectangle` parameter is
* provided.
* @param rectangle The 2D extent of the tile, expressed in the `projection`.
* @param ellipsoid The ellipsoid with which computations are performed.
* @return The desired screen pixels.
*/
static glm::dvec2 computeDesiredScreenPixels(
double geometricError,
double maximumScreenSpaceError,
const CesiumGeospatial::Projection& projection,
const CesiumGeometry::Rectangle& rectangle,
const CesiumGeospatial::Ellipsoid& ellipsoid CESIUM_DEFAULT_ELLIPSOID);
/**
* @brief Computes the texture translation and scale necessary to align a
* raster overlay with the given rectangle on geometry whose texture
* coordinates were computed using a different rectangle.
*
* @param geometryRectangle The geometry rectangle used to the compute the
* texture coordinates.
* @param overlayRectangle The rectangle covered by the raster overlay
* texture.
* @return The translation in X and Y, and the scale in Z and W.
*/
static glm::dvec4 computeTranslationAndScale(
const CesiumGeometry::Rectangle& geometryRectangle,
const CesiumGeometry::Rectangle& overlayRectangle);
};
} // namespace CesiumRasterOverlays