bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Private/VecMath.h
2025-02-07 22:52:32 +08:00

363 lines
10 KiB
C++

// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Math/Matrix.h"
#include <glm/glm.hpp>
#include <algorithm>
#include <cmath>
#include <limits>
#include <type_traits>
/**
* @brief Vector math utility functions.
*
* The functions in this class mainly perform conversions between
* the `glm` types and the Unreal Engine types, as well as basic,
* frequently used mathematical operations on these types.
*
* As far as possible these functions will internally perform the
* computations with `double` precision.
*
*/
class VecMath {
public:
/**
* @brief Create a `glm` 4x4 matrix from the given `FMatrix`.
*
* @param m The `FMatrix`.
* @return The `glm` matrix.
*/
static glm::dmat4 createMatrix4D(const FMatrix& m) noexcept;
/**
* @brief Create a `glm` 4x4 matrix from the given `FMatrix`.
*
* This will use the elements of the given matrix, but replace
* the translation column with the given translation vector.
*
* @param m The `FMatrix`.
* @param translation The translation vector.
* @return The `glm` matrix.
*/
static glm::dmat4
createMatrix4D(const FMatrix& m, const glm::dvec3& translation) noexcept;
/**
* @brief Create a `glm` 4x4 matrix from the given `FMatrix`.
*
* This will use the elements of the given matrix, but replace
* the translation column with the given translation.
*
* @param m The `FMatrix`.
* @param tx The translation in x-direction
* @param ty The translation in y-direction
* @param tz The translation in z-direction
* @param tw The w-component of the translation, usually 1.0
* @return The `glm` matrix.
*/
static glm::dmat4 createMatrix4D(
const FMatrix& m,
double tx,
double ty,
double tz,
double tw) noexcept;
/**
* @brief Create a `glm` 4x4 matrix from the given `FMatrix`.
*
* This will use the elements of the given matrix, but replace
* the translation column with the given translation vector.
*
* @param m The `FMatrix`.
* @param translation The translation vector.
* @return The `glm` matrix.
*/
static glm::dmat4
createMatrix4D(const FMatrix& m, const glm::dvec4& translation) noexcept;
/**
* @brief Create a translation matrix from the given vector.
*
* This will return an identity matrix where the
* the translation column is set to be the given
* translation vector.
*
* @param translation The translation vector.
* @return The `glm` matrix.
*/
static glm::dmat4 createTranslationMatrix4D(
double tx,
double ty,
double tz,
double tw) noexcept;
/**
* @brief Create a rotation matrix from the given `FRotator`.
*
* This will return an identity matrix where the
* the upper-left 3x3 matrix is set to be the matrix conversion
* of the input FRotator.
*
* @param rot The `FRotator`.
* @return The `glm` matrix.
*/
static glm::dmat4 createRotationMatrix4D(const FRotator& rot) noexcept;
/**
* @brief Create a `glm` vector from the given `FVector`.
*
* @param v The `FVector`
* @return The `glm` vector
*/
static glm::dvec3 createVector3D(const FVector& v) noexcept;
/**
* @brief Create a `glm` vector from the given `FIntVector`.
*
* @param v The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec3 createVector3D(const FIntVector& v) noexcept;
/**
* @brief Create a `glm` double-precision quaternion from the given `FQuat`.
*
* @param q The `FQuat`
* @return The `glm` quaternion
*/
static glm::dquat createQuaternion(const FQuat& q) noexcept;
/**
* @brief Create a `FMatrix` from the given `glm` matrix.
*
* The result will be an identity matrix, with the upper-left 3x3
* matrix to be set to the given input.
*
* @param m The `glm` matrix.
* @return The `FMatrix`.
*/
static FMatrix createMatrix(const glm::dmat3& m) noexcept;
/**
* @brief Create a `FMatrix` from the given `glm` matrix.
*
* If the ultimate goal is to create an `FTransform`, use
* {@link createTransform} instead.
*
* @param m The `glm` matrix.
* @return The `FMatrix`.
*/
static FMatrix createMatrix(const glm::dmat4& m) noexcept;
/**
* @brief Create a `FTransform` from the given `glm` matrix.
*
* @param m The `glm` matrix.
* @return The `FTransform`.
*/
static FTransform createTransform(const glm::dmat4& m) noexcept;
/**
* @brief Create a `FMatrix` from the given `glm` columns
*
* The result will be an identity matrix, with the upper-left 3x3
* matrix to be set to the given columns
*
* @param column0 The first column
* @param column1 The second column
* @param column2 The third column
* @return The `FMatrix`.
*/
static FMatrix createMatrix(
const glm::dvec3& column0,
const glm::dvec3& column1,
const glm::dvec3& column2) noexcept;
/**
* @brief Create an `FVector` from the given `glm` 4D vector.
*
* @param v The `glm` vector.
* @return The `FVector`.
*
*/
static FVector createVector(const glm::dvec4& v) noexcept;
/**
* @brief Create an `FVector` from the given `glm` 3D vector.
*
* @param v The `glm` vector.
* @return The `FVector`.
*
*/
static FVector createVector(const glm::dvec3& v) noexcept;
/**
* @brief Create a `FRotator` from the given `glm` matrix.
*
* The result will be an `FRotator`. Note that any translation and scaling
* information will be lost.
*
* This method assumes that `m` is already associated with the left-handed UE
* coordinate system.
*
* @param m The `gl` matrix.
* @return The `FRotator`.
*/
static FRotator createRotator(const glm::dmat4& m) noexcept;
/**
* @brief Create a `FRotator` from the given `glm` matrix.
*
* This method assumes that `m` is already associated with the left-handed UE
* coordinate system.
*
* @param m The `glm` matrix.
* @return The `FRotator`.
*/
static FRotator createRotator(const glm::dmat3& m) noexcept;
/**
* @brief Create a `FRotator` from the given `glm` quaternion.
*
* This method assumes that `q` is already associated with the left-handed UE
* coordinate system.
*
* @param q The `glm` quaternion.
* @return The `FRotator`.
*/
static FRotator createRotator(const glm::dquat& q) noexcept;
/**
* @brief Create a `FQuat` from the given `glm` quaternion.
*
* @param q The `glm` quaternion.
* @return The `FQuat`.
*/
static FQuat createQuaternion(const glm::dquat& q) noexcept;
/**
* @brief Add the given `FVector` and `FIntVector`, to create a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param f The `FVector`
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec4 add4D(const FVector& f, const FIntVector& i) noexcept;
/**
* @brief Add the given `FIntVector` and `FVector`, to create a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param i The `FIntVector`
* @param f The `FVector`
* @return The `glm` vector
*/
static glm::dvec4 add4D(const FIntVector& i, const FVector& f) noexcept;
/**
* @brief Add the `glm` vector and `FIntVector`, to create a `glm` vector.
*
* @param d The `glm` vector
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec4 add4D(const glm::dvec4& d, const FIntVector& i) noexcept;
/**
* @brief Add the given `FVector` and `FIntVector`, to create a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param f The `FVector`
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec3 add3D(const FVector& f, const FIntVector& i) noexcept;
/**
* @brief Add the given `FIntVector` and `FVector`, to create a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param i The `FIntVector`
* @param f The `FVector`
* @return The `glm` vector
*/
static glm::dvec3 add3D(const FIntVector& i, const FVector& f) noexcept;
/**
* @brief Add the `glm` vector and `FIntVector`, to create a `glm` vector.
*
* @param d The `glm` vector
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec3 add3D(const glm::dvec3& d, const FIntVector& i) noexcept;
/**
* @brief Subtract the given `FIntVector` from the given `FVector`, to create
* a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param f The `FVector`
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec4 subtract4D(const FVector& f, const FIntVector& i) noexcept;
/**
* @brief Subtract the given `FVector` from the given `FIntVector`, to create
* a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param i The `FIntVector`
* @param f The `FVector`
* @return The `glm` vector
*/
static glm::dvec4 subtract4D(const FIntVector& i, const FVector& f) noexcept;
/**
* @brief Subtract the given `FIntVector` from the given `FVector`, to create
* a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param f The `FVector`
* @param i The `FIntVector`
* @return The `glm` vector
*/
static glm::dvec3 subtract3D(const FVector& f, const FIntVector& i) noexcept;
/**
* @brief Subtract the given `FVector` from the given `FIntVector`, to create
* a `glm` vector.
*
* This will internally perform the computation with `double` precision.
*
* @param i The `FIntVector`
* @param f The `FVector`
* @return The `glm` vector
*/
static glm::dvec3 subtract3D(const FIntVector& i, const FVector& f) noexcept;
};
template <class IntType>
std::enable_if_t<std::is_signed_v<IntType>, float> GltfNormalized(IntType val) {
return std::max(
static_cast<float>(val) / std::numeric_limits<IntType>::max(),
-1.0f);
}
template <class IntType>
std::enable_if_t<std::is_unsigned_v<IntType>, float>
GltfNormalized(IntType val) {
return static_cast<float>(val) / std::numeric_limits<IntType>::max();
}