21using half_float::half;
25template<std::
floating_po
int F>
26constexpr F
pi = std::numbers::pi_v<F>;
31concept Arithmetic = std::is_arithmetic_v<T> || std::same_as<T, half>;
34[[nodiscard]]
constexpr T
remap(T value, T l1, T h1, T l2, T h2) {
35 return l2 + (value - l1) * (h2 - l2) / (h1 - l1);
39[[nodiscard]]
constexpr T
remap(T value, T h1, T h2) {
40 return value * h2 / h1;
43[[nodiscard]]
constexpr bool isPowerOf2(std::unsigned_integral
auto n) {
44 return n && !(n & (n - 1));
47template<std::
unsigned_
integral T>
52 auto bigger = std::bit_ceil(n);
53 auto smaller = std::bit_floor(n);
54 return (n - smaller) < (bigger - n) ? smaller : bigger;
57[[nodiscard]]
constexpr uint32_t
log2ceil(uint32_t value) {
58 return ((std::bit_cast<uint32_t>(
static_cast<float>(value)) >> 23) & 0xff) - 127;
62 if (
const auto rest = n % alignment; rest > 0) {
63 return alignment - rest;
68template<u
int8_t S, Arithmetic P>
70 static_assert(S >= 2,
"Vectors must have at least two values!");
76 constexpr Vec() =
default;
78 template<std::convertible_to<P>... Vals>
79 requires (
sizeof...(Vals) == S)
80 constexpr Vec(Vals... vals)
81 :
values{static_cast<P>(vals)...} {}
86 [[nodiscard]]
constexpr const P*
data()
const {
90 [[nodiscard]]
constexpr P*
data() {
94 [[nodiscard]]
constexpr uint8_t
size()
const {
100 return this->values[index];
107 return this->values[index];
116 template<u
int8_t SO, Arithmetic PO>
119 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
120 out[i] +=
static_cast<P
>(other[i]);
125 template<u
int8_t SO, Arithmetic PO>
127 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
128 (*this)[i] +=
static_cast<P
>(other[i]);
134 for (uint8_t i = 0; i < S; i++) {
140 template<u
int8_t SO, Arithmetic PO>
143 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
144 out[i] -=
static_cast<P
>(other[i]);
149 template<u
int8_t SO, Arithmetic PO>
151 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
152 (*this)[i] -=
static_cast<P
>(other[i]);
158 for (uint8_t i = 0; i < S; i++) {
159 out[i] *=
static_cast<P
>(scalar);
165 for (uint8_t i = 0; i < S; i++) {
166 (*this)[i] *=
static_cast<P
>(scalar);
172 for (uint8_t i = 0; i < S; i++) {
173 out[i] /=
static_cast<P
>(scalar);
179 for (uint8_t i = 0; i < S; i++) {
180 (*this)[i] /=
static_cast<P
>(scalar);
186 for (uint8_t i = 0; i < S; i++) {
187 out[i] %=
static_cast<P
>(scalar);
193 for (uint8_t i = 0; i < S; i++) {
194 (*this)[i] %=
static_cast<P
>(scalar);
198 template<u
int8_t SO, Arithmetic PO>
200 if constexpr (S != SO) {
203 for (uint8_t i = 0; i < S; i++) {
204 if ((*
this)[i] !=
static_cast<P
>(other[i])) {
212 template<u
int8_t SO, Arithmetic PO = P>
215 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
216 out[i] =
static_cast<PO
>((*this)[i]);
221 template<u
int8_t SO, Arithmetic PO>
224 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
225 out[i] *=
static_cast<P
>(other[i]);
230 template<u
int8_t SO, Arithmetic PO>
233 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
234 out[i] /=
static_cast<P
>(other[i]);
239 template<u
int8_t SO, Arithmetic PO>
242 for (uint8_t i = 0; i < (S > SO ? SO : S); i++) {
243 if constexpr ((std::floating_point<P> && std::floating_point<PO>) || std::floating_point<P>) {
244 out[i] = std::fmod(out[i],
static_cast<P
>(other[i]));
246 out[i] %=
static_cast<P
>(other[i]);
252 [[nodiscard]]
constexpr float magf()
const {
254 for (uint8_t i = 0; i < S; i++) {
255 out += std::pow((*
this)[i], 2);
257 return std::sqrt(out);
260 [[nodiscard]]
constexpr double mag()
const {
262 for (uint8_t i = 0; i < S; i++) {
263 out += std::pow((*
this)[i], 2);
265 return std::sqrt(out);
268 [[nodiscard]]
constexpr P
sum()
const {
270 for (uint8_t i = 0; i < S; i++) {
276 template<Arithmetic PO>
279 for (uint8_t i = 0; i < S; i++) {
280 out[i] = (*this)[i] *
static_cast<P
>(other[i]);
285 template<Arithmetic PO>
290 [[nodiscard]]
constexpr Vec abs()
const {
292 for (uint8_t i = 0; i < S; i++) {
293 out[i] = std::abs(out[i]);
302 [[nodiscard]]
constexpr bool isZero()
const {
303 return *
this ==
zero();
306static_assert(std::is_trivially_copyable_v<Vec<2, float>>);
308#define SOURCEPP_VEC_DEFINE(S) \
309 template<Arithmetic P> \
310 using Vec##S = Vec<S, P>; \
311 using Vec##S##i8 = Vec##S<int8_t>; \
312 using Vec##S##i16 = Vec##S<int16_t>; \
313 using Vec##S##i32 = Vec##S<int32_t>; \
314 using Vec##S##i64 = Vec##S<int64_t>; \
315 using Vec##S##i = Vec##S##i32; \
316 using Vec##S##ui8 = Vec##S<uint8_t>; \
317 using Vec##S##ui16 = Vec##S<uint16_t>; \
318 using Vec##S##ui32 = Vec##S<uint32_t>; \
319 using Vec##S##ui64 = Vec##S<uint64_t>; \
320 using Vec##S##ui = Vec##S##ui32; \
321 using Vec##S##f16 = Vec##S<half>; \
322 using Vec##S##f32 = Vec##S<float>; \
323 using Vec##S##f64 = Vec##S<double>; \
324 using Vec##S##f = Vec##S##f32
330#undef SOURCEPP_VEC_DEFINE
345 const float fx = (
static_cast<float>(this->
x) / 32767.5f) - 1.f;
346 const float fy = (
static_cast<float>(this->
y) / 32767.5f) - 1.f;
347 const float fz = (
static_cast<float>(this->
z) / 16383.5f) - 1.f;
350 float fw = std::sqrt(1.f - fx * fx - fy * fy - fz * fz);
357 return {fx, fy, fz, fw};
360static_assert(std::is_trivially_copyable_v<QuatCompressed48>);
371 const double fx = (
static_cast<double>(this->
x) / 1048575.5) - 1.0f;
372 const double fy = (
static_cast<double>(this->
y) / 1048575.5) - 1.0f;
373 const double fz = (
static_cast<double>(this->
z) / 1048575.5) - 1.0f;
376 double fw = std::sqrt(1.0 - fx * fx - fy * fy - fz * fz);
383 return {
static_cast<float>(fx),
static_cast<float>(fy),
static_cast<float>(fz),
static_cast<float>(fw)};
386static_assert(std::is_trivially_copyable_v<QuatCompressed64>);
388template<u
int8_t M, u
int8_t N, Arithmetic P>
390 static_assert(M >= 2,
"Matrices must have at least two rows!");
391 static_assert(N >= 2,
"Matrices must have at least two columns!");
394 [[nodiscard]] P*
operator[](uint8_t i) {
return this->data[i]; }
396 [[nodiscard]]
const P*
operator[](uint8_t i)
const {
return this->data[i]; }
401static_assert(std::is_trivially_copyable_v<Mat<2, 2, float>>);
403#define SOURCEPP_MAT_DEFINE(M, N) \
404 template<Arithmetic P> \
405 using Mat##M##x##N = Mat<M, N, P>; \
406 using Mat##M##x##N##i8 = Mat##M##x##N<int8_t>; \
407 using Mat##M##x##N##i16 = Mat##M##x##N<int16_t>; \
408 using Mat##M##x##N##i32 = Mat##M##x##N<int32_t>; \
409 using Mat##M##x##N##i64 = Mat##M##x##N<int64_t>; \
410 using Mat##M##x##N##i = Mat##M##x##N##i32; \
411 using Mat##M##x##N##ui8 = Mat##M##x##N<uint8_t>; \
412 using Mat##M##x##N##ui16 = Mat##M##x##N<uint16_t>; \
413 using Mat##M##x##N##ui32 = Mat##M##x##N<uint32_t>; \
414 using Mat##M##x##N##ui64 = Mat##M##x##N<uint64_t>; \
415 using Mat##M##x##N##ui = Mat##M##x##N##ui32; \
416 using Mat##M##x##N##f16 = Mat##M##x##N<half>; \
417 using Mat##M##x##N##f32 = Mat##M##x##N<float>; \
418 using Mat##M##x##N##f64 = Mat##M##x##N<double>; \
419 using Mat##M##x##N##f = Mat##M##x##N##f32
431#undef SOURCEPP_MAT_DEFINE
#define SOURCEPP_VEC_DEFINE(S)
#define SOURCEPP_MAT_DEFINE(M, N)
P * operator[](uint8_t i)
const P * operator[](uint8_t i) const
constexpr T nearestPowerOf2(T n)
constexpr bool isPowerOf2(std::unsigned_integral auto n)
constexpr uint16_t paddingForAlignment(uint16_t alignment, uint64_t n)
constexpr T remap(T value, T l1, T h1, T l2, T h2)
constexpr uint32_t log2ceil(uint32_t value)
Lower precision Quat compressed to 6 bytes.
Lower precision Quat compressed to 8 bytes.
constexpr float magf() const
constexpr Vec< SO, PO > to() const
constexpr Vec operator-(const Vec< SO, PO > &other) const
constexpr Vec operator%(Arithmetic auto scalar) const
constexpr void operator/=(Arithmetic auto scalar)
constexpr Vec operator+(const Vec< SO, PO > &other) const
constexpr P operator[](uint8_t index) const
constexpr const P * data() const
constexpr bool isZero() const
constexpr void operator-=(const Vec< SO, PO > &other)
constexpr P & operator[](uint8_t index)
constexpr P dot(const Vec< S, PO > &other) const
constexpr Vec scale(const Vec< S, PO > &other) const
constexpr void operator*=(Arithmetic auto scalar)
constexpr void operator%=(Arithmetic auto scalar)
constexpr Vec operator-() const
constexpr bool operator==(const Vec< SO, PO > &other) const
static constexpr Vec zero()
constexpr Vec mod(const Vec< SO, PO > &other) const
constexpr Vec operator/(Arithmetic auto scalar) const
constexpr Vec abs() const
constexpr double mag() const
constexpr Vec div(const Vec< SO, PO > &other) const
constexpr Vec operator*(Arithmetic auto scalar) const
constexpr uint8_t size() const
constexpr void operator+=(const Vec< SO, PO > &other)
constexpr Vec(Vals... vals)
constexpr Vec operator+() const
constexpr Vec mul(const Vec< SO, PO > &other) const