//---------------------------------------------------------------------------// // ," /\ ", Azur: A game engine for CASIO fx-CG and PC // // | _/__\_ | Designed by Lephe' and the Planète Casio community. // // "._`\/'_." License: MIT // //---------------------------------------------------------------------------// // num.vec: Vector arithmetic // // This header provides basic vector arithmetic. It is type-generic and works // on any numerical type, including integers, floating-point types, and this // library's fixed-point types. Not all operations are available for all types // however. // // We slightly abuse the underlying object representation by expecting the // vector type vec to be isomorphic to T[N] so we can perform accesses to // members with a pointer cast and array access. This access doesn't break // strict aliasing rules since the members' type is correct. //--- #pragma once #include namespace libnum { template requires(N > 0) struct vec { T coords[N]; inline constexpr int size() const { return N; } inline constexpr T &operator[](int i) { return ((T *)this)[i]; } inline constexpr T const &operator[](int i) const { return ((T *)this)[i]; } }; template struct vec { T x, y; vec(): x {0}, y {0} {} vec(T _x, T _y): x {_x}, y {_y} {} inline constexpr int size() const { return 2; } inline constexpr T &operator[](int i) { return ((T *)this)[i]; } inline constexpr T const &operator[](int i) const { return ((T *)this)[i]; } }; using vec2 = vec; template struct vec { T x, y, z; vec(): x {0}, y {0}, z {0} {} vec(T _x, T _y, T _z): x {_x}, y {_y}, z {_z} {} vec(T scalar): x {scalar}, y {scalar}, z {scalar} {} vec(vec v): x {v.x}, y {v.y}, z {0} {} vec(vec v, T _z): x {v.x}, y {v.y}, z {_z} {} inline constexpr int size() const { return 3; } inline constexpr T &operator[](int i) { return ((T *)this)[i]; } inline constexpr T const &operator[](int i) const { return ((T *)this)[i]; } inline constexpr vec xy() const { return vec(x, y); } inline constexpr vec xz() const { return vec(x, z); } inline constexpr vec yz() const { return vec(y, z); } }; using vec3 = vec; template struct vec { T x, y, z, w; vec(): x {0}, y {0}, z {0} {} vec(T _x, T _y, T _z, T _w): x {_x}, y {_y}, z {_z}, w {_w} {} vec(T scalar): x {scalar}, y {scalar}, z {scalar}, w {scalar} {} vec(vec v): x {v.x}, y {v.y}, z {0}, w {0} {} vec(vec v, T _z, T _w): x {v.x}, y {v.y}, z {_z}, w {_w} {} vec(vec v): x {v.x}, y {v.y}, z {v.z}, w {0} {} vec(vec v, T _w): x {v.x}, y {v.y}, z {v.z}, w {_w} {} inline constexpr int size() const { return 4; } inline constexpr T &operator[](int i) { return ((T *)this)[i]; } inline constexpr T const &operator[](int i) const { return ((T *)this)[i]; } inline constexpr vec xyz() const { return vec(x, y, z); } }; using vec4 = vec; /* The following concept identifies vec types */ template struct is_vec_trait: std::false_type {}; template struct is_vec_trait>: std::true_type {}; template concept is_vec = is_vec_trait::value; /* Arithmetic */ template inline constexpr vec &operator+=(vec &lhs, vec const &rhs) { for(int i = 0; i < N; i++) lhs[i] += rhs[i]; return lhs; } template inline constexpr vec &operator-=(vec &lhs, vec const &rhs) { for(int i = 0; i < N; i++) lhs[i] -= rhs[i]; return lhs; } template inline constexpr vec &operator*=(vec &lhs, T const &rhs) { for(int i = 0; i < N; i++) lhs[i] *= rhs; return lhs; } template inline constexpr vec &operator*=(vec &lhs, vec const &rhs) { T r = T(0); for(int i = 0; i < N; i++) r += lhs[i] * rhs[i]; return r; } template inline constexpr vec &operator/=(vec &lhs, T const &rhs) { for(int i = 0; i < N; i++) lhs[i] /= rhs; return lhs; } template inline constexpr vec operator+(vec const &lhs) { return lhs; } template inline constexpr vec operator-(vec lhs) { for(int i = 0; i < N; i++) lhs[i] = -lhs[i]; return lhs; } template inline constexpr vec operator+(vec lhs, vec const &rhs) { return lhs += rhs; } template inline constexpr vec operator-(vec lhs, vec const &rhs) { return lhs -= rhs; } template inline constexpr vec operator*(vec lhs, T const &rhs) { return lhs *= rhs; } template inline constexpr vec operator*(T const &lhs, vec rhs) { for(int i = 0; i < N; i++) rhs[i] *= lhs; return rhs; } /* Comparisons */ template inline constexpr bool operator==(vec const &lhs, vec const &rhs) { for(int i = 0; i < N; i++) { if(lhs[i] != rhs[i]) return false; } return true; } template inline constexpr bool operator!=(vec const &lhs, vec const &rhs) { for(int i = 0; i < N; i++) { if(lhs[i] != rhs[i]) return true; } return false; } } /* namespace libnum */