Split engine to packages NazaraUtils and NZSL (#375)
* Move code to NazaraUtils and NZSL packages
* Reorder includes
* Tests: Remove glslang and spirv-tools deps
* Tests: Remove glslang init
* Remove NazaraUtils tests and fix Vector4Test
* Fix Linux compilation
* Update msys2-build.yml
* Fix assimp package
* Update xmake.lua
* Update xmake.lua
* Fix shader compilation on MinGW
* Final fixes
* The final fix 2: the fix strikes back!
* Disable cache on CI
* The return of the fix™️
This commit is contained in:
@@ -9,27 +9,17 @@
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Math/Enums.hpp>
|
||||
#include <Nazara/Utils/Algorithm.hpp>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
template<typename T> constexpr T HalfPi = T(1.5707963267948966192313216916398);
|
||||
template<typename T> constexpr T Pi = T(3.1415926535897932384626433832795);
|
||||
template<typename T> constexpr T Sqrt2 = T(1.4142135623730950488016887242097);
|
||||
template<typename T> constexpr T Sqrt3 = T(1.7320508075688772935274463415059);
|
||||
template<typename T> constexpr T Sqrt5 = T(2.2360679774997896964091736687313);
|
||||
|
||||
template<AngleUnit Unit, typename T> class Angle;
|
||||
|
||||
template<typename T> constexpr T Approach(T value, T objective, T increment);
|
||||
template<typename T> constexpr T Clamp(T value, T min, T max);
|
||||
template<typename T, AngleUnit Unit> constexpr Angle<Unit, T> Clamp(Angle<Unit, T> value, T min, T max);
|
||||
template<typename T> T ClearBit(T number, T bit);
|
||||
template<typename T> constexpr std::size_t CountBits(T value);
|
||||
template<typename T> constexpr T DegreeToRadian(T degrees);
|
||||
template<typename T> constexpr T GetNearestPowerOfTwo(T number);
|
||||
|
||||
constexpr unsigned int GetNumberLength(signed char number);
|
||||
constexpr unsigned int GetNumberLength(unsigned char number);
|
||||
unsigned int GetNumberLength(int number);
|
||||
@@ -39,19 +29,8 @@ namespace Nz
|
||||
unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS);
|
||||
template<typename T> constexpr unsigned int IntegralLog2(T number);
|
||||
template<typename T> constexpr unsigned int IntegralLog2Pot(T pot);
|
||||
template<typename T> constexpr T IntegralPow(T base, unsigned int exponent);
|
||||
template<typename T, typename T2> constexpr T Lerp(const T& from, const T& to, const T2& interpolation);
|
||||
template<typename T> constexpr T MultiplyAdd(T x, T y, T z);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b);
|
||||
template<typename T> constexpr bool NumberEquals(T a, T b, T maxDifference);
|
||||
inline std::string NumberToString(long long number, UInt8 radix = 10);
|
||||
template<typename T> constexpr T RadianToDegree(T radians);
|
||||
template<typename T> T SetBit(T number, T bit);
|
||||
inline long long StringToNumber(const std::string_view& str, UInt8 radix = 10, bool* ok = nullptr);
|
||||
template<typename T> bool TestBit(T number, T bit);
|
||||
template<typename T> T ToggleBit(T number, T bit);
|
||||
}
|
||||
|
||||
#include <Nazara/Math/Algorithm.inl>
|
||||
|
||||
@@ -13,149 +13,6 @@
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
namespace Detail
|
||||
{
|
||||
namespace
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
||||
static constexpr unsigned int MultiplyDeBruijnBitPosition[32] =
|
||||
{
|
||||
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
|
||||
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
|
||||
};
|
||||
|
||||
static constexpr unsigned int MultiplyDeBruijnBitPosition2[32] =
|
||||
{
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr std::enable_if_t<sizeof(T) <= sizeof(UInt32), unsigned int> IntegralLog2(T number)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
||||
number |= number >> 1; // first round down to one less than a power of 2
|
||||
number |= number >> 2;
|
||||
number |= number >> 4;
|
||||
number |= number >> 8;
|
||||
number |= number >> 16;
|
||||
|
||||
return MultiplyDeBruijnBitPosition[static_cast<UInt32>(number * 0x07C4ACDDU) >> 27];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr std::enable_if_t<(sizeof(T) > sizeof(UInt32)), unsigned int> IntegralLog2(T number)
|
||||
{
|
||||
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
|
||||
|
||||
// Masking and shifting bits to the right (to bring it back to 32 bits)
|
||||
|
||||
// Call of the function with 32 bits number, if the result is non-null we have our answer
|
||||
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
|
||||
{
|
||||
// The 32 bits mask on the part we are treating
|
||||
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
|
||||
T val = (number & mask) >> i*8; // Masking and shifting bits to the right (to bring it back to 32 bits)
|
||||
|
||||
// Call of the function with 32 bits number, if the result is non-null we have our answer
|
||||
unsigned int log2 = IntegralLog2<UInt32>(val);
|
||||
if (log2)
|
||||
return log2 + i*8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr std::enable_if_t<sizeof(T) <= sizeof(UInt32), unsigned int> IntegralLog2Pot(T number)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
|
||||
return MultiplyDeBruijnBitPosition2[static_cast<UInt32>(number * 0x077CB531U) >> 27];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr std::enable_if_t<(sizeof(T) > sizeof(UInt32)), unsigned int> IntegralLog2Pot(T number)
|
||||
{
|
||||
static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed");
|
||||
|
||||
// The algorithm for logarithm in base 2 only works with numbers greater than 32 bits
|
||||
// This code subdivides the biggest number into 32 bits ones
|
||||
for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32))
|
||||
{
|
||||
// The 32 bits mask on the part we are treating
|
||||
T mask = T(std::numeric_limits<UInt32>::max()) << i*8;
|
||||
UInt32 val = UInt32((number & mask) >> i*8); // Masking and shifting bits to the right (to bring it back to 32 bits)
|
||||
|
||||
// Call of the function with 32 bits number, if the result is non-null we have our answer
|
||||
unsigned int log2 = IntegralLog2Pot<UInt32>(val);
|
||||
if (log2 || val == 1)
|
||||
return log2 + i*8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T> constexpr std::enable_if_t<std::is_floating_point<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
T diff = std::abs(a - b);
|
||||
return diff <= maxDifference;
|
||||
}
|
||||
|
||||
template<typename T> constexpr std::enable_if_t<!std::is_signed<T>::value || (!std::is_integral<T>::value && !std::is_floating_point<T>::value), bool> NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
if (b > a)
|
||||
std::swap(a, b);
|
||||
|
||||
T diff = a - b;
|
||||
return diff <= maxDifference;
|
||||
}
|
||||
|
||||
template<typename T> constexpr std::enable_if_t<std::is_signed<T>::value && std::is_integral<T>::value, bool> NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
if (b > a)
|
||||
std::swap(a, b);
|
||||
|
||||
using UnsignedT = std::make_unsigned_t<T>;
|
||||
return static_cast<UnsignedT>(a) - static_cast<UnsignedT>(b) <= static_cast<UnsignedT>(maxDifference);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Approaches the objective, beginning with value and with increment
|
||||
* \return The nearest value of the objective you can get with the value and the increment for one step
|
||||
*
|
||||
* \param value Initial value
|
||||
* \param objective Target value
|
||||
* \param increment One step value
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline T Approach(T value, T objective, T increment)
|
||||
{
|
||||
if (value < objective)
|
||||
return std::min(value + increment, objective);
|
||||
else if (value > objective)
|
||||
return std::max(value - increment, objective);
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Clamps value between min and max and returns the expected value
|
||||
* \return If value is not in the interval of min..max, value obtained is the nearest limit of this interval
|
||||
*
|
||||
* \param value Value to clamp
|
||||
* \param min Minimum of the interval
|
||||
* \param max Maximum of the interval
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr T Clamp(T value, T min, T max)
|
||||
{
|
||||
return std::max(std::min(value, max), min);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Clamps an angle value between min and max and returns the expected value
|
||||
@@ -171,64 +28,6 @@ namespace Nz
|
||||
return std::max(std::min(value.value, max), min);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ClearBit(T number, T bit)
|
||||
{
|
||||
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
|
||||
return number &= ~(T(1) << bit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets number of bits set in the number
|
||||
* \return The number of bits set to 1
|
||||
*
|
||||
* \param value The value to count bits
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline std::size_t CountBits(T value)
|
||||
{
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan
|
||||
std::size_t count = 0;
|
||||
while (value)
|
||||
{
|
||||
value &= value - 1;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Converts degree to radian
|
||||
* \return The representation in radian of the angle in degree (0..2*pi)
|
||||
*
|
||||
* \param degrees Angle in degree (this is expected between 0..360)
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr T DegreeToRadian(T degrees)
|
||||
{
|
||||
return degrees * T(Pi<T>/180.0);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets the nearest power of two for the number
|
||||
* \return First power of two containing the number
|
||||
*
|
||||
* \param number Number to get nearest power
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline T GetNearestPowerOfTwo(T number)
|
||||
{
|
||||
T x = 1;
|
||||
while (x < number)
|
||||
x <<= 1; // We multiply by 2
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets the number of digits to represent the number in base 10
|
||||
@@ -379,147 +178,6 @@ namespace Nz
|
||||
return GetNumberLength(static_cast<long long>(number)) + precision + 1; // Plus one for the dot
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets the log in base 2 of integral number
|
||||
* \return Log of the number (floor)
|
||||
*
|
||||
* \param number To get log in base 2
|
||||
*
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr unsigned int IntegralLog2(T number)
|
||||
{
|
||||
// Proxy needed to avoid an overload problem
|
||||
return Detail::IntegralLog2<T>(number);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets the log in base 2 of integral number, only works for power of two !
|
||||
* \return Log of the number
|
||||
*
|
||||
* \param pot To get log in base 2
|
||||
*
|
||||
* \remark Only works for power of two
|
||||
* \remark If number is 0, 0 is returned
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr unsigned int IntegralLog2Pot(T pot)
|
||||
{
|
||||
return Detail::IntegralLog2Pot<T>(pot);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Gets the power of integrals
|
||||
* \return base^exponent for integral
|
||||
*
|
||||
* \param base Base of the exponentation
|
||||
* \param exponent Power for the base
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr T IntegralPow(T base, unsigned int exponent)
|
||||
{
|
||||
T r = 1;
|
||||
for (unsigned int i = 0; i < exponent; ++i)
|
||||
r *= base;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Interpolates the value to other one with a factor of interpolation
|
||||
* \return A new value which is the interpolation of two values
|
||||
*
|
||||
* \param from Initial value
|
||||
* \param to Target value
|
||||
* \param interpolation Factor of interpolation
|
||||
*
|
||||
* \remark interpolation is meant to be between 0 and 1, other values are potentially undefined behavior
|
||||
* \remark With NAZARA_DEBUG, a NazaraWarning is produced
|
||||
*
|
||||
* \see Lerp
|
||||
*/
|
||||
template<typename T, typename T2>
|
||||
constexpr T Lerp(const T& from, const T& to, const T2& interpolation)
|
||||
{
|
||||
return static_cast<T>(from + interpolation * (to - from));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Multiplies X and Y, then add Z
|
||||
* \return The result of X * Y + Z
|
||||
*
|
||||
* \param x is X
|
||||
* \param y is Y
|
||||
* \param z is Z
|
||||
*
|
||||
* \remark This function is meant to use a special faster instruction in CPU if possible
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
constexpr T MultiplyAdd(T x, T y, T z)
|
||||
{
|
||||
return x * y + z;
|
||||
}
|
||||
|
||||
#ifdef FP_FAST_FMAF
|
||||
template<>
|
||||
constexpr float MultiplyAdd(float x, float y, float z)
|
||||
{
|
||||
return std::fmaf(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FP_FAST_FMA
|
||||
template<>
|
||||
constexpr double MultiplyAdd(double x, double y, double z)
|
||||
{
|
||||
return std::fma(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FP_FAST_FMAL
|
||||
template<>
|
||||
constexpr long double MultiplyAdd(long double x, long double y, long double z)
|
||||
{
|
||||
return std::fmal(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within a certain epsilon
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline bool NumberEquals(T a, T b)
|
||||
{
|
||||
return NumberEquals(a, b, std::numeric_limits<T>::epsilon());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Checks whether two numbers are equal
|
||||
* \return true if they are equal within the max difference
|
||||
*
|
||||
* \param a First value
|
||||
* \param b Second value
|
||||
* \param maxDifference Epsilon of comparison (expected to be positive)
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr inline bool NumberEquals(T a, T b, T maxDifference)
|
||||
{
|
||||
return Detail::NumberEquals(a, b, maxDifference);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Converts the number to String
|
||||
@@ -572,26 +230,6 @@ namespace Nz
|
||||
return str;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Converts radian to degree
|
||||
* \return The representation in degree of the angle in radian (0..360)
|
||||
*
|
||||
* \param radians Angle in radian (this is expected between 0..2*pi)
|
||||
*/
|
||||
template<typename T>
|
||||
constexpr T RadianToDegree(T radians)
|
||||
{
|
||||
return radians * T(180.0/Pi<T>);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T SetBit(T number, T bit)
|
||||
{
|
||||
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
|
||||
return number |= (T(1) << bit);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \ingroup math
|
||||
* \brief Converts the string to number
|
||||
@@ -656,20 +294,6 @@ namespace Nz
|
||||
|
||||
return (negative) ? -static_cast<long long>(total) : total;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool TestBit(T number, T bit)
|
||||
{
|
||||
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
|
||||
return number & (T(1) << bit);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ToggleBit(T number, T bit)
|
||||
{
|
||||
NazaraAssert(bit < sizeof(number) * CHAR_BIT, "bit index out of range");
|
||||
return number ^= (T(1) << bit);
|
||||
}
|
||||
}
|
||||
|
||||
#include <Nazara/Core/DebugOff.hpp>
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
#ifndef NAZARA_MATH_ANGLE_HPP
|
||||
#define NAZARA_MATH_ANGLE_HPP
|
||||
|
||||
#include <Nazara/Core/TypeTag.hpp>
|
||||
#include <Nazara/Math/Algorithm.hpp>
|
||||
#include <Nazara/Math/Enums.hpp>
|
||||
#include <Nazara/Utils/TypeTag.hpp>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
///FIXME: Matrices column-major, difficile de bosser avec (Tout passer en row-major et transposer dans les shaders ?)
|
||||
|
||||
#include <Nazara/Core/TypeTag.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Math/Config.hpp>
|
||||
#include <Nazara/Utils/TypeTag.hpp>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define NAZARA_MATH_VECTOR2_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/TypeTag.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Utils/TypeTag.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#define NAZARA_MATH_VECTOR3_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/TypeTag.hpp>
|
||||
#include <Nazara/Math/Angle.hpp>
|
||||
#include <Nazara/Utils/TypeTag.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define NAZARA_MATH_VECTOR4_HPP
|
||||
|
||||
#include <Nazara/Prerequisites.hpp>
|
||||
#include <Nazara/Core/TypeTag.hpp>
|
||||
#include <Nazara/Utils/TypeTag.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user