8 constexpr PL_ALWAYS_INLINE T
Square(T f)
14 constexpr PL_ALWAYS_INLINE T
Sign(T f)
16 return (f < 0 ? T(-1) : f > 0 ? T(1)
21 constexpr PL_ALWAYS_INLINE T
Abs(T f)
23 return (f < 0 ? -f : f);
27 constexpr PL_ALWAYS_INLINE T
Min(T f1, T f2)
29 return (f2 < f1 ? f2 : f1);
32 template <
typename T,
typename... ARGS>
33 constexpr PL_ALWAYS_INLINE T
Min(T f1, T f2, ARGS... f)
35 return Min(
Min(f1, f2), f...);
39 constexpr PL_ALWAYS_INLINE T
Max(T f1, T f2)
41 return (f1 < f2 ? f2 : f1);
44 template <
typename T,
typename... ARGS>
45 constexpr PL_ALWAYS_INLINE T
Max(T f1, T f2, ARGS... f)
47 return Max(
Max(f1, f2), f...);
51 constexpr PL_ALWAYS_INLINE T
Clamp(T value, T min_val, T max_val)
53 return value < min_val ? min_val : (max_val < value ? max_val : value);
59 return Clamp(value, T(0), T(1));
62 template <
typename Type>
65 static_assert(std::is_floating_point_v<Type>);
72 PL_ASSERT_DEBUG(value != 0,
"FirstBitLow is undefined for 0");
74#if PL_ENABLED(PL_PLATFORM_WINDOWS)
75 unsigned long uiIndex = 0;
76 _BitScanForward(&uiIndex, value);
78#elif PL_ENABLED(PL_COMPILER_GCC) || PL_ENABLED(PL_COMPILER_CLANG)
79 return __builtin_ctz(value);
81 PL_ASSERT_NOT_IMPLEMENTED;
88 PL_ASSERT_DEBUG(value != 0,
"FirstBitLow is undefined for 0");
92#elif PL_ENABLED(PL_PLATFORM_WINDOWS)
93 unsigned long uiIndex = 0;
94# if PL_ENABLED(PL_PLATFORM_64BIT)
96 _BitScanForward64(&uiIndex, value);
98 uint32_t lower =
static_cast<uint32_t
>(value);
99 unsigned char returnCode = _BitScanForward(&uiIndex, lower);
102 uint32_t upper =
static_cast<uint32_t
>(value >> 32);
103 returnCode = _BitScanForward(&uiIndex, upper);
111#elif PL_ENABLED(PL_COMPILER_GCC) || PL_ENABLED(PL_COMPILER_CLANG)
112 return __builtin_ctzll(value);
114 PL_ASSERT_NOT_IMPLEMENTED;
121 PL_ASSERT_DEBUG(value != 0,
"FirstBitHigh is undefined for 0");
123#if PL_ENABLED(PL_PLATFORM_WINDOWS)
124 unsigned long uiIndex = 0;
125 _BitScanReverse(&uiIndex, value);
127#elif PL_ENABLED(PL_COMPILER_GCC) || PL_ENABLED(PL_COMPILER_CLANG)
128 return 31 - __builtin_clz(value);
130 PL_ASSERT_NOT_IMPLEMENTED;
137 PL_ASSERT_DEBUG(value != 0,
"FirstBitHigh is undefined for 0");
141#elif PL_ENABLED(PL_PLATFORM_WINDOWS)
142 unsigned long uiIndex = 0;
143# if PL_ENABLED(PL_PLATFORM_64BIT)
144 _BitScanReverse64(&uiIndex, value);
146 uint32_t upper =
static_cast<uint32_t
>(value >> 32);
147 unsigned char returnCode = _BitScanReverse(&uiIndex, upper);
150 uint32_t lower =
static_cast<uint32_t
>(value);
151 returnCode = _BitScanReverse(&uiIndex, lower);
159#elif PL_ENABLED(PL_COMPILER_GCC) || PL_ENABLED(PL_COMPILER_CLANG)
160 return 63 - __builtin_clzll(value);
162 PL_ASSERT_NOT_IMPLEMENTED;
169 return (uiBitmask == 0) ? 32 :
FirstBitLow(uiBitmask);
174 const plUInt32 numLow =
CountTrailingZeros(
static_cast<plUInt32
>(uiBitmask & 0xFFFFFFFF));
175 const plUInt32 numHigh =
CountTrailingZeros(
static_cast<plUInt32
>((uiBitmask >> 32u) & 0xFFFFFFFF));
177 return (numLow == 32) ? (32 + numHigh) : numLow;
182 return (uiBitmask == 0) ? 32 : (31u -
FirstBitHigh(uiBitmask));
188#if PL_ENABLED(PL_COMPILER_MSVC) && (PL_ENABLED(PL_PLATFORM_ARCH_X86) || (PL_ENABLED(PL_PLATFORM_ARCH_ARM) && PL_ENABLED(PL_PLATFORM_32BIT)))
189# if PL_ENABLED(PL_PLATFORM_ARCH_X86)
190 return __popcnt(value);
192 return _CountOneBits(value);
194#elif PL_ENABLED(PL_COMPILER_GCC) || PL_ENABLED(PL_COMPILER_CLANG)
195 return __builtin_popcount(value);
197 value = value - ((value >> 1) & 0x55555555u);
198 value = (value & 0x33333333u) + ((value >> 2) & 0x33333333u);
199 return ((value + (value >> 4) & 0xF0F0F0Fu) * 0x1010101u) >> 24;
207 result +=
CountBits(plUInt32(value >> 32));
211 template <
typename Type>
214 return (uiNumBitsToSet >=
sizeof(Type) * 8) ? ~static_cast<Type>(0) : ((
static_cast<Type
>(1) << uiNumBitsToSet) -
static_cast<Type
>(1));
217 template <
typename Type>
220 return (uiNumBitsToSet == 0) ? 0 : ~static_cast<Type>(0) << ((
sizeof(Type) * 8) -
plMath::Min<plUInt32>(uiNumBitsToSet,
sizeof(Type) * 8));
223 template <
typename T>
224 PL_ALWAYS_INLINE
void Swap(T& ref_f1, T& ref_f2)
226 std::swap(ref_f1, ref_f2);
229 template <
typename T>
230 PL_FORCE_INLINE T
Lerp(T f1, T f2,
float fFactor)
233 PL_ASSERT_DEBUG((fFactor >= -0.00001f) && (fFactor <= 1.0f + 0.00001f),
"lerp: factor is not in the range [0; 1]");
235 return (T)(f1 + (fFactor * (f2 - f1)));
238 template <
typename T>
239 PL_FORCE_INLINE T
Lerp(T f1, T f2,
double fFactor)
242 PL_ASSERT_DEBUG((fFactor >= -0.00001) && (fFactor <= 1.0 + 0.00001),
"lerp: factor is not in the range [0; 1]");
244 return (T)(f1 + (fFactor * (f2 - f1)));
247 template <
typename T>
248 PL_FORCE_INLINE
constexpr float Unlerp(T fMin, T fMax, T fValue)
250 return static_cast<float>(fValue - fMin) /
static_cast<float>(fMax - fMin);
254 template <
typename T>
255 constexpr PL_FORCE_INLINE T
Step(T value, T edge)
257 return (value >= edge ? T(1) : T(0));
262 return (value < 1) ? false : ((value & (value - 1)) == 0);
267 return (value < 1) ? false : ((value & (value - 1)) == 0);
272 return (value < 1) ? false : ((value & (value - 1)) == 0);
275 template <
typename Type>
276 constexpr bool IsEqual(Type lhs, Type rhs, Type fEpsilon)
278 return ((rhs >= lhs - fEpsilon) && (rhs <= lhs + fEpsilon));
281 template <
typename T>
282 constexpr inline bool IsInRange(T value, T minVal, T maxVal)
284 return minVal < maxVal ? (value >= minVal) && (value <= maxVal) : (value <= minVal) && (value >= maxVal);
287 template <
typename Type>
290 PL_ASSERT_DEBUG(fEpsilon >= 0,
"Epsilon may not be negative.");
292 return ((f >= -fEpsilon) && (f <= fEpsilon));
295 template <
typename Type>
304 template <
typename Type>
307 return (f -
Trunc(f));
310 template <
typename Type>
313 const Type divider = edge2 - edge1;
315 if (divider == (Type)0)
317 return (x >= edge2) ? 1 : 0;
320 x =
Saturate((x - edge1) / divider);
322 return (x * x * ((Type)3 - ((Type)2 * x)));
325 template <
typename Type>
328 const Type divider = edge2 - edge1;
330 if (divider == (Type)0)
332 return (x >= edge2) ? 1 : 0;
335 x =
Saturate((x - edge1) / divider);
337 return (x * x * x * (x * ((Type)6 * x - (Type)15) + (Type)10));
350 return static_cast<plUInt8
>(
Saturate(value) * 255.0f + 0.5f);
364 return static_cast<plUInt16
>(
Saturate(value) * 65535.0f + 0.5f);
378 value =
Clamp(value, -1.0f, 1.0f) * 127.0f;
387 return static_cast<plInt8
>(value);
401 value =
Clamp(value, -1.0f, 1.0f) * 32767.0f;
410 return static_cast<plInt16
>(value);
418 return value * (1.0f / 255.0f);
425 return value * (1.0f / 65535.0f);
432 return (value == -128) ? -1.0f : value * (1.0f / 127.0f);
439 return (value == -32768) ? -1.0f : value * (1.0f / 32767.0f);
442 template <
typename T,
typename T2>
443 T
EvaluateBezierCurve(T2 t,
const T& startPoint,
const T& controlPoint1,
const T& controlPoint2,
const T& endPoint)
447 const T2 f1 = mt * mt * mt;
448 const T2 f2 = 3 * mt * mt * t;
449 const T2 f3 = 3 * mt * t * t;
450 const T2 f4 = t * t * t;
452 return f1 * startPoint + f2 * controlPoint1 + f3 * controlPoint2 + f4 * endPoint;
464 return static_cast<plInt32
>(value);
467#if PL_DISABLED(PL_PLATFORM_ARCH_X86) || (_MSC_VER <= 1916)
470 return static_cast<plInt64
>(value);
476#if PL_ENABLED(PL_PLATFORM_32BIT)
477 if (uiValue <= MaxValue<size_t>())
479 out_uiResult =
static_cast<size_t>(uiValue);
485 out_uiResult =
static_cast<size_t>(uiValue);
490#if PL_ENABLED(PL_PLATFORM_64BIT)
Float wrapper struct for a safe usage and conversions of angles.
Definition Angle.h:10
constexpr plAngle()
Standard constructor, initializing with 0.
Definition Angle.h:40
constexpr float GetRadian() const
Returns the radian value. (No need for any conversion)
Definition Angle_inl.h:48
static constexpr plAngle AngleBetween(plAngle a, plAngle b)
Computes the smallest angle between the two given angles. The angle will always be a positive value.
Definition Math_inl.h:456
This namespace provides common math-functionality as functions.
Definition Constants.h:6
plInt8 ColorFloatToSignedByte(float value)
Converts a color value from float [-1;1] range to signed byte [-127;127] range, with proper rounding.
Definition Math_inl.h:368
constexpr plInt32 FloatToInt(float value)
Casts the float to an integer, removes the fractional part.
Definition Math_inl.h:462
PL_FORCE_INLINE constexpr float Unlerp(T fMin, T fMax, T fValue)
Returns the interpolation factor such that Lerp(fMin, fMax, factor) == fValue.
Definition Math_inl.h:248
T EvaluateBezierCurve(T2 t, const T &startPoint, const T &controlPoint1, const T &controlPoint2, const T &endPoint)
Evaluates the cubic spline defined by four control points at time t and returns the interpolated resu...
Definition Math_inl.h:443
constexpr PL_ALWAYS_INLINE T Square(T f)
Returns f * f.
Definition Math_inl.h:8
PL_FORCE_INLINE T Lerp(T f1, T f2, float fFactor)
Returns the linear interpolation of f1 and f2. factor is a value between 0 and 1.
Definition Math_inl.h:230
constexpr PL_ALWAYS_INLINE T Min(T f1, T f2)
Returns the smaller value, f1 or f2.
Definition Math_inl.h:27
PL_ALWAYS_INLINE plUInt32 FirstBitHigh(plUInt32 value)
Returns the index of the most significant bit set.
Definition Math_inl.h:119
PL_ALWAYS_INLINE Type Fraction(Type f)
Returns the fraction-part of f.
Definition Math_inl.h:305
constexpr Type Invert(Type f)
Returns 1 / f.
Definition Math_inl.h:63
constexpr PL_ALWAYS_INLINE T Clamp(T value, T min_val, T max_val)
Clamps "value" to the range [min; max]. Returns "value", if it is inside the range already.
Definition Math_inl.h:51
plUInt8 ColorFloatToByte(float value)
Converts a color value from float [0;1] range to unsigned byte [0;255] range, with proper rounding.
Definition Math_inl.h:340
PL_ALWAYS_INLINE plUInt32 FirstBitLow(plUInt32 value)
Returns the index of the least significant bit set.
Definition Math_inl.h:70
constexpr float ColorSignedByteToFloat(plInt8 value)
Converts a color value from signed byte [-128;127] range to float [-1;1] range, with proper rounding.
Definition Math_inl.h:428
PL_FOUNDATION_DLL size_t SafeConvertToSizeT(plUInt64 uiValue)
Checks whether the given 64bit value actually fits into size_t, If it doesn't the program is terminat...
plInt16 ColorFloatToSignedShort(float value)
Converts a color value from float [-1;1] range to signed short [-32767;32767] range,...
Definition Math_inl.h:391
constexpr bool IsInRange(T value, T minVal, T maxVal)
Checks whether the value of the first parameter lies between the value of the second and third.
Definition Math_inl.h:282
plUInt16 ColorFloatToShort(float value)
Converts a color value from float [0;1] range to unsigned short [0;65535] range, with proper rounding...
Definition Math_inl.h:354
constexpr float ColorByteToFloat(plUInt8 value)
Converts a color value from unsigned byte [0;255] range to float [0;1] range, with proper rounding.
Definition Math_inl.h:414
constexpr float ColorSignedShortToFloat(plInt16 value)
Converts a color value from signed short [-32768;32767] range to float [0;1] range,...
Definition Math_inl.h:435
Type SmootherStep(Type x, Type edge1, Type edge2)
Returns 0, if value is <= edge1, 1 if value >= edge2 and the second order hermite interpolation in be...
Definition Math_inl.h:326
PL_ALWAYS_INLINE plUInt32 CountBits(plUInt32 value)
Returns the number of bits set.
Definition Math_inl.h:186
PL_ALWAYS_INLINE Type Bitmask_LowN(plUInt32 uiNumBitsToSet)
Creates a bitmask in which the low N bits are set. For example for N=5, this would be '0000 ....
Definition Math_inl.h:212
PL_ALWAYS_INLINE plUInt32 CountLeadingZeros(plUInt32 uiBitmask)
Definition Math_inl.h:180
constexpr PL_ALWAYS_INLINE T Sign(T f)
Returns the sign of f (i.e: -1, 1 or 0)
Definition Math_inl.h:14
bool IsZero(Type f, Type fEpsilon)
Checks whether the given number is close to zero.
Definition Math_inl.h:288
constexpr bool IsEqual(Type lhs, Type rhs, Type fEpsilon)
Checks, whether fValue is in the range [fDesired - fMaxImprecision; fDesired + fMaxImprecision].
Definition Math_inl.h:276
PL_ALWAYS_INLINE Type Trunc(Type f)
Returns the integer-part of f (removes the fraction).
Definition Math_inl.h:296
PL_ALWAYS_INLINE void Swap(T &ref_f1, T &ref_f2)
Swaps the values in the two variables f1 and f2.
Definition Math_inl.h:224
constexpr PL_ALWAYS_INLINE T Abs(T f)
Returns the absolute value of f.
Definition Math_inl.h:21
plResult TryConvertToSizeT(size_t &out_uiResult, plUInt64 uiValue)
Checks whether the given 64bit value actually fits into size_t, If it doesn't PL_FAILURE is returned.
Definition Math_inl.h:474
constexpr PL_ALWAYS_INLINE T Saturate(T value)
Clamps "value" to the range [0; 1]. Returns "value", if it is inside the range already.
Definition Math_inl.h:57
constexpr PL_ALWAYS_INLINE T Max(T f1, T f2)
Returns the greater value, f1 or f2.
Definition Math_inl.h:39
PL_ALWAYS_INLINE plUInt32 CountTrailingZeros(plUInt32 uiBitmask)
Definition Math_inl.h:167
Type SmoothStep(Type x, Type edge1, Type edge2)
Returns 0, if value is <= edge1, 1 if value >= edge2 and the hermite interpolation in between.
Definition Math_inl.h:311
constexpr PL_FORCE_INLINE bool IsPowerOf2(plInt32 value)
Returns true, if there exists some x with 2^x == value.
Definition Math_inl.h:260
PL_ALWAYS_INLINE Type Bitmask_HighN(plUInt32 uiNumBitsToSet)
Creates a bitmask in which the high N bits are set. For example for N=5, this would be '1111 1000 ....
Definition Math_inl.h:218
constexpr float ColorShortToFloat(plUInt16 value)
Converts a color value from unsigned short [0;65535] range to float [0;1] range, with proper rounding...
Definition Math_inl.h:421
constexpr PL_FORCE_INLINE T Step(T value, T edge)
Returns 0, if value < edge, and 1, if value >= edge.
Definition Math_inl.h:255
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54