NSUNI/NSLAR Library a250670
Loading...
Searching...
No Matches
math.hpp
Go to the documentation of this file.
1
6#pragma once
7#include <algorithm>
8#include <cassert>
9#include <tuple>
10#include <type_traits>
11#define GLM_ENABLE_EXPERIMENTAL
12
13#include <glm/glm.hpp>
14#include <glm/gtx/quaternion.hpp>
15
19#include "NNL/utility/trait.hpp"
20namespace nnl {
25namespace utl::math {
32
39inline bool IsNan(float value) { return std::isnan(value); }
40
49template <typename TContainer>
50bool IsNan(const TContainer& value) {
51 static_assert(std::is_floating_point_v<typename TContainer::value_type>);
52
53 return value != value;
54}
55
61inline bool IsFinite(float value) { return std::isfinite(value); }
62
70template <typename TContainer>
71bool IsFinite(const TContainer& container) {
72 static_assert(std::is_floating_point_v<typename TContainer::value_type>);
73
74 for (std::size_t i = 0; i < static_cast<std::size_t>(TContainer::length()); i++)
75 if (!IsFinite(container[i])) return false; // glm matrices, vectors
76
77 return true;
78}
79
86glm::quat EulerToQuat(glm::vec3 euler);
87
96glm::vec3 QuatToEuler(glm::quat quat);
97
106std::tuple<glm::vec3, glm::quat, glm::vec3> Decompose(const glm::mat4& matrix);
107
116glm::mat4 Compose(glm::vec3 scale, glm::quat rotation, glm::vec3 translation);
117
129glm::mat4 InverseSafe(const glm::mat4& m);
130
134glm::mat3 InverseSafe(const glm::mat3& m);
135
146glm::mat4 Inverse(const glm::mat4& m);
147
151glm::mat3 Inverse(const glm::mat3& m);
162glm::vec3 NormalizeSafe(const glm::vec3& vec);
169template <typename T>
170constexpr inline T Sqr(T value) {
171 static_assert(std::is_arithmetic_v<T>);
172 return value * value;
173}
174
181template <typename T>
182bool IsPow2(T n) {
183 static_assert(std::is_integral_v<T>);
184 return (n > 0 && ((n & (n - 1)) == 0));
185}
186
192inline u32 RoundUpPow2(u32 v) {
193 NNL_EXPECTS_DBG(v >= 1 && v <= 2147483648);
194 v--;
195 v |= v >> 1;
196 v |= v >> 2;
197 v |= v >> 4;
198 v |= v >> 8;
199 v |= v >> 16;
200 v++;
201 return v;
202}
203
209inline u32 RoundDownPow2(u32 v) { return IsPow2(v) ? v : RoundUpPow2(v) >> 1; }
210
218template <typename T>
219T RoundNum(T number, std::size_t multiple) {
220 static_assert(std::is_integral_v<T>);
221
222 if (multiple == 0) return number;
223
224 if (number % multiple != 0) return ((number / multiple) + 1) * multiple;
225
226 return number;
227}
228
238template <typename T, std::size_t num_int = 0>
239constexpr T FloatToFixed(f32 value) {
240 static_assert(std::is_integral_v<T>);
241 static_assert(num_int < std::numeric_limits<T>::digits, "no fractional bits");
242 static_assert(sizeof(T) < sizeof(f32));
244
245 std::size_t fraction = std::numeric_limits<T>::digits - num_int;
246 f32 res = std::round(value * static_cast<f32>(1U << fraction));
247 res = std::clamp<int>(res, std::numeric_limits<T>::min(), std::numeric_limits<T>::max());
248 return static_cast<T>(res);
249}
250
260template <typename T, std::size_t num_int = 0>
261constexpr f32 FixedToFloat(T value) {
262 static_assert(std::is_integral_v<T>);
263 static_assert(num_int < std::numeric_limits<T>::digits, "no fractional bits");
264 static_assert(sizeof(T) < sizeof(f32));
265 std::size_t fraction = std::numeric_limits<T>::digits - num_int;
266 f32 res = static_cast<f32>(value) / static_cast<f32>(1U << fraction);
267 return res;
268}
269
277inline bool IsApproxEqual(float a, float b, float range = NNL_EPSILON) {
278 if (std::abs(a - b) > range) return false;
279 return true;
280}
281
289template <typename TContainer>
290bool IsApproxEqual(TContainer a, TContainer b, float range = NNL_EPSILON) {
291 static_assert(std::is_floating_point_v<typename TContainer::value_type>);
292
293 std::size_t size = 0;
294
296 if (a.size() != b.size()) return false;
297 size = static_cast<std::size_t>(a.size());
298 } else {
299 size = static_cast<std::size_t>(TContainer::length());
300 }
301
302 for (std::size_t i = 0; i < size; i++)
303 if (!IsApproxEqual(a[i], b[i], range)) return false;
304
305 return true;
306}
307
308} // namespace utl::math
309} // namespace nnl
Global configuration constants for the library.
Defines macros for Design-by-Contract verification.
Contains macros and definitions for fixed-width types.
#define NNL_EPSILON
Default floating-point comparison epsilon.
Definition constant.hpp:52
#define NNL_EXPECTS_DBG(precondition)
Debug-only precondition check.
Definition contract.hpp:59
float f32
32-bit floating point
Definition fixed_type.hpp:59
std::uint32_t u32
32-bit unsigned integer
Definition fixed_type.hpp:60
constexpr T Sqr(T value)
Calculates the square of a value.
Definition math.hpp:170
bool IsPow2(T n)
Checks whether a number can be expressed as an integer power of 2.
Definition math.hpp:182
u32 RoundDownPow2(u32 v)
Rounds down to the previous power of 2.
Definition math.hpp:209
bool IsFinite(float value)
Checks if a floating-point value is finite.
Definition math.hpp:61
glm::mat4 Compose(glm::vec3 scale, glm::quat rotation, glm::vec3 translation)
Composes a transformation matrix from scale, rotation, and translation.
glm::vec3 QuatToEuler(glm::quat quat)
Converts quaternion to Euler angles (Pitch X, Yaw Y, Roll Z)
glm::vec3 NormalizeSafe(const glm::vec3 &vec)
Normalizes a vector safely.
T RoundNum(T number, std::size_t multiple)
Rounds number up to the nearest multiple.
Definition math.hpp:219
glm::mat4 Inverse(const glm::mat4 &m)
Computes the inverse of a matrix.
constexpr f32 FixedToFloat(T value)
Converts a fixed-point value to a float value.
Definition math.hpp:261
glm::mat4 InverseSafe(const glm::mat4 &m)
Computes the inverse of a matrix safely.
glm::quat EulerToQuat(glm::vec3 euler)
Converts Euler angles in degrees (Pitch X, Yaw Y, Roll Z) to a quaternion.
bool IsApproxEqual(float a, float b, float range=NNL_EPSILON)
Checks if floating-point numbers are approximately equal.
Definition math.hpp:277
std::tuple< glm::vec3, glm::quat, glm::vec3 > Decompose(const glm::mat4 &matrix)
Decomposes a transformation matrix into scale, rotation, and translation.
constexpr T FloatToFixed(f32 value)
Converts a float value to a fixed point value.
Definition math.hpp:239
bool IsNan(float value)
Checks if a floating-point value is not a number.
Definition math.hpp:39
u32 RoundUpPow2(u32 v)
Rounds up the number to the next power of 2.
Definition math.hpp:192
constexpr bool has_size_member_v
Type trait to detect if a type T has a size() member function.
Definition trait.hpp:58
Provides various math utility functions.
Definition math.hpp:25
Definition exception.hpp:56
Provides additional type trait utilities.