From b220cbf336535d4541970895868f524ffbefe782 Mon Sep 17 00:00:00 2001 From: bicarus-dev <202771338+bicarus-dev@users.noreply.github.com> Date: Sun, 14 Dec 2025 04:37:28 -0800 Subject: [PATCH] build: remove linalg library (#448) I think this was used for DRS VR support. --- src/spice2x/external/linalg.h | 721 ---------------------------------- src/spice2x/games/drs/drs.h | 1 - src/spice2x/licenses.txt | 4 - 3 files changed, 726 deletions(-) delete mode 100644 src/spice2x/external/linalg.h diff --git a/src/spice2x/external/linalg.h b/src/spice2x/external/linalg.h deleted file mode 100644 index aff292a..0000000 --- a/src/spice2x/external/linalg.h +++ /dev/null @@ -1,721 +0,0 @@ -// linalg.h - 2.2-beta - Single-header public domain linear algebra library -// -// The intent of this library is to provide the bulk of the functionality -// you need to write programs that frequently use small, fixed-size vectors -// and matrices, in domains such as computational geometry or computer -// graphics. It strives for terse, readable source code. -// -// The original author of this software is Sterling Orsten, and its permanent -// home is . If you find this software -// useful, an acknowledgement in your source text and/or product documentation -// is appreciated, but not required. -// -// The author acknowledges significant insights and contributions by: -// Stan Melax -// Dimitri Diakopoulos -// -// Some features are deprecated. Define LINALG_FORWARD_COMPATIBLE to remove them. - - - -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. -// -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to - - - -#pragma once -#ifndef LINALG_H -#define LINALG_H - -#include // For various unary math functions, such as std::sqrt -#include // To resolve std::abs ambiguity on clang -#include // For implementing namespace linalg::aliases -#include // For std::array -#include // For forward definitions of std::ostream -#include // For std::enable_if, std::is_same, std::declval -#include // For std::hash declaration - -// In Visual Studio 2015, `constexpr` applied to a member function implies `const`, which causes ambiguous overload resolution -#if _MSC_VER <= 1900 -#define LINALG_CONSTEXPR14 -#else -#define LINALG_CONSTEXPR14 constexpr -#endif - -namespace linalg -{ - // Small, fixed-length vector type, consisting of exactly M elements of type T, and presumed to be a column-vector unless otherwise noted. - template struct vec; - - // Small, fixed-size matrix type, consisting of exactly M rows and N columns of type T, stored in column-major order. - template struct mat; - - // Specialize converter with a function application operator that converts type U to type T to enable implicit conversions - template struct converter {}; - namespace detail - { - template using conv_t = typename std::enable_if::value, decltype(converter{}(std::declval()))>::type; - - // Trait for retrieving scalar type of any linear algebra object - template struct scalar_type {}; - template struct scalar_type> { using type = T; }; - template struct scalar_type> { using type = T; }; - - // Type returned by the compare(...) function which supports all six comparison operators against 0 - template struct ord { T a,b; }; - template constexpr bool operator == (const ord & o, std::nullptr_t) { return o.a == o.b; } - template constexpr bool operator != (const ord & o, std::nullptr_t) { return !(o.a == o.b); } - template constexpr bool operator < (const ord & o, std::nullptr_t) { return o.a < o.b; } - template constexpr bool operator > (const ord & o, std::nullptr_t) { return o.b < o.a; } - template constexpr bool operator <= (const ord & o, std::nullptr_t) { return !(o.b < o.a); } - template constexpr bool operator >= (const ord & o, std::nullptr_t) { return !(o.a < o.b); } - - // Patterns which can be used with the compare(...) function - template struct any_compare {}; - template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return ord{a.x,b.x}; } }; - template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : ord{a.y,b.y}; } }; - template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : !(a.y==b.y) ? ord{a.y,b.y} : ord{a.z,b.z}; } }; - template struct any_compare,vec> { using type=ord; constexpr ord operator() (const vec & a, const vec & b) const { return !(a.x==b.x) ? ord{a.x,b.x} : !(a.y==b.y) ? ord{a.y,b.y} : !(a.z==b.z) ? ord{a.z,b.z} : ord{a.w,b.w}; } }; - template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return compare(a.x,b.x); } }; - template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : compare(a.y,b.y); } }; - template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : a.y!=b.y ? compare(a.y,b.y) : compare(a.z,b.z); } }; - template struct any_compare,mat> { using type=ord; constexpr ord operator() (const mat & a, const mat & b) const { return a.x!=b.x ? compare(a.x,b.x) : a.y!=b.y ? compare(a.y,b.y) : a.z!=b.z ? compare(a.z,b.z) : compare(a.w,b.w); } }; - - // Helper for compile-time index-based access to members of vector and matrix types - template struct getter; - template<> struct getter<0> { template constexpr auto operator() (A & a) const -> decltype(a.x) { return a.x; } }; - template<> struct getter<1> { template constexpr auto operator() (A & a) const -> decltype(a.y) { return a.y; } }; - template<> struct getter<2> { template constexpr auto operator() (A & a) const -> decltype(a.z) { return a.z; } }; - template<> struct getter<3> { template constexpr auto operator() (A & a) const -> decltype(a.w) { return a.w; } }; - - // Stand-in for std::integer_sequence/std::make_integer_sequence - template struct seq {}; - template struct make_seq_impl; - template struct make_seq_impl { using type=seq<>; }; - template struct make_seq_impl { using type=seq; }; - template struct make_seq_impl { using type=seq; }; - template struct make_seq_impl { using type=seq; }; - template struct make_seq_impl { using type=seq; }; - template using make_seq = typename make_seq_impl::type; - template vec constexpr swizzle(const vec & v, seq i) { return {getter{}(v)...}; } - template mat constexpr swizzle(const mat & m, seq i, seq j) { return {swizzle(getter{}(m),i)...}; } - - // SFINAE helpers to determine result of function application - template using ret_t = decltype(std::declval()(std::declval()...)); - - // SFINAE helper which is defined if all provided types are scalars - struct empty {}; - template struct scalars; - template<> struct scalars<> { using type=void; }; - template struct scalars : std::conditional::value, scalars, empty>::type {}; - template using scalars_t = typename scalars::type; - - // Helpers which indicate how apply(F, ...) should be called for various arguments - template struct apply {}; // Patterns which contain only vectors or scalars - template struct apply, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a ) { return {f(getter{}(a) )...}; } }; - template struct apply, vec, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b ) { return {f(getter{}(a), getter{}(b) )...}; } }; - template struct apply, vec, B > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b ) { return {f(getter{}(a), b )...}; } }; - template struct apply, A, vec > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b ) { return {f(a, getter{}(b) )...}; } }; - template struct apply, vec, vec, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b, const vec & c) { return {f(getter{}(a), getter{}(b), getter{}(c))...}; } }; - template struct apply, vec, vec, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, const vec & b, C c) { return {f(getter{}(a), getter{}(b), c )...}; } }; - template struct apply, vec, B, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b, const vec & c) { return {f(getter{}(a), b, getter{}(c))...}; } }; - template struct apply, vec, B, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, const vec & a, B b, C c) { return {f(getter{}(a), b, c )...}; } }; - template struct apply, A, vec, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b, const vec & c) { return {f(a, getter{}(b), getter{}(c))...}; } }; - template struct apply, A, vec, C > { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, const vec & b, C c) { return {f(a, getter{}(b), c )...}; } }; - template struct apply, A, B, vec> { using type=vec,M>; enum {size=M, mm=0}; template static constexpr type impl(seq, F f, A a, B b, const vec & c) { return {f(a, b, getter{}(c))...}; } }; - template struct apply, mat > { using type=mat,M,N>; enum {size=N, mm=0}; template static constexpr type impl(seq, F f, const mat & a ) { return {apply >::impl(make_seq<0,M>{}, f, getter{}(a) )...}; } }; - template struct apply, mat, mat> { using type=mat,M,N>; enum {size=N, mm=1}; template static constexpr type impl(seq, F f, const mat & a, const mat & b) { return {apply, vec>::impl(make_seq<0,M>{}, f, getter{}(a), getter{}(b))...}; } }; - template struct apply, mat, B > { using type=mat,M,N>; enum {size=N, mm=0}; template static constexpr type impl(seq, F f, const mat & a, B b) { return {apply, B >::impl(make_seq<0,M>{}, f, getter{}(a), b )...}; } }; - template struct apply, A, mat> { using type=mat,M,N>; enum {size=N, mm=0}; template static constexpr type impl(seq, F f, A a, const mat & b) { return {apply>::impl(make_seq<0,M>{}, f, a, getter{}(b))...}; } }; - template struct apply, A...> { using type = ret_t; enum {size=0, mm=0}; static constexpr type impl(seq<>, F f, A... a) { return f(a...); } }; - - // Function objects for selecting between alternatives - struct min { template constexpr auto operator() (A a, B b) const -> typename std::remove_reference::type { return a constexpr auto operator() (A a, B b) const -> typename std::remove_reference::type { return a constexpr auto operator() (A a, B b, C c) const -> typename std::remove_reference::type { return a constexpr auto operator() (A a, B b, C c) const -> typename std::remove_reference::type { return a ? b : c; } }; - struct lerp { template constexpr auto operator() (A a, B b, C c) const -> decltype(a*(1-c) + b*c) { return a*(1-c) + b*c; } }; - - // Function objects for applying operators - struct op_pos { template constexpr auto operator() (A a) const -> decltype(+a) { return +a; } }; - struct op_neg { template constexpr auto operator() (A a) const -> decltype(-a) { return -a; } }; - struct op_not { template constexpr auto operator() (A a) const -> decltype(!a) { return !a; } }; - struct op_cmp { template constexpr auto operator() (A a) const -> decltype(~(a)) { return ~a; } }; - struct op_mul { template constexpr auto operator() (A a, B b) const -> decltype(a * b) { return a * b; } }; - struct op_div { template constexpr auto operator() (A a, B b) const -> decltype(a / b) { return a / b; } }; - struct op_mod { template constexpr auto operator() (A a, B b) const -> decltype(a % b) { return a % b; } }; - struct op_add { template constexpr auto operator() (A a, B b) const -> decltype(a + b) { return a + b; } }; - struct op_sub { template constexpr auto operator() (A a, B b) const -> decltype(a - b) { return a - b; } }; - struct op_lsh { template constexpr auto operator() (A a, B b) const -> decltype(a << b) { return a << b; } }; - struct op_rsh { template constexpr auto operator() (A a, B b) const -> decltype(a >> b) { return a >> b; } }; - struct op_lt { template constexpr auto operator() (A a, B b) const -> decltype(a < b) { return a < b; } }; - struct op_gt { template constexpr auto operator() (A a, B b) const -> decltype(a > b) { return a > b; } }; - struct op_le { template constexpr auto operator() (A a, B b) const -> decltype(a <= b) { return a <= b; } }; - struct op_ge { template constexpr auto operator() (A a, B b) const -> decltype(a >= b) { return a >= b; } }; - struct op_eq { template constexpr auto operator() (A a, B b) const -> decltype(a == b) { return a == b; } }; - struct op_ne { template constexpr auto operator() (A a, B b) const -> decltype(a != b) { return a != b; } }; - struct op_int { template constexpr auto operator() (A a, B b) const -> decltype(a & b) { return a & b; } }; - struct op_xor { template constexpr auto operator() (A a, B b) const -> decltype(a ^ b) { return a ^ b; } }; - struct op_un { template constexpr auto operator() (A a, B b) const -> decltype(a | b) { return a | b; } }; - struct op_and { template constexpr auto operator() (A a, B b) const -> decltype(a && b) { return a && b; } }; - struct op_or { template constexpr auto operator() (A a, B b) const -> decltype(a || b) { return a || b; } }; - - // Function objects for applying standard library math functions - struct std_abs { template auto operator() (A a) const -> decltype(std::abs (a)) { return std::abs (a); } }; - struct std_floor { template auto operator() (A a) const -> decltype(std::floor(a)) { return std::floor(a); } }; - struct std_ceil { template auto operator() (A a) const -> decltype(std::ceil (a)) { return std::ceil (a); } }; - struct std_exp { template auto operator() (A a) const -> decltype(std::exp (a)) { return std::exp (a); } }; - struct std_log { template auto operator() (A a) const -> decltype(std::log (a)) { return std::log (a); } }; - struct std_log10 { template auto operator() (A a) const -> decltype(std::log10(a)) { return std::log10(a); } }; - struct std_sqrt { template auto operator() (A a) const -> decltype(std::sqrt (a)) { return std::sqrt (a); } }; - struct std_sin { template auto operator() (A a) const -> decltype(std::sin (a)) { return std::sin (a); } }; - struct std_cos { template auto operator() (A a) const -> decltype(std::cos (a)) { return std::cos (a); } }; - struct std_tan { template auto operator() (A a) const -> decltype(std::tan (a)) { return std::tan (a); } }; - struct std_asin { template auto operator() (A a) const -> decltype(std::asin (a)) { return std::asin (a); } }; - struct std_acos { template auto operator() (A a) const -> decltype(std::acos (a)) { return std::acos (a); } }; - struct std_atan { template auto operator() (A a) const -> decltype(std::atan (a)) { return std::atan (a); } }; - struct std_sinh { template auto operator() (A a) const -> decltype(std::sinh (a)) { return std::sinh (a); } }; - struct std_cosh { template auto operator() (A a) const -> decltype(std::cosh (a)) { return std::cosh (a); } }; - struct std_tanh { template auto operator() (A a) const -> decltype(std::tanh (a)) { return std::tanh (a); } }; - struct std_round { template auto operator() (A a) const -> decltype(std::round(a)) { return std::round(a); } }; - struct std_fmod { template auto operator() (A a, B b) const -> decltype(std::fmod (a, b)) { return std::fmod (a, b); } }; - struct std_pow { template auto operator() (A a, B b) const -> decltype(std::pow (a, b)) { return std::pow (a, b); } }; - struct std_atan2 { template auto operator() (A a, B b) const -> decltype(std::atan2 (a, b)) { return std::atan2 (a, b); } }; - struct std_copysign { template auto operator() (A a, B b) const -> decltype(std::copysign(a, b)) { return std::copysign(a, b); } }; - } - - // Small, fixed-length vector type, consisting of exactly M elements of type T, and presumed to be a column-vector unless otherwise noted - template struct vec - { - T x; - constexpr vec() : x() {} - constexpr vec(const T & x_) : x(x_) {} - // NOTE: vec does NOT have a constructor from pointer, this can conflict with initializing its single element from zero - template - constexpr explicit vec(const vec & v) : vec(static_cast(v.x)) {} - constexpr const T & operator[] (int i) const { return x; } - LINALG_CONSTEXPR14 T & operator[] (int i) { return x; } - - template> constexpr vec(const U & u) : vec(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct vec - { - T x,y; - constexpr vec() : x(), y() {} - constexpr vec(const T & x_, const T & y_) : x(x_), y(y_) {} - constexpr explicit vec(const T & s) : vec(s, s) {} - constexpr explicit vec(const T * p) : vec(p[0], p[1]) {} - template - constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y)) {} - constexpr const T & operator[] (int i) const { return i==0?x:y; } - LINALG_CONSTEXPR14 T & operator[] (int i) { return i==0?x:y; } - - template> constexpr vec(const U & u) : vec(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct vec - { - T x,y,z; - constexpr vec() : x(), y(), z() {} - constexpr vec(const T & x_, const T & y_, - const T & z_) : x(x_), y(y_), z(z_) {} - constexpr vec(const vec & xy, - const T & z_) : vec(xy.x, xy.y, z_) {} - constexpr explicit vec(const T & s) : vec(s, s, s) {} - constexpr explicit vec(const T * p) : vec(p[0], p[1], p[2]) {} - template - constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z)) {} - constexpr const T & operator[] (int i) const { return i==0?x:i==1?y:z; } - LINALG_CONSTEXPR14 T & operator[] (int i) { return i==0?x:i==1?y:z; } - constexpr const vec & xy() const { return *reinterpret_cast *>(this); } - vec & xy() { return *reinterpret_cast *>(this); } - - template> constexpr vec(const U & u) : vec(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct vec - { - T x,y,z,w; - constexpr vec() : x(), y(), z(), w() {} - constexpr vec(const T & x_, const T & y_, - const T & z_, const T & w_) : x(x_), y(y_), z(z_), w(w_) {} - constexpr vec(const vec & xy, - const T & z_, const T & w_) : vec(xy.x, xy.y, z_, w_) {} - constexpr vec(const vec & xyz, - const T & w_) : vec(xyz.x, xyz.y, xyz.z, w_) {} - constexpr explicit vec(const T & s) : vec(s, s, s, s) {} - constexpr explicit vec(const T * p) : vec(p[0], p[1], p[2], p[3]) {} - template - constexpr explicit vec(const vec & v) : vec(static_cast(v.x), static_cast(v.y), static_cast(v.z), static_cast(v.w)) {} - constexpr const T & operator[] (int i) const { return i==0?x:i==1?y:i==2?z:w; } - LINALG_CONSTEXPR14 T & operator[] (int i) { return i==0?x:i==1?y:i==2?z:w; } - constexpr const vec & xy() const { return *reinterpret_cast *>(this); } - constexpr const vec & xyz() const { return *reinterpret_cast *>(this); } - vec & xy() { return *reinterpret_cast *>(this); } - vec & xyz() { return *reinterpret_cast *>(this); } - - template> constexpr vec(const U & u) : vec(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - - // Small, fixed-size matrix type, consisting of exactly M rows and N columns of type T, stored in column-major order. - template struct mat - { - typedef vec V; - V x; - constexpr mat() : x() {} - constexpr mat(const V & x_) : x(x_) {} - constexpr explicit mat(const T & s) : x(s) {} - constexpr explicit mat(const T * p) : x(p+M*0) {} - template - constexpr explicit mat(const mat & m) : mat(V(m.x)) {} - constexpr vec row(int i) const { return {x[i]}; } - constexpr const V & operator[] (int j) const { return x; } - LINALG_CONSTEXPR14 V & operator[] (int j) { return x; } - - template> constexpr mat(const U & u) : mat(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct mat - { - typedef vec V; - V x,y; - constexpr mat() : x(), y() {} - constexpr mat(const V & x_, const V & y_) : x(x_), y(y_) {} - constexpr explicit mat(const T & s) : x(s), y(s) {} - constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1) {} - template - constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y)) {} - constexpr vec row(int i) const { return {x[i], y[i]}; } - constexpr const V & operator[] (int j) const { return j==0?x:y; } - LINALG_CONSTEXPR14 V & operator[] (int j) { return j==0?x:y; } - - template> constexpr mat(const U & u) : mat(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct mat - { - typedef vec V; - V x,y,z; - constexpr mat() : x(), y(), z() {} - constexpr mat(const V & x_, const V & y_, - const V & z_) : x(x_), y(y_), z(z_) {} - constexpr explicit mat(const T & s) : x(s), y(s), z(s) {} - constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1), z(p+M*2) {} - template - constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y), V(m.z)) {} - constexpr vec row(int i) const { return {x[i], y[i], z[i]}; } - constexpr const V & operator[] (int j) const { return j==0?x:j==1?y:z; } - LINALG_CONSTEXPR14 V & operator[] (int j) { return j==0?x:j==1?y:z; } - - template> constexpr mat(const U & u) : mat(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - template struct mat - { - typedef vec V; - V x,y,z,w; - constexpr mat() : x(), y(), z(), w() {} - constexpr mat(const V & x_, const V & y_, - const V & z_, const V & w_) : x(x_), y(y_), z(z_), w(w_) {} - constexpr explicit mat(const T & s) : x(s), y(s), z(s), w(s) {} - constexpr explicit mat(const T * p) : x(p+M*0), y(p+M*1), z(p+M*2), w(p+M*3) {} - template - constexpr explicit mat(const mat & m) : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {} - constexpr vec row(int i) const { return {x[i], y[i], z[i], w[i]}; } - constexpr const V & operator[] (int j) const { return j==0?x:j==1?y:j==2?z:w; } - LINALG_CONSTEXPR14 V & operator[] (int j) { return j==0?x:j==1?y:j==2?z:w; } - - template> constexpr mat(const U & u) : mat(converter{}(u)) {} - template> constexpr operator U () const { return converter{}(*this); } - }; - - // Define a type which will convert to the multiplicative identity of any square matrix - struct identity_t { constexpr explicit identity_t(int) {} }; - template struct converter, identity_t> { constexpr mat operator() (identity_t) const { return {vec{1}}; } }; - template struct converter, identity_t> { constexpr mat operator() (identity_t) const { return {{1,0},{0,1}}; } }; - template struct converter, identity_t> { constexpr mat operator() (identity_t) const { return {{1,0,0},{0,1,0},{0,0,1}}; } }; - template struct converter, identity_t> { constexpr mat operator() (identity_t) const { return {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}}; } }; - constexpr identity_t identity {1}; - - // Produce a scalar by applying f(A,B) -> A to adjacent pairs of elements from a vec/mat in left-to-right/column-major order (matching the associativity of arithmetic and logical operators) - template constexpr A fold(F f, A a, const vec & b) { return f(a, b.x); } - template constexpr A fold(F f, A a, const vec & b) { return f(f(a, b.x), b.y); } - template constexpr A fold(F f, A a, const vec & b) { return f(f(f(a, b.x), b.y), b.z); } - template constexpr A fold(F f, A a, const vec & b) { return f(f(f(f(a, b.x), b.y), b.z), b.w); } - template constexpr A fold(F f, A a, const mat & b) { return fold(f, a, b.x); } - template constexpr A fold(F f, A a, const mat & b) { return fold(f, fold(f, a, b.x), b.y); } - template constexpr A fold(F f, A a, const mat & b) { return fold(f, fold(f, fold(f, a, b.x), b.y), b.z); } - template constexpr A fold(F f, A a, const mat & b) { return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w); } - - // Type aliases for the result of calling apply(...) with various arguments, can be used with return type SFINAE to constrian overload sets - template using apply_t = typename detail::apply::type; - template using mm_apply_t = typename std::enable_if::mm, apply_t>::type; - template using no_mm_apply_t = typename std::enable_if::mm, apply_t>::type; - template using scalar_t = typename detail::scalar_type::type; // Underlying scalar type when performing elementwise operations - - // apply(f,...) applies the provided function in an elementwise fashion to its arguments, producing an object of the same dimensions - template constexpr apply_t apply(F func, const A & ... args) { return detail::apply::impl(detail::make_seq<0,detail::apply::size>{}, func, args...); } - - // map(a,f) is equivalent to apply(f,a) - template constexpr apply_t map(const A & a, F func) { return apply(func, a); } - - // zip(a,b,f) is equivalent to apply(f,a,b) - template constexpr apply_t zip(const A & a, const B & b, F func) { return apply(func, a, b); } - - // Relational operators are defined to compare the elements of two vectors or matrices lexicographically, in column-major order - template constexpr typename detail::any_compare::type compare(const A & a, const B & b) { return detail::any_compare()(a,b); } - template constexpr auto operator == (const A & a, const B & b) -> decltype(compare(a,b) == 0) { return compare(a,b) == 0; } - template constexpr auto operator != (const A & a, const B & b) -> decltype(compare(a,b) != 0) { return compare(a,b) != 0; } - template constexpr auto operator < (const A & a, const B & b) -> decltype(compare(a,b) < 0) { return compare(a,b) < 0; } - template constexpr auto operator > (const A & a, const B & b) -> decltype(compare(a,b) > 0) { return compare(a,b) > 0; } - template constexpr auto operator <= (const A & a, const B & b) -> decltype(compare(a,b) <= 0) { return compare(a,b) <= 0; } - template constexpr auto operator >= (const A & a, const B & b) -> decltype(compare(a,b) >= 0) { return compare(a,b) >= 0; } - - // Functions for coalescing scalar values - template constexpr bool any (const A & a) { return fold(detail::op_or{}, false, a); } - template constexpr bool all (const A & a) { return fold(detail::op_and{}, true, a); } - template constexpr scalar_t sum (const A & a) { return fold(detail::op_add{}, scalar_t(0), a); } - template constexpr scalar_t product(const A & a) { return fold(detail::op_mul{}, scalar_t(1), a); } - template constexpr scalar_t minelem(const A & a) { return fold(detail::min{}, a.x, a); } - template constexpr scalar_t maxelem(const A & a) { return fold(detail::max{}, a.x, a); } - template int argmin(const vec & a) { int j=0; for(int i=1; i int argmax(const vec & a) { int j=0; for(int i=1; i a[j]) j = i; return j; } - - // Unary operators are defined component-wise for linalg types - template constexpr apply_t operator + (const A & a) { return apply(detail::op_pos{}, a); } - template constexpr apply_t operator - (const A & a) { return apply(detail::op_neg{}, a); } - template constexpr apply_t operator ~ (const A & a) { return apply(detail::op_cmp{}, a); } - template constexpr apply_t operator ! (const A & a) { return apply(detail::op_not{}, a); } - - // Binary operators are defined component-wise for linalg types, EXCEPT for `operator *` - template constexpr apply_t operator + (const A & a, const B & b) { return apply(detail::op_add{}, a, b); } - template constexpr apply_t operator - (const A & a, const B & b) { return apply(detail::op_sub{}, a, b); } - template constexpr apply_t cmul (const A & a, const B & b) { return apply(detail::op_mul{}, a, b); } - template constexpr apply_t operator / (const A & a, const B & b) { return apply(detail::op_div{}, a, b); } - template constexpr apply_t operator % (const A & a, const B & b) { return apply(detail::op_mod{}, a, b); } - template constexpr apply_t operator | (const A & a, const B & b) { return apply(detail::op_un{}, a, b); } - template constexpr apply_t operator ^ (const A & a, const B & b) { return apply(detail::op_xor{}, a, b); } - template constexpr apply_t operator & (const A & a, const B & b) { return apply(detail::op_int{}, a, b); } - template constexpr apply_t operator << (const A & a, const B & b) { return apply(detail::op_lsh{}, a, b); } - template constexpr apply_t operator >> (const A & a, const B & b) { return apply(detail::op_rsh{}, a, b); } - - // Binary `operator *` was originally defined component-wise for all patterns, in a fashion consistent with the other operators. However, - // this was one of the most frequent sources of confusion among new users of this library, with the binary `operator *` being used accidentally - // by users who INTENDED the semantics of the algebraic matrix product, but RECEIVED the semantics of the Hadamard product. While there is - // precedent within the HLSL, Fortran, R, APL, J, and Mathematica programming languages for `operator *` having the semantics of the Hadamard - // product between matrices, it is counterintuitive to users of GLSL, Eigen, and many other languages and libraries that chose matrix product - // semantics for `operator *`. - // - // For these reasons, binary `operator *` is now DEPRECATED between pairs of matrices. Users may call `cmul(...)` for component-wise multiplication, - // or `mul(...)` for matrix multiplication. Binary `operator *` continues to be available for vector * vector, vector * scalar, matrix * scalar, etc. - template constexpr no_mm_apply_t operator * (const A & a, const B & b) { return cmul(a,b); } - #ifndef LINALG_FORWARD_COMPATIBLE - template [[deprecated("`operator *` between pairs of matrices is deprecated. See the source text for details.")]] constexpr mm_apply_t operator * (const A & a, const B & b) { return cmul(a,b); } - #endif - - // Binary assignment operators a $= b is always defined as though it were explicitly written a = a $ b - template constexpr auto operator += (A & a, const B & b) -> decltype(a = a + b) { return a = a + b; } - template constexpr auto operator -= (A & a, const B & b) -> decltype(a = a - b) { return a = a - b; } - template constexpr auto operator *= (A & a, const B & b) -> decltype(a = a * b) { return a = a * b; } - template constexpr auto operator /= (A & a, const B & b) -> decltype(a = a / b) { return a = a / b; } - template constexpr auto operator %= (A & a, const B & b) -> decltype(a = a % b) { return a = a % b; } - template constexpr auto operator |= (A & a, const B & b) -> decltype(a = a | b) { return a = a | b; } - template constexpr auto operator ^= (A & a, const B & b) -> decltype(a = a ^ b) { return a = a ^ b; } - template constexpr auto operator &= (A & a, const B & b) -> decltype(a = a & b) { return a = a & b; } - template constexpr auto operator <<= (A & a, const B & b) -> decltype(a = a << b) { return a = a << b; } - template constexpr auto operator >>= (A & a, const B & b) -> decltype(a = a >> b) { return a = a >> b; } - - // Swizzles and subobjects - template constexpr vec swizzle(const vec & a) { return {detail::getter{}(a)...}; } - template constexpr vec subvec (const vec & a) { return detail::swizzle(a, detail::make_seq{}); } - template constexpr mat submat (const mat & a) { return detail::swizzle(a, detail::make_seq{}, detail::make_seq{}); } - - // Component-wise standard library math functions - template apply_t abs (const A & a) { return apply(detail::std_abs{}, a); } - template apply_t floor(const A & a) { return apply(detail::std_floor{}, a); } - template apply_t ceil (const A & a) { return apply(detail::std_ceil{}, a); } - template apply_t exp (const A & a) { return apply(detail::std_exp{}, a); } - template apply_t log (const A & a) { return apply(detail::std_log{}, a); } - template apply_t log10(const A & a) { return apply(detail::std_log10{}, a); } - template apply_t sqrt (const A & a) { return apply(detail::std_sqrt{}, a); } - template apply_t sin (const A & a) { return apply(detail::std_sin{}, a); } - template apply_t cos (const A & a) { return apply(detail::std_cos{}, a); } - template apply_t tan (const A & a) { return apply(detail::std_tan{}, a); } - template apply_t asin (const A & a) { return apply(detail::std_asin{}, a); } - template apply_t acos (const A & a) { return apply(detail::std_acos{}, a); } - template apply_t atan (const A & a) { return apply(detail::std_atan{}, a); } - template apply_t sinh (const A & a) { return apply(detail::std_sinh{}, a); } - template apply_t cosh (const A & a) { return apply(detail::std_cosh{}, a); } - template apply_t tanh (const A & a) { return apply(detail::std_tanh{}, a); } - template apply_t round(const A & a) { return apply(detail::std_round{}, a); } - - template apply_t fmod (const A & a, const B & b) { return apply(detail::std_fmod{}, a, b); } - template apply_t pow (const A & a, const B & b) { return apply(detail::std_pow{}, a, b); } - template apply_t atan2 (const A & a, const B & b) { return apply(detail::std_atan2{}, a, b); } - template apply_t copysign(const A & a, const B & b) { return apply(detail::std_copysign{}, a, b); } - - // Component-wise relational functions on vectors - template constexpr apply_t equal (const A & a, const B & b) { return apply(detail::op_eq{}, a, b); } - template constexpr apply_t nequal (const A & a, const B & b) { return apply(detail::op_ne{}, a, b); } - template constexpr apply_t less (const A & a, const B & b) { return apply(detail::op_lt{}, a, b); } - template constexpr apply_t greater(const A & a, const B & b) { return apply(detail::op_gt{}, a, b); } - template constexpr apply_t lequal (const A & a, const B & b) { return apply(detail::op_le{}, a, b); } - template constexpr apply_t gequal (const A & a, const B & b) { return apply(detail::op_ge{}, a, b); } - - // Component-wise selection functions on vectors - template constexpr apply_t min(const A & a, const B & b) { return apply(detail::min{}, a, b); } - template constexpr apply_t max(const A & a, const B & b) { return apply(detail::max{}, a, b); } - template constexpr apply_t clamp (const X & x, const L & l, const H & h) { return apply(detail::clamp{}, x, l, h); } - template constexpr apply_t select(const P & p, const A & a, const B & b) { return apply(detail::select{}, p, a, b); } - template constexpr apply_t lerp (const A & a, const B & b, const T & t) { return apply(detail::lerp{}, a, b, t); } - - // Support for vector algebra - template constexpr T cross (const vec & a, const vec & b) { return a.x*b.y-a.y*b.x; } - template constexpr vec cross (T a, const vec & b) { return {-a*b.y, a*b.x}; } - template constexpr vec cross (const vec & a, T b) { return {a.y*b, -a.x*b}; } - template constexpr vec cross (const vec & a, const vec & b) { return {a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x}; } - template constexpr T dot (const vec & a, const vec & b) { return sum(a*b); } - template constexpr T length2 (const vec & a) { return dot(a,a); } - template T length (const vec & a) { return std::sqrt(length2(a)); } - template vec normalize(const vec & a) { return a / length(a); } - template constexpr T distance2(const vec & a, const vec & b) { return length2(b-a); } - template T distance (const vec & a, const vec & b) { return length(b-a); } - template T uangle (const vec & a, const vec & b) { T d=dot(a,b); return d > 1 ? 0 : std::acos(d < -1 ? -1 : d); } - template T angle (const vec & a, const vec & b) { return uangle(normalize(a), normalize(b)); } - template vec rot (T a, const vec & v) { const T s = std::sin(a), c = std::cos(a); return {v.x*c - v.y*s, v.x*s + v.y*c}; } - template vec nlerp (const vec & a, const vec & b, T t) { return normalize(lerp(a,b,t)); } - template vec slerp (const vec & a, const vec & b, T t) { T th=uangle(a,b); return th == 0 ? a : a*(std::sin(th*(1-t))/std::sin(th)) + b*(std::sin(th*t)/std::sin(th)); } - - // Support for quaternion algebra using 4D vectors, representing xi + yj + zk + w - template constexpr vec qconj(const vec & q) { return {-q.x,-q.y,-q.z,q.w}; } - template vec qinv (const vec & q) { return qconj(q)/length2(q); } - template vec qexp (const vec & q) { const auto v = q.xyz(); const auto vv = length(v); return std::exp(q.w) * vec{v * (vv > 0 ? std::sin(vv)/vv : 0), std::cos(vv)}; } - template vec qlog (const vec & q) { const auto v = q.xyz(); const auto vv = length(v), qq = length(q); return {v * (vv > 0 ? std::acos(q.w/qq)/vv : 0), std::log(qq)}; } - template vec qpow (const vec & q, const T & p) { const auto v = q.xyz(); const auto vv = length(v), qq = length(q), th = std::acos(q.w/qq); return std::pow(qq,p)*vec{v * (vv > 0 ? std::sin(p*th)/vv : 0), std::cos(p*th)}; } - template constexpr vec qmul (const vec & a, const vec & b) { return {a.x*b.w+a.w*b.x+a.y*b.z-a.z*b.y, a.y*b.w+a.w*b.y+a.z*b.x-a.x*b.z, a.z*b.w+a.w*b.z+a.x*b.y-a.y*b.x, a.w*b.w-a.x*b.x-a.y*b.y-a.z*b.z}; } - template constexpr vec qmul(const vec & a, R... r) { return qmul(a, qmul(r...)); } - - // Support for 3D spatial rotations using quaternions, via qmul(qmul(q, v), qconj(q)) - template constexpr vec qxdir (const vec & q) { return {q.w*q.w+q.x*q.x-q.y*q.y-q.z*q.z, (q.x*q.y+q.z*q.w)*2, (q.z*q.x-q.y*q.w)*2}; } - template constexpr vec qydir (const vec & q) { return {(q.x*q.y-q.z*q.w)*2, q.w*q.w-q.x*q.x+q.y*q.y-q.z*q.z, (q.y*q.z+q.x*q.w)*2}; } - template constexpr vec qzdir (const vec & q) { return {(q.z*q.x+q.y*q.w)*2, (q.y*q.z-q.x*q.w)*2, q.w*q.w-q.x*q.x-q.y*q.y+q.z*q.z}; } - template constexpr mat qmat (const vec & q) { return {qxdir(q), qydir(q), qzdir(q)}; } - template constexpr vec qrot (const vec & q, const vec & v) { return qxdir(q)*v.x + qydir(q)*v.y + qzdir(q)*v.z; } - template T qangle(const vec & q) { return std::atan2(length(q.xyz()), q.w)*2; } - template vec qaxis (const vec & q) { return normalize(q.xyz()); } - template vec qnlerp(const vec & a, const vec & b, T t) { return nlerp(a, dot(a,b) < 0 ? -b : b, t); } - template vec qslerp(const vec & a, const vec & b, T t) { return slerp(a, dot(a,b) < 0 ? -b : b, t); } - - // Support for matrix algebra - template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x; } - template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y; } - template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y + a.z*b.z; } - template constexpr vec mul(const mat & a, const vec & b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; } - template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x)}; } - template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y)}; } - template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y), mul(a,b.z)}; } - template constexpr mat mul(const mat & a, const mat & b) { return {mul(a,b.x), mul(a,b.y), mul(a,b.z), mul(a,b.w)}; } - template constexpr vec mul(const mat & a, const mat & b, const vec & c) { return mul(mul(a,b),c); } - template constexpr mat mul(const mat & a, const mat & b, const mat & c) { return mul(mul(a,b),c); } - template constexpr vec mul(const mat & a, const mat & b, const mat & c, const vec & d) { return mul(mul(a,b,c),d); } - template constexpr mat mul(const mat & a, const mat & b, const mat & c, const mat & d) { return mul(mul(a,b,c),d); } - template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x}; } - template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y}; } - template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y, a*b.z}; } - template constexpr mat outerprod(const vec & a, const vec & b) { return {a*b.x, a*b.y, a*b.z, a*b.w}; } - template constexpr vec diagonal(const mat & a) { return {a.x.x}; } - template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y}; } - template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y, a.z.z}; } - template constexpr vec diagonal(const mat & a) { return {a.x.x, a.y.y, a.z.z, a.w.w}; } - template constexpr T trace(const mat & a) { return sum(diagonal(a)); } - template constexpr mat transpose(const mat & m) { return {m.row(0)}; } - template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1)}; } - template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1), m.row(2)}; } - template constexpr mat transpose(const mat & m) { return {m.row(0), m.row(1), m.row(2), m.row(3)}; } - template constexpr mat transpose(const vec & m) { return transpose(mat(m)); } - template constexpr mat adjugate(const mat & a) { return {vec{1}}; } - template constexpr mat adjugate(const mat & a) { return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}}; } - template constexpr mat adjugate(const mat & a); - template constexpr mat adjugate(const mat & a); - template constexpr mat comatrix(const mat & a) { return transpose(adjugate(a)); } - template constexpr T determinant(const mat & a) { return a.x.x; } - template constexpr T determinant(const mat & a) { return a.x.x*a.y.y - a.x.y*a.y.x; } - template constexpr T determinant(const mat & a) { return a.x.x*(a.y.y*a.z.z - a.z.y*a.y.z) + a.x.y*(a.y.z*a.z.x - a.z.z*a.y.x) + a.x.z*(a.y.x*a.z.y - a.z.x*a.y.y); } - template constexpr T determinant(const mat & a); - template constexpr mat inverse(const mat & a) { return adjugate(a)/determinant(a); } - - // Vectors and matrices can be used as ranges - template T * begin( vec & a) { return &a.x; } - template const T * begin(const vec & a) { return &a.x; } - template T * end ( vec & a) { return begin(a) + M; } - template const T * end (const vec & a) { return begin(a) + M; } - template vec * begin( mat & a) { return &a.x; } - template const vec * begin(const mat & a) { return &a.x; } - template vec * end ( mat & a) { return begin(a) + N; } - template const vec * end (const mat & a) { return begin(a) + N; } - - // Factory functions for 3D spatial transformations (will possibly be removed or changed in a future version) - enum fwd_axis { neg_z, pos_z }; // Should projection matrices be generated assuming forward is {0,0,-1} or {0,0,1} - enum z_range { neg_one_to_one, zero_to_one }; // Should projection matrices map z into the range of [-1,1] or [0,1]? - template vec rotation_quat (const vec & axis, T angle) { return {axis*std::sin(angle/2), std::cos(angle/2)}; } - template vec rotation_quat (const mat & m); - template mat translation_matrix(const vec & translation) { return {{1,0,0,0},{0,1,0,0},{0,0,1,0},{translation,1}}; } - template mat rotation_matrix (const vec & rotation) { return {{qxdir(rotation),0}, {qydir(rotation),0}, {qzdir(rotation),0}, {0,0,0,1}}; } - template mat scaling_matrix (const vec & scaling) { return {{scaling.x,0,0,0}, {0,scaling.y,0,0}, {0,0,scaling.z,0}, {0,0,0,1}}; } - template mat pose_matrix (const vec & q, const vec & p) { return {{qxdir(q),0}, {qydir(q),0}, {qzdir(q),0}, {p,1}}; } - template mat lookat_matrix (const vec & eye, const vec & center, const vec & view_y_dir, fwd_axis fwd = neg_z); - template mat frustum_matrix (T x0, T x1, T y0, T y1, T n, T f, fwd_axis a = neg_z, z_range z = neg_one_to_one); - template mat perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z, z_range z = neg_one_to_one) { T y = n*std::tan(fovy / 2), x = y*aspect; return frustum_matrix(-x, x, -y, y, n, f, a, z); } - - // Provide implicit conversion between linalg::vec and std::array - template struct converter, std::array> { vec operator() (const std::array & a) const { return {a[0]}; } }; - template struct converter, std::array> { vec operator() (const std::array & a) const { return {a[0], a[1]}; } }; - template struct converter, std::array> { vec operator() (const std::array & a) const { return {a[0], a[1], a[2]}; } }; - template struct converter, std::array> { vec operator() (const std::array & a) const { return {a[0], a[1], a[2], a[3]}; } }; - - template struct converter, vec> { std::array operator() (const vec & a) const { return {a[0]}; } }; - template struct converter, vec> { std::array operator() (const vec & a) const { return {a[0], a[1]}; } }; - template struct converter, vec> { std::array operator() (const vec & a) const { return {a[0], a[1], a[2]}; } }; - template struct converter, vec> { std::array operator() (const vec & a) const { return {a[0], a[1], a[2], a[3]}; } }; - - // Provide typedefs for common element types and vector/matrix sizes - namespace aliases - { - typedef vec bool1; typedef vec byte1; typedef vec short1; typedef vec ushort1; - typedef vec bool2; typedef vec byte2; typedef vec short2; typedef vec ushort2; - typedef vec bool3; typedef vec byte3; typedef vec short3; typedef vec ushort3; - typedef vec bool4; typedef vec byte4; typedef vec short4; typedef vec ushort4; - typedef vec int1; typedef vec uint1; typedef vec float1; typedef vec double1; - typedef vec int2; typedef vec uint2; typedef vec float2; typedef vec double2; - typedef vec int3; typedef vec uint3; typedef vec float3; typedef vec double3; - typedef vec int4; typedef vec uint4; typedef vec float4; typedef vec double4; - typedef mat bool1x1; typedef mat int1x1; typedef mat float1x1; typedef mat double1x1; - typedef mat bool1x2; typedef mat int1x2; typedef mat float1x2; typedef mat double1x2; - typedef mat bool1x3; typedef mat int1x3; typedef mat float1x3; typedef mat double1x3; - typedef mat bool1x4; typedef mat int1x4; typedef mat float1x4; typedef mat double1x4; - typedef mat bool2x1; typedef mat int2x1; typedef mat float2x1; typedef mat double2x1; - typedef mat bool2x2; typedef mat int2x2; typedef mat float2x2; typedef mat double2x2; - typedef mat bool2x3; typedef mat int2x3; typedef mat float2x3; typedef mat double2x3; - typedef mat bool2x4; typedef mat int2x4; typedef mat float2x4; typedef mat double2x4; - typedef mat bool3x1; typedef mat int3x1; typedef mat float3x1; typedef mat double3x1; - typedef mat bool3x2; typedef mat int3x2; typedef mat float3x2; typedef mat double3x2; - typedef mat bool3x3; typedef mat int3x3; typedef mat float3x3; typedef mat double3x3; - typedef mat bool3x4; typedef mat int3x4; typedef mat float3x4; typedef mat double3x4; - typedef mat bool4x1; typedef mat int4x1; typedef mat float4x1; typedef mat double4x1; - typedef mat bool4x2; typedef mat int4x2; typedef mat float4x2; typedef mat double4x2; - typedef mat bool4x3; typedef mat int4x3; typedef mat float4x3; typedef mat double4x3; - typedef mat bool4x4; typedef mat int4x4; typedef mat float4x4; typedef mat double4x4; - } - - // Provide output streaming operators, writing something that resembles an aggregate literal that could be used to construct the specified value - namespace ostream_overloads - { - template std::basic_ostream & operator << (std::basic_ostream & out, const vec & v) { return out << '{' << v[0] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const vec & v) { return out << '{' << v[0] << ',' << v[1] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const vec & v) { return out << '{' << v[0] << ',' << v[1] << ',' << v[2] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const vec & v) { return out << '{' << v[0] << ',' << v[1] << ',' << v[2] << ',' << v[3] << '}'; } - - template std::basic_ostream & operator << (std::basic_ostream & out, const mat & m) { return out << '{' << m[0] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const mat & m) { return out << '{' << m[0] << ',' << m[1] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const mat & m) { return out << '{' << m[0] << ',' << m[1] << ',' << m[2] << '}'; } - template std::basic_ostream & operator << (std::basic_ostream & out, const mat & m) { return out << '{' << m[0] << ',' << m[1] << ',' << m[2] << ',' << m[3] << '}'; } - } -} - -namespace std -{ - // Provide specializations for std::hash<...> with linalg types - template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x); } }; - template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1); } }; - template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2); } }; - template struct hash> { std::size_t operator()(const linalg::vec & v) const { std::hash h; return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3); } }; - - template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x); } }; - template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M); } }; - template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M*2)); } }; - template struct hash> { std::size_t operator()(const linalg::mat & v) const { std::hash> h; return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M*2)) ^ (h(v.w) << (M*3)); } }; -} - -// Definitions of functions too long to be defined inline -template constexpr linalg::mat linalg::adjugate(const mat & a) -{ - return {{a.y.y*a.z.z - a.z.y*a.y.z, a.z.y*a.x.z - a.x.y*a.z.z, a.x.y*a.y.z - a.y.y*a.x.z}, - {a.y.z*a.z.x - a.z.z*a.y.x, a.z.z*a.x.x - a.x.z*a.z.x, a.x.z*a.y.x - a.y.z*a.x.x}, - {a.y.x*a.z.y - a.z.x*a.y.y, a.z.x*a.x.y - a.x.x*a.z.y, a.x.x*a.y.y - a.y.x*a.x.y}}; -} - -template constexpr linalg::mat linalg::adjugate(const mat & a) -{ - return {{a.y.y*a.z.z*a.w.w + a.w.y*a.y.z*a.z.w + a.z.y*a.w.z*a.y.w - a.y.y*a.w.z*a.z.w - a.z.y*a.y.z*a.w.w - a.w.y*a.z.z*a.y.w, - a.x.y*a.w.z*a.z.w + a.z.y*a.x.z*a.w.w + a.w.y*a.z.z*a.x.w - a.w.y*a.x.z*a.z.w - a.z.y*a.w.z*a.x.w - a.x.y*a.z.z*a.w.w, - a.x.y*a.y.z*a.w.w + a.w.y*a.x.z*a.y.w + a.y.y*a.w.z*a.x.w - a.x.y*a.w.z*a.y.w - a.y.y*a.x.z*a.w.w - a.w.y*a.y.z*a.x.w, - a.x.y*a.z.z*a.y.w + a.y.y*a.x.z*a.z.w + a.z.y*a.y.z*a.x.w - a.x.y*a.y.z*a.z.w - a.z.y*a.x.z*a.y.w - a.y.y*a.z.z*a.x.w}, - {a.y.z*a.w.w*a.z.x + a.z.z*a.y.w*a.w.x + a.w.z*a.z.w*a.y.x - a.y.z*a.z.w*a.w.x - a.w.z*a.y.w*a.z.x - a.z.z*a.w.w*a.y.x, - a.x.z*a.z.w*a.w.x + a.w.z*a.x.w*a.z.x + a.z.z*a.w.w*a.x.x - a.x.z*a.w.w*a.z.x - a.z.z*a.x.w*a.w.x - a.w.z*a.z.w*a.x.x, - a.x.z*a.w.w*a.y.x + a.y.z*a.x.w*a.w.x + a.w.z*a.y.w*a.x.x - a.x.z*a.y.w*a.w.x - a.w.z*a.x.w*a.y.x - a.y.z*a.w.w*a.x.x, - a.x.z*a.y.w*a.z.x + a.z.z*a.x.w*a.y.x + a.y.z*a.z.w*a.x.x - a.x.z*a.z.w*a.y.x - a.y.z*a.x.w*a.z.x - a.z.z*a.y.w*a.x.x}, - {a.y.w*a.z.x*a.w.y + a.w.w*a.y.x*a.z.y + a.z.w*a.w.x*a.y.y - a.y.w*a.w.x*a.z.y - a.z.w*a.y.x*a.w.y - a.w.w*a.z.x*a.y.y, - a.x.w*a.w.x*a.z.y + a.z.w*a.x.x*a.w.y + a.w.w*a.z.x*a.x.y - a.x.w*a.z.x*a.w.y - a.w.w*a.x.x*a.z.y - a.z.w*a.w.x*a.x.y, - a.x.w*a.y.x*a.w.y + a.w.w*a.x.x*a.y.y + a.y.w*a.w.x*a.x.y - a.x.w*a.w.x*a.y.y - a.y.w*a.x.x*a.w.y - a.w.w*a.y.x*a.x.y, - a.x.w*a.z.x*a.y.y + a.y.w*a.x.x*a.z.y + a.z.w*a.y.x*a.x.y - a.x.w*a.y.x*a.z.y - a.z.w*a.x.x*a.y.y - a.y.w*a.z.x*a.x.y}, - {a.y.x*a.w.y*a.z.z + a.z.x*a.y.y*a.w.z + a.w.x*a.z.y*a.y.z - a.y.x*a.z.y*a.w.z - a.w.x*a.y.y*a.z.z - a.z.x*a.w.y*a.y.z, - a.x.x*a.z.y*a.w.z + a.w.x*a.x.y*a.z.z + a.z.x*a.w.y*a.x.z - a.x.x*a.w.y*a.z.z - a.z.x*a.x.y*a.w.z - a.w.x*a.z.y*a.x.z, - a.x.x*a.w.y*a.y.z + a.y.x*a.x.y*a.w.z + a.w.x*a.y.y*a.x.z - a.x.x*a.y.y*a.w.z - a.w.x*a.x.y*a.y.z - a.y.x*a.w.y*a.x.z, - a.x.x*a.y.y*a.z.z + a.z.x*a.x.y*a.y.z + a.y.x*a.z.y*a.x.z - a.x.x*a.z.y*a.y.z - a.y.x*a.x.y*a.z.z - a.z.x*a.y.y*a.x.z}}; -} - -template constexpr T linalg::determinant(const mat & a) -{ - return a.x.x*(a.y.y*a.z.z*a.w.w + a.w.y*a.y.z*a.z.w + a.z.y*a.w.z*a.y.w - a.y.y*a.w.z*a.z.w - a.z.y*a.y.z*a.w.w - a.w.y*a.z.z*a.y.w) - + a.x.y*(a.y.z*a.w.w*a.z.x + a.z.z*a.y.w*a.w.x + a.w.z*a.z.w*a.y.x - a.y.z*a.z.w*a.w.x - a.w.z*a.y.w*a.z.x - a.z.z*a.w.w*a.y.x) - + a.x.z*(a.y.w*a.z.x*a.w.y + a.w.w*a.y.x*a.z.y + a.z.w*a.w.x*a.y.y - a.y.w*a.w.x*a.z.y - a.z.w*a.y.x*a.w.y - a.w.w*a.z.x*a.y.y) - + a.x.w*(a.y.x*a.w.y*a.z.z + a.z.x*a.y.y*a.w.z + a.w.x*a.z.y*a.y.z - a.y.x*a.z.y*a.w.z - a.w.x*a.y.y*a.z.z - a.z.x*a.w.y*a.y.z); -} - -template linalg::vec linalg::rotation_quat(const mat & m) -{ - const vec q {m.x.x-m.y.y-m.z.z, m.y.y-m.x.x-m.z.z, m.z.z-m.x.x-m.y.y, m.x.x+m.y.y+m.z.z}, s[] { - {1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y}, - {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z}, - {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x}, - {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}}; - return copysign(normalize(sqrt(max(T(0), T(1)+q))), s[argmax(q)]); -} - -template linalg::mat linalg::lookat_matrix(const vec & eye, const vec & center, const vec & view_y_dir, fwd_axis a) -{ - const vec f = normalize(center - eye), z = a == pos_z ? f : -f, x = normalize(cross(view_y_dir, z)), y = cross(z, x); - return inverse(mat{{x,0},{y,0},{z,0},{eye,1}}); -} - -template linalg::mat linalg::frustum_matrix(T x0, T x1, T y0, T y1, T n, T f, fwd_axis a, z_range z) -{ - const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0; - return {{2*n/(x1-x0),0,0,0}, {0,2*n/(y1-y0),0,0}, {-s*(x0+x1)/(x1-x0),-s*(y0+y1)/(y1-y0),s*(f+o)/(f-n),s}, {0,0,-(n+o)*f/(f-n),0}}; -} - -#endif diff --git a/src/spice2x/games/drs/drs.h b/src/spice2x/games/drs/drs.h index e8303cb..ec2f202 100644 --- a/src/spice2x/games/drs/drs.h +++ b/src/spice2x/games/drs/drs.h @@ -1,7 +1,6 @@ #pragma once #include "games/game.h" -#include "external/linalg.h" #include "touch/touch.h" namespace games::drs { diff --git a/src/spice2x/licenses.txt b/src/spice2x/licenses.txt index 40008fa..d739e29 100644 --- a/src/spice2x/licenses.txt +++ b/src/spice2x/licenses.txt @@ -318,10 +318,6 @@ stb_image_write (Public Domain) ------------------------------------------- http://nothings.org/stb/stb_image_write.h -linalg.h (Public Domain, Unlicense) -------------------------------------------- -https://github.com/sgorsten/linalg - fmt (2-clause BSD) ------------------------------------------- Copyright (c) 2012 - 2016, Victor Zverovich