@@ -16,10 +16,7 @@ | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
/* There are many reasons for wanting single-word type names, the most | |||||
* important one being compilation speedups in our vector.h: we can hide | |||||
* some global methods in namespaces that contain the name of the type, | |||||
* but namespaces cannot have spaces in their names. */ | |||||
/* It’s nice to have single-word type names, so define this. */ | |||||
typedef long double ldouble; | typedef long double ldouble; | ||||
/* The “real” type used for real numbers. It’s a specialisation of the | /* The “real” type used for real numbers. It’s a specialisation of the | ||||
@@ -31,22 +28,23 @@ typedef Real<16> real; | |||||
class half; | class half; | ||||
/* | /* | ||||
* Forward declaration of vec and matrix | |||||
* Forward declaration of vec_t, mat_t, cmplx_t, quat_t | |||||
*/ | */ | ||||
int const FULL_SWIZZLE = 0xaaaa; | int const FULL_SWIZZLE = 0xaaaa; | ||||
int const NO_SWIZZLE = 0xbbbb; | int const NO_SWIZZLE = 0xbbbb; | ||||
template<int N, typename T, int SWIZZLE = FULL_SWIZZLE> struct vec; | |||||
template<int COLS, int ROWS, typename T> struct mat; | |||||
template<typename T> struct Cmplx; | |||||
template<typename T> struct Quat; | |||||
template<typename T, int N, int SWIZZLE = FULL_SWIZZLE> struct vec_t; | |||||
template<typename T, int COLS, int ROWS> struct mat_t; | |||||
template<typename T> struct cmplx_t; | |||||
template<typename T> struct quat_t; | |||||
template<typename T> struct dualquat_t; | |||||
/* | /* | ||||
* Generic GLSL-like type names | * Generic GLSL-like type names | ||||
*/ | */ | ||||
#define LOL_VECTOR_TYPEDEFS(tleft, tright, suffix) \ | |||||
#define _T(tleft, tright, suffix) \ | |||||
typedef tleft half tright f16##suffix; \ | typedef tleft half tright f16##suffix; \ | ||||
typedef tleft float tright suffix; \ | typedef tleft float tright suffix; \ | ||||
typedef tleft double tright d##suffix; \ | typedef tleft double tright d##suffix; \ | ||||
@@ -62,28 +60,29 @@ template<typename T> struct Quat; | |||||
typedef tleft real tright r##suffix; | typedef tleft real tright r##suffix; | ||||
/* Idiotic hack to put "," inside a macro argument */ | /* Idiotic hack to put "," inside a macro argument */ | ||||
#define COMMA , | |||||
#define _C , | |||||
LOL_VECTOR_TYPEDEFS(vec<2 COMMA, >, vec2) | |||||
LOL_VECTOR_TYPEDEFS(vec<3 COMMA, >, vec3) | |||||
LOL_VECTOR_TYPEDEFS(vec<4 COMMA, >, vec4) | |||||
_T(vec_t<, _C 2>, vec2) | |||||
_T(vec_t<, _C 3>, vec3) | |||||
_T(vec_t<, _C 4>, vec4) | |||||
LOL_VECTOR_TYPEDEFS(mat<2 COMMA 2 COMMA, >, mat2) | |||||
LOL_VECTOR_TYPEDEFS(mat<3 COMMA 3 COMMA, >, mat3) | |||||
LOL_VECTOR_TYPEDEFS(mat<4 COMMA 4 COMMA, >, mat4) | |||||
_T(mat_t<, _C 2 _C 2>, mat2) | |||||
_T(mat_t<, _C 3 _C 3>, mat3) | |||||
_T(mat_t<, _C 4 _C 4>, mat4) | |||||
LOL_VECTOR_TYPEDEFS(mat<2 COMMA 3 COMMA, >, mat2x3) | |||||
LOL_VECTOR_TYPEDEFS(mat<2 COMMA 4 COMMA, >, mat2x4) | |||||
LOL_VECTOR_TYPEDEFS(mat<3 COMMA 2 COMMA, >, mat3x2) | |||||
LOL_VECTOR_TYPEDEFS(mat<3 COMMA 4 COMMA, >, mat3x4) | |||||
LOL_VECTOR_TYPEDEFS(mat<4 COMMA 2 COMMA, >, mat4x2) | |||||
LOL_VECTOR_TYPEDEFS(mat<4 COMMA 3 COMMA, >, mat4x3) | |||||
_T(mat_t<, _C 2 _C 3>, mat2x3) | |||||
_T(mat_t<, _C 2 _C 4>, mat2x4) | |||||
_T(mat_t<, _C 3 _C 2>, mat3x2) | |||||
_T(mat_t<, _C 3 _C 4>, mat3x4) | |||||
_T(mat_t<, _C 4 _C 2>, mat4x2) | |||||
_T(mat_t<, _C 4 _C 3>, mat4x3) | |||||
LOL_VECTOR_TYPEDEFS(Cmplx<, >, cmplx) | |||||
LOL_VECTOR_TYPEDEFS(Quat<, >, quat) | |||||
_T(cmplx_t<, >, cmplx) | |||||
_T(quat_t<, >, quat) | |||||
_T(dualquat_t<, >, dualquat) | |||||
#undef COMMA | |||||
#undef LOL_VECTOR_TYPEDEFS | |||||
#undef _C | |||||
#undef _T | |||||
/* | /* | ||||
* HLSL/Cg-compliant type names | * HLSL/Cg-compliant type names | ||||
@@ -49,7 +49,7 @@ template <typename T> struct Box2 | |||||
B(T(0)) | B(T(0)) | ||||
{} | {} | ||||
inline Box2(vec<2,T> const &a, vec<2,T> const &b) | |||||
inline Box2(vec_t<T,2> const &a, vec_t<T,2> const &b) | |||||
: A(a), | : A(a), | ||||
B(b) | B(b) | ||||
{} | {} | ||||
@@ -59,32 +59,32 @@ template <typename T> struct Box2 | |||||
B(bx, by) | B(bx, by) | ||||
{} | {} | ||||
Box2<T> operator +(vec<2,T> const &v) const | |||||
Box2<T> operator +(vec_t<T,2> const &v) const | |||||
{ | { | ||||
return Box2<T>(A + v, B + v); | return Box2<T>(A + v, B + v); | ||||
} | } | ||||
Box2<T> &operator +=(vec<2,T> const &v) | |||||
Box2<T> &operator +=(vec_t<T,2> const &v) | |||||
{ | { | ||||
return *this = *this + v; | return *this = *this + v; | ||||
} | } | ||||
Box2<T> operator -(vec<2,T> const &v) const | |||||
Box2<T> operator -(vec_t<T,2> const &v) const | |||||
{ | { | ||||
return Box2<T>(A - v, B - v); | return Box2<T>(A - v, B - v); | ||||
} | } | ||||
Box2<T> &operator -=(vec<2,T> const &v) | |||||
Box2<T> &operator -=(vec_t<T,2> const &v) | |||||
{ | { | ||||
return *this = *this - v; | return *this = *this - v; | ||||
} | } | ||||
Box2<T> operator *(vec<2,T> const &v) const | |||||
Box2<T> operator *(vec_t<T,2> const &v) const | |||||
{ | { | ||||
return Box2<T>(A * v, B * v); | return Box2<T>(A * v, B * v); | ||||
} | } | ||||
Box2<T> &operator *=(vec<2,T> const &v) | |||||
Box2<T> &operator *=(vec_t<T,2> const &v) | |||||
{ | { | ||||
return *this = *this * v; | return *this = *this * v; | ||||
} | } | ||||
@@ -99,7 +99,7 @@ template <typename T> struct Box2 | |||||
return A != box.A || B != box.B; | return A != box.A || B != box.B; | ||||
} | } | ||||
vec<2,T> A, B; | |||||
vec_t<T,2> A, B; | |||||
}; | }; | ||||
/* | /* | ||||
@@ -113,7 +113,7 @@ template <typename T> struct Box3 | |||||
B(T(0)) | B(T(0)) | ||||
{} | {} | ||||
inline Box3(vec<3,T> const &a, vec<3,T> const &b) | |||||
inline Box3(vec_t<T,3> const &a, vec_t<T,3> const &b) | |||||
: A(a), | : A(a), | ||||
B(b) | B(b) | ||||
{} | {} | ||||
@@ -124,32 +124,32 @@ template <typename T> struct Box3 | |||||
B(bx, by, bz) | B(bx, by, bz) | ||||
{} | {} | ||||
Box3<T> operator +(vec<3,T> const &v) const | |||||
Box3<T> operator +(vec_t<T,3> const &v) const | |||||
{ | { | ||||
return Box3<T>(A + v, B + v); | return Box3<T>(A + v, B + v); | ||||
} | } | ||||
Box3<T> &operator +=(vec<3,T> const &v) | |||||
Box3<T> &operator +=(vec_t<T,3> const &v) | |||||
{ | { | ||||
return *this = *this + v; | return *this = *this + v; | ||||
} | } | ||||
Box3<T> operator -(vec<3,T> const &v) const | |||||
Box3<T> operator -(vec_t<T,3> const &v) const | |||||
{ | { | ||||
return Box3<T>(A - v, B - v); | return Box3<T>(A - v, B - v); | ||||
} | } | ||||
Box3<T> &operator -=(vec<3,T> const &v) | |||||
Box3<T> &operator -=(vec_t<T,3> const &v) | |||||
{ | { | ||||
return *this = *this - v; | return *this = *this - v; | ||||
} | } | ||||
Box3<T> operator *(vec<3,T> const &v) const | |||||
Box3<T> operator *(vec_t<T,3> const &v) const | |||||
{ | { | ||||
return Box3<T>(A * v, B * v); | return Box3<T>(A * v, B * v); | ||||
} | } | ||||
Box3<T> &operator *=(vec<3,T> const &v) | |||||
Box3<T> &operator *=(vec_t<T,3> const &v) | |||||
{ | { | ||||
return *this = *this * v; | return *this = *this * v; | ||||
} | } | ||||
@@ -164,7 +164,7 @@ template <typename T> struct Box3 | |||||
return A != box.A || B != box.B; | return A != box.A || B != box.B; | ||||
} | } | ||||
vec<3,T> A, B; | |||||
vec_t<T,3> A, B; | |||||
}; | }; | ||||
/* | /* | ||||
@@ -29,17 +29,17 @@ namespace lol | |||||
#endif | #endif | ||||
/* | /* | ||||
* The generic "matrix" type, which is fixed-size | |||||
* The generic “mat_t” type, which is fixed-size | |||||
*/ | */ | ||||
template<int COLS, int ROWS, typename T> | |||||
struct mat | |||||
template<typename T, int COLS, int ROWS> | |||||
struct mat_t | |||||
{ | { | ||||
typedef mat<COLS,ROWS,T> type; | |||||
typedef mat_t<T,COLS,ROWS> type; | |||||
inline mat() {} | |||||
inline mat_t() {} | |||||
explicit inline mat(T const &val) | |||||
explicit inline mat_t(T const &val) | |||||
{ | { | ||||
T const zero = T(0); | T const zero = T(0); | ||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
@@ -47,11 +47,11 @@ struct mat | |||||
m_data[i][j] = i == j ? val : zero; | m_data[i][j] = i == j ? val : zero; | ||||
} | } | ||||
inline vec<ROWS,T>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec<ROWS,T> const& operator[](size_t n) const { return m_data[n]; } | |||||
inline vec_t<T,ROWS>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec_t<T,ROWS> const& operator[](size_t n) const { return m_data[n]; } | |||||
private: | private: | ||||
vec<ROWS,T> m_data[COLS]; | |||||
vec_t<T,ROWS> m_data[COLS]; | |||||
}; | }; | ||||
/* | /* | ||||
@@ -59,28 +59,28 @@ private: | |||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
struct mat<2, 2, T> | |||||
struct mat_t<T, 2, 2> | |||||
{ | { | ||||
typedef mat<2,2,T> type; | |||||
typedef mat_t<T,2,2> type; | |||||
inline mat() {} | |||||
inline mat(vec<2,T> v0, vec<2,T> v1) | |||||
inline mat_t() {} | |||||
inline mat_t(vec_t<T,2> v0, vec_t<T,2> v1) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ v0, v1 } {} | : m_data{ v0, v1 } {} | ||||
#else | #else | ||||
: m_v0(v0), m_v1(v1) {} | : m_v0(v0), m_v1(v1) {} | ||||
#endif | #endif | ||||
explicit inline mat(T const &val) | |||||
explicit inline mat_t(T const &val) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<2,T>(val, T(0)), | |||||
vec<2,T>(T(0), val) } {} | |||||
: m_data{ vec_t<T,2>(val, T(0)), | |||||
vec_t<T,2>(T(0), val) } {} | |||||
#else | #else | ||||
: m_v0(val, T(0)), | : m_v0(val, T(0)), | ||||
m_v1(T(0), val) {} | m_v1(T(0), val) {} | ||||
#endif | #endif | ||||
explicit inline mat(mat<4,4,T> const &m) | |||||
explicit inline mat_t(mat_t<T,4,4> const &m) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ m[0].xy, m[1].xy } {} | : m_data{ m[0].xy, m[1].xy } {} | ||||
#else | #else | ||||
@@ -88,16 +88,16 @@ struct mat<2, 2, T> | |||||
#endif | #endif | ||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
inline vec<2,T>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec<2,T> const& operator[](size_t n) const { return m_data[n]; } | |||||
inline vec_t<T,2>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec_t<T,2> const& operator[](size_t n) const { return m_data[n]; } | |||||
#else | #else | ||||
inline vec<2,T>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec<2,T> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
inline vec_t<T,2>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec_t<T,2> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
#endif | #endif | ||||
/* Helpers for transformation matrices */ | /* Helpers for transformation matrices */ | ||||
static mat<2,2,T> rotate(T degrees); | |||||
static inline mat<2,2,T> rotate(mat<2,2,T> m, T degrees) | |||||
static mat_t<T,2,2> rotate(T degrees); | |||||
static inline mat_t<T,2,2> rotate(mat_t<T,2,2> m, T degrees) | |||||
{ | { | ||||
return rotate(degrees) * m; | return rotate(degrees) * m; | ||||
} | } | ||||
@@ -107,15 +107,15 @@ struct mat<2, 2, T> | |||||
template<class U> | template<class U> | ||||
friend std::ostream &operator<<(std::ostream &stream, | friend std::ostream &operator<<(std::ostream &stream, | ||||
mat<2,2,U> const &m); | |||||
mat_t<U,2,2> const &m); | |||||
static const mat<2,2,T> identity; | |||||
static const mat_t<T,2,2> identity; | |||||
private: | private: | ||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
vec<2,T> m_data[2]; | |||||
vec_t<T,2> m_data[2]; | |||||
#else | #else | ||||
vec<2,T> m_v0, m_v1; | |||||
vec_t<T,2> m_v0, m_v1; | |||||
#endif | #endif | ||||
}; | }; | ||||
@@ -124,91 +124,91 @@ private: | |||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
struct mat<3,3,T> | |||||
struct mat_t<T, 3, 3> | |||||
{ | { | ||||
typedef mat<3,3,T> type; | |||||
typedef mat_t<T,3,3> type; | |||||
inline mat() {} | |||||
inline mat(vec<3,T> v0, vec<3,T> v1, vec<3,T> v2) | |||||
inline mat_t() {} | |||||
inline mat_t(vec_t<T,3> v0, vec_t<T,3> v1, vec_t<T,3> v2) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ v0, v1, v2 } {} | : m_data{ v0, v1, v2 } {} | ||||
#else | #else | ||||
: m_v0(v0), m_v1(v1), m_v2(v2) {} | : m_v0(v0), m_v1(v1), m_v2(v2) {} | ||||
#endif | #endif | ||||
explicit inline mat(T const &val) | |||||
explicit inline mat_t(T const &val) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<3,T>(val, (T)0, (T)0), | |||||
vec<3,T>((T)0, val, (T)0), | |||||
vec<3,T>((T)0, (T)0, val) } {} | |||||
: m_data{ vec_t<T,3>(val, (T)0, (T)0), | |||||
vec_t<T,3>((T)0, val, (T)0), | |||||
vec_t<T,3>((T)0, (T)0, val) } {} | |||||
#else | #else | ||||
: m_v0(val, (T)0, (T)0), | : m_v0(val, (T)0, (T)0), | ||||
m_v1((T)0, val, (T)0), | m_v1((T)0, val, (T)0), | ||||
m_v2((T)0, (T)0, val) {} | m_v2((T)0, (T)0, val) {} | ||||
#endif | #endif | ||||
explicit inline mat(mat<2,2,T> m, T const &val = T(1)) | |||||
explicit inline mat_t(mat_t<T,2,2> m, T const &val = T(1)) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<3,T>(m[0], (T)0), | |||||
vec<3,T>(m[1], (T)0), | |||||
vec<3,T>((T)0, (T)0, val) } {} | |||||
: m_data{ vec_t<T,3>(m[0], (T)0), | |||||
vec_t<T,3>(m[1], (T)0), | |||||
vec_t<T,3>((T)0, (T)0, val) } {} | |||||
#else | #else | ||||
: m_v0(m[0], (T)0), | : m_v0(m[0], (T)0), | ||||
m_v1(m[1], (T)0), | m_v1(m[1], (T)0), | ||||
m_v2((T)0, (T)0, val) {} | m_v2((T)0, (T)0, val) {} | ||||
#endif | #endif | ||||
explicit inline mat(mat<4,4,T> const &m) | |||||
explicit inline mat_t(mat_t<T,4,4> const &m) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ m[0].xyz, m[1].xyz, m[2].xyz } {} | : m_data{ m[0].xyz, m[1].xyz, m[2].xyz } {} | ||||
#else | #else | ||||
: m_v0(m[0].xyz), m_v1(m[1].xyz), m_v2(m[2].xyz) {} | : m_v0(m[0].xyz), m_v1(m[1].xyz), m_v2(m[2].xyz) {} | ||||
#endif | #endif | ||||
explicit mat(Quat<T> const &q); | |||||
explicit mat_t(quat_t<T> const &q); | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
inline vec<3,T>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec<3,T> const& operator[](size_t n) const { return m_data[n]; } | |||||
inline vec_t<T,3>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec_t<T,3> const& operator[](size_t n) const { return m_data[n]; } | |||||
#else | #else | ||||
inline vec<3,T>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec<3,T> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
inline vec_t<T,3>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec_t<T,3> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
#endif | #endif | ||||
/* Helpers for transformation matrices */ | /* Helpers for transformation matrices */ | ||||
static mat<3,3,T> scale(T x); | |||||
static mat<3,3,T> scale(T x, T y, T z); | |||||
static mat<3,3,T> scale(vec<3,T> v); | |||||
static mat<3,3,T> rotate(T degrees, T x, T y, T z); | |||||
static mat<3,3,T> rotate(T degrees, vec<3,T> v); | |||||
static mat<3,3,T> fromeuler_xyz(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_xzy(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_yxz(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_yzx(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_zxy(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_zyx(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_xyz(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_xzy(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_yxz(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_yzx(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_zxy(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_zyx(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_xyx(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_xzx(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_yxy(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_yzy(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_zxz(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_zyz(vec<3,T> const &v); | |||||
static mat<3,3,T> fromeuler_xyx(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_xzx(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_yxy(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_yzy(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_zxz(T phi, T theta, T psi); | |||||
static mat<3,3,T> fromeuler_zyz(T phi, T theta, T psi); | |||||
static inline mat<3,3,T> rotate(mat<3,3,T> m, T degrees, vec<3,T> v) | |||||
static mat_t<T,3,3> scale(T x); | |||||
static mat_t<T,3,3> scale(T x, T y, T z); | |||||
static mat_t<T,3,3> scale(vec_t<T,3> v); | |||||
static mat_t<T,3,3> rotate(T degrees, T x, T y, T z); | |||||
static mat_t<T,3,3> rotate(T degrees, vec_t<T,3> v); | |||||
static mat_t<T,3,3> fromeuler_xyz(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_xzy(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_yxz(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_yzx(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_zxy(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_zyx(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_xyz(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_xzy(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_yxz(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_yzx(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_zxy(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_zyx(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_xyx(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_xzx(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_yxy(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_yzy(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_zxz(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_zyz(vec_t<T,3> const &v); | |||||
static mat_t<T,3,3> fromeuler_xyx(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_xzx(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_yxy(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_yzy(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_zxz(T phi, T theta, T psi); | |||||
static mat_t<T,3,3> fromeuler_zyz(T phi, T theta, T psi); | |||||
static inline mat_t<T,3,3> rotate(mat_t<T,3,3> m, T degrees, vec_t<T,3> v) | |||||
{ | { | ||||
return rotate(degrees, v) * m; | return rotate(degrees, v) * m; | ||||
} | } | ||||
@@ -218,15 +218,15 @@ struct mat<3,3,T> | |||||
template<class U> | template<class U> | ||||
friend std::ostream &operator<<(std::ostream &stream, | friend std::ostream &operator<<(std::ostream &stream, | ||||
mat<3,3,U> const &m); | |||||
mat_t<U,3,3> const &m); | |||||
static const mat<3,3,T> identity; | |||||
static const mat_t<T,3,3> identity; | |||||
private: | private: | ||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
vec<3,T> m_data[3]; | |||||
vec_t<T,3> m_data[3]; | |||||
#else | #else | ||||
vec<3,T> m_v0, m_v1, m_v2; | |||||
vec_t<T,3> m_v0, m_v1, m_v2; | |||||
#endif | #endif | ||||
}; | }; | ||||
@@ -235,24 +235,24 @@ private: | |||||
*/ | */ | ||||
template <typename T> | template <typename T> | ||||
struct mat<4, 4, T> | |||||
struct mat_t<T, 4, 4> | |||||
{ | { | ||||
typedef mat<4,4,T> type; | |||||
typedef mat_t<T,4,4> type; | |||||
inline mat() {} | |||||
inline mat(vec<4,T> v0, vec<4,T> v1, vec<4,T> v2, vec<4,T> v3) | |||||
inline mat_t() {} | |||||
inline mat_t(vec_t<T,4> v0, vec_t<T,4> v1, vec_t<T,4> v2, vec_t<T,4> v3) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ v0, v1, v2, v3 } {} | : m_data{ v0, v1, v2, v3 } {} | ||||
#else | #else | ||||
: m_v0(v0), m_v1(v1), m_v2(v2), m_v3(v3) {} | : m_v0(v0), m_v1(v1), m_v2(v2), m_v3(v3) {} | ||||
#endif | #endif | ||||
explicit inline mat(T const &val) | |||||
explicit inline mat_t(T const &val) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<4,T>(val, (T)0, (T)0, (T)0), | |||||
vec<4,T>((T)0, val, (T)0, (T)0), | |||||
vec<4,T>((T)0, (T)0, val, (T)0), | |||||
vec<4,T>((T)0, (T)0, (T)0, val) } {} | |||||
: m_data{ vec_t<T,4>(val, (T)0, (T)0, (T)0), | |||||
vec_t<T,4>((T)0, val, (T)0, (T)0), | |||||
vec_t<T,4>((T)0, (T)0, val, (T)0), | |||||
vec_t<T,4>((T)0, (T)0, (T)0, val) } {} | |||||
#else | #else | ||||
: m_v0(val, (T)0, (T)0, (T)0), | : m_v0(val, (T)0, (T)0, (T)0), | ||||
m_v1((T)0, val, (T)0, (T)0), | m_v1((T)0, val, (T)0, (T)0), | ||||
@@ -260,12 +260,12 @@ struct mat<4, 4, T> | |||||
m_v3((T)0, (T)0, (T)0, val) {} | m_v3((T)0, (T)0, (T)0, val) {} | ||||
#endif | #endif | ||||
explicit inline mat(mat<2,2,T> m, T const &val = T(1)) | |||||
explicit inline mat_t(mat_t<T,2,2> m, T const &val = T(1)) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<4,T>(m[0], (T)0, (T)0), | |||||
vec<4,T>(m[1], (T)0, (T)0), | |||||
vec<4,T>((T)0, (T)0, val, (T)0), | |||||
vec<4,T>((T)0, (T)0, (T)0, val) } {} | |||||
: m_data{ vec_t<T,4>(m[0], (T)0, (T)0), | |||||
vec_t<T,4>(m[1], (T)0, (T)0), | |||||
vec_t<T,4>((T)0, (T)0, val, (T)0), | |||||
vec_t<T,4>((T)0, (T)0, (T)0, val) } {} | |||||
#else | #else | ||||
: m_v0(m[0], (T)0, (T)0), | : m_v0(m[0], (T)0, (T)0), | ||||
m_v1(m[1], (T)0, (T)0), | m_v1(m[1], (T)0, (T)0), | ||||
@@ -273,12 +273,12 @@ struct mat<4, 4, T> | |||||
m_v3((T)0, (T)0, (T)0, val) {} | m_v3((T)0, (T)0, (T)0, val) {} | ||||
#endif | #endif | ||||
explicit inline mat(mat<3,3,T> m, T const &val = T(1)) | |||||
explicit inline mat_t(mat_t<T,3,3> m, T const &val = T(1)) | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
: m_data{ vec<4,T>(m[0], (T)0), | |||||
vec<4,T>(m[1], (T)0), | |||||
vec<4,T>(m[2], (T)0), | |||||
vec<4,T>((T)0, (T)0, (T)0, val) } {} | |||||
: m_data{ vec_t<T,4>(m[0], (T)0), | |||||
vec_t<T,4>(m[1], (T)0), | |||||
vec_t<T,4>(m[2], (T)0), | |||||
vec_t<T,4>((T)0, (T)0, (T)0, val) } {} | |||||
#else | #else | ||||
: m_v0(m[0], (T)0), | : m_v0(m[0], (T)0), | ||||
m_v1(m[1], (T)0), | m_v1(m[1], (T)0), | ||||
@@ -286,120 +286,120 @@ struct mat<4, 4, T> | |||||
m_v3((T)0, (T)0, (T)0, val) {} | m_v3((T)0, (T)0, (T)0, val) {} | ||||
#endif | #endif | ||||
explicit mat(Quat<T> const &q); | |||||
explicit mat_t(quat_t<T> const &q); | |||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
inline vec<4,T>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec<4,T> const& operator[](size_t n) const { return m_data[n]; } | |||||
inline vec_t<T,4>& operator[](size_t n) { return m_data[n]; } | |||||
inline vec_t<T,4> const& operator[](size_t n) const { return m_data[n]; } | |||||
#else | #else | ||||
inline vec<4,T>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec<4,T> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
inline vec_t<T,4>& operator[](size_t n) { return (&m_v0)[n]; } | |||||
inline vec_t<T,4> const& operator[](size_t n) const { return (&m_v0)[n]; } | |||||
#endif | #endif | ||||
/* Helpers for transformation matrices */ | /* Helpers for transformation matrices */ | ||||
static mat<4,4,T> translate(T x, T y, T z); | |||||
static mat<4,4,T> translate(vec<3,T> v); | |||||
static mat_t<T,4,4> translate(T x, T y, T z); | |||||
static mat_t<T,4,4> translate(vec_t<T,3> v); | |||||
static inline mat<4,4,T> scale(T x) | |||||
static inline mat_t<T,4,4> scale(T x) | |||||
{ | { | ||||
return mat<4,4,T>(mat<3,3,T>::scale(x), (T)1); | |||||
return mat_t<T,4,4>(mat_t<T,3,3>::scale(x), (T)1); | |||||
} | } | ||||
static inline mat<4,4,T> scale(T x, T y, T z) | |||||
static inline mat_t<T,4,4> scale(T x, T y, T z) | |||||
{ | { | ||||
return mat<4,4,T>(mat<3,3,T>::scale(x, y, z), (T)1); | |||||
return mat_t<T,4,4>(mat_t<T,3,3>::scale(x, y, z), (T)1); | |||||
} | } | ||||
static inline mat<4,4,T> scale(vec<3,T> v) | |||||
static inline mat_t<T,4,4> scale(vec_t<T,3> v) | |||||
{ | { | ||||
return mat<4,4,T>(mat<3,3,T>::scale(v), (T)1); | |||||
return mat_t<T,4,4>(mat_t<T,3,3>::scale(v), (T)1); | |||||
} | } | ||||
static inline mat<4,4,T> translate(mat<4,4,T> const &m, vec<3,T> v) | |||||
static inline mat_t<T,4,4> translate(mat_t<T,4,4> const &m, vec_t<T,3> v) | |||||
{ | { | ||||
return translate(v) * m; | return translate(v) * m; | ||||
} | } | ||||
static inline mat<4,4,T> rotate(T degrees, T x, T y, T z) | |||||
static inline mat_t<T,4,4> rotate(T degrees, T x, T y, T z) | |||||
{ | { | ||||
return mat<4,4,T>(mat<3,3,T>::rotate(degrees, x, y, z), (T)1); | |||||
return mat_t<T,4,4>(mat_t<T,3,3>::rotate(degrees, x, y, z), (T)1); | |||||
} | } | ||||
static inline mat<4,4,T> rotate(T degrees, vec<3,T> v) | |||||
static inline mat_t<T,4,4> rotate(T degrees, vec_t<T,3> v) | |||||
{ | { | ||||
return mat<4,4,T>(mat<3,3,T>::rotate(degrees, v), (T)1); | |||||
return mat_t<T,4,4>(mat_t<T,3,3>::rotate(degrees, v), (T)1); | |||||
} | } | ||||
static inline mat<4,4,T> rotate(mat<4,4,T> &m, T degrees, vec<3,T> v) | |||||
static inline mat_t<T,4,4> rotate(mat_t<T,4,4> &m, T degrees, vec_t<T,3> v) | |||||
{ | { | ||||
return rotate(degrees, v) * m; | return rotate(degrees, v) * m; | ||||
} | } | ||||
static mat<4,4,T> fromeuler_xyz(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_xzy(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_yxz(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_yzx(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_zxy(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_zyx(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_xyz(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_xzy(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_yxz(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_yzx(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_zxy(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_zyx(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_xyx(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_xzx(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_yxy(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_yzy(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_zxz(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_zyz(vec<3,T> const &v); | |||||
static mat<4,4,T> fromeuler_xyx(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_xzx(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_yxy(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_yzy(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_zxz(T phi, T theta, T psi); | |||||
static mat<4,4,T> fromeuler_zyz(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_xyz(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_xzy(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_yxz(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_yzx(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_zxy(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_zyx(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_xyz(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_xzy(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_yxz(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_yzx(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_zxy(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_zyx(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_xyx(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_xzx(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_yxy(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_yzy(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_zxz(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_zyz(vec_t<T,3> const &v); | |||||
static mat_t<T,4,4> fromeuler_xyx(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_xzx(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_yxy(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_yzy(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_zxz(T phi, T theta, T psi); | |||||
static mat_t<T,4,4> fromeuler_zyz(T phi, T theta, T psi); | |||||
/* Helpers for view matrices */ | /* Helpers for view matrices */ | ||||
static mat<4,4,T> lookat(vec<3,T> eye, vec<3,T> center, vec<3,T> up); | |||||
static mat_t<T,4,4> lookat(vec_t<T,3> eye, vec_t<T,3> center, vec_t<T,3> up); | |||||
/* Helpers for projection matrices */ | /* Helpers for projection matrices */ | ||||
static mat<4,4,T> ortho(T left, T right, T bottom, T top, T near, T far); | |||||
static mat<4,4,T> ortho(T width, T height, T near, T far); | |||||
static mat<4,4,T> frustum(T left, T right, T bottom, T top, T near, T far); | |||||
static mat<4,4,T> perspective(T fov_y, T width, T height, T near, T far); | |||||
static mat<4,4,T> shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); | |||||
static mat_t<T,4,4> ortho(T left, T right, T bottom, T top, T near, T far); | |||||
static mat_t<T,4,4> ortho(T width, T height, T near, T far); | |||||
static mat_t<T,4,4> frustum(T left, T right, T bottom, T top, T near, T far); | |||||
static mat_t<T,4,4> perspective(T fov_y, T width, T height, T near, T far); | |||||
static mat_t<T,4,4> shifted_perspective(T fov_y, T screen_size, T screen_ratio_yx, T near, T far); | |||||
void printf() const; | void printf() const; | ||||
String tostring() const; | String tostring() const; | ||||
template<class U> | template<class U> | ||||
friend std::ostream &operator<<(std::ostream &stream, | friend std::ostream &operator<<(std::ostream &stream, | ||||
mat<4,4,U> const &m); | |||||
mat_t<U,4,4> const &m); | |||||
static const mat<4,4,T> identity; | |||||
static const mat_t<T,4,4> identity; | |||||
private: | private: | ||||
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | #if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS | ||||
vec<4,T> m_data[4]; | |||||
vec_t<T,4> m_data[4]; | |||||
#else | #else | ||||
vec<4,T> m_v0, m_v1, m_v2, m_v3; | |||||
vec_t<T,4> m_v0, m_v1, m_v2, m_v3; | |||||
#endif | #endif | ||||
}; | }; | ||||
template<typename T> T determinant(mat<2,2,T> const &); | |||||
template<typename T> T determinant(mat<3,3,T> const &); | |||||
template<typename T> T determinant(mat<4,4,T> const &); | |||||
template<typename T> T determinant(mat_t<T,2,2> const &); | |||||
template<typename T> T determinant(mat_t<T,3,3> const &); | |||||
template<typename T> T determinant(mat_t<T,4,4> const &); | |||||
template<typename T> mat<2,2,T> inverse(mat<2,2,T> const &); | |||||
template<typename T> mat<3,3,T> inverse(mat<3,3,T> const &); | |||||
template<typename T> mat<4,4,T> inverse(mat<4,4,T> const &); | |||||
template<typename T> mat_t<T,2,2> inverse(mat_t<T,2,2> const &); | |||||
template<typename T> mat_t<T,3,3> inverse(mat_t<T,3,3> const &); | |||||
template<typename T> mat_t<T,4,4> inverse(mat_t<T,4,4> const &); | |||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<ROWS, COLS, T> transpose(mat<COLS, ROWS, T> const &m) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, ROWS, COLS> transpose(mat_t<T, COLS, ROWS> const &m) | |||||
{ | { | ||||
mat<ROWS, COLS, T> ret; | |||||
mat_t<T, ROWS, COLS> ret; | |||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
for (int j = 0; j < ROWS; ++j) | for (int j = 0; j < ROWS; ++j) | ||||
ret[j][i] = m[i][j]; | ret[j][i] = m[i][j]; | ||||
@@ -410,50 +410,50 @@ static inline mat<ROWS, COLS, T> transpose(mat<COLS, ROWS, T> const &m) | |||||
* Addition/subtraction/unary | * Addition/subtraction/unary | ||||
*/ | */ | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> &operator +=(mat<COLS, ROWS, T> &a, | |||||
mat<COLS, ROWS, T> const &b) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> &operator +=(mat_t<T, COLS, ROWS> &a, | |||||
mat_t<T, COLS, ROWS> const &b) | |||||
{ | { | ||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
a[i] += b[i]; | a[i] += b[i]; | ||||
return a; | return a; | ||||
} | } | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> operator +(mat<COLS, ROWS, T> const &a, | |||||
mat<COLS, ROWS, T> const &b) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> operator +(mat_t<T, COLS, ROWS> const &a, | |||||
mat_t<T, COLS, ROWS> const &b) | |||||
{ | { | ||||
mat<COLS, ROWS, T> ret = a; | |||||
mat_t<T, COLS, ROWS> ret = a; | |||||
return ret += b; | return ret += b; | ||||
} | } | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> operator +(mat<COLS, ROWS, T> const &m) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> operator +(mat_t<T, COLS, ROWS> const &m) | |||||
{ | { | ||||
return m; | return m; | ||||
} | } | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> &operator -=(mat<COLS, ROWS, T> &a, | |||||
mat<COLS, ROWS, T> const &b) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> &operator -=(mat_t<T, COLS, ROWS> &a, | |||||
mat_t<T, COLS, ROWS> const &b) | |||||
{ | { | ||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
a[i] -= b[i]; | a[i] -= b[i]; | ||||
return a; | return a; | ||||
} | } | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> operator -(mat<COLS, ROWS, T> const &a, | |||||
mat<COLS, ROWS, T> const &b) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> operator -(mat_t<T, COLS, ROWS> const &a, | |||||
mat_t<T, COLS, ROWS> const &b) | |||||
{ | { | ||||
mat<COLS, ROWS, T> ret = a; | |||||
mat_t<T, COLS, ROWS> ret = a; | |||||
return ret -= b; | return ret -= b; | ||||
} | } | ||||
template<int COLS, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> operator -(mat<COLS, ROWS, T> const &m) | |||||
template<typename T, int COLS, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> operator -(mat_t<T, COLS, ROWS> const &m) | |||||
{ | { | ||||
mat<COLS, ROWS, T> ret; | |||||
mat_t<T, COLS, ROWS> ret; | |||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
ret[i] = -m[i]; | ret[i] = -m[i]; | ||||
return ret; | return ret; | ||||
@@ -463,21 +463,21 @@ static inline mat<COLS, ROWS, T> operator -(mat<COLS, ROWS, T> const &m) | |||||
* Matrix-vector and vector-matrix multiplication | * Matrix-vector and vector-matrix multiplication | ||||
*/ | */ | ||||
template<int COLS, int ROWS, int MASK, typename T> | |||||
static inline vec<ROWS, T> operator *(mat<COLS, ROWS, T> const &m, | |||||
vec<COLS, T, MASK> const &v) | |||||
template<typename T, int COLS, int ROWS, int SWIZZLE> | |||||
static inline vec_t<T, ROWS> operator *(mat_t<T, COLS, ROWS> const &m, | |||||
vec_t<T, COLS, SWIZZLE> const &v) | |||||
{ | { | ||||
vec<ROWS, T> ret(T(0)); | |||||
vec_t<T, ROWS> ret(T(0)); | |||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
ret += m[i] * v[i]; | ret += m[i] * v[i]; | ||||
return ret; | return ret; | ||||
} | } | ||||
template<int COLS, int ROWS, int MASK, typename T> | |||||
static inline vec<COLS, T> operator *(vec<ROWS, T, MASK> const &v, | |||||
mat<COLS, ROWS, T> const &m) | |||||
template<typename T, int COLS, int ROWS, int SWIZZLE> | |||||
static inline vec_t<T, COLS> operator *(vec_t<T, ROWS, SWIZZLE> const &v, | |||||
mat_t<T, COLS, ROWS> const &m) | |||||
{ | { | ||||
vec<COLS, T> ret(T(0)); | |||||
vec_t<T, COLS> ret(T(0)); | |||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
ret[i] = dot(v, m[i]); | ret[i] = dot(v, m[i]); | ||||
return ret; | return ret; | ||||
@@ -487,19 +487,19 @@ static inline vec<COLS, T> operator *(vec<ROWS, T, MASK> const &v, | |||||
* Matrix-matrix multiplication | * Matrix-matrix multiplication | ||||
*/ | */ | ||||
template<int COLS, int N, int ROWS, typename T> | |||||
static inline mat<COLS, ROWS, T> operator *(mat<N, ROWS, T> const &a, | |||||
mat<COLS, N, T> const &b) | |||||
template<typename T, int COLS, int N, int ROWS> | |||||
static inline mat_t<T, COLS, ROWS> operator *(mat_t<T, N, ROWS> const &a, | |||||
mat_t<T, COLS, N> const &b) | |||||
{ | { | ||||
mat<COLS, ROWS, T> ret; | |||||
mat_t<T, COLS, ROWS> ret; | |||||
for (int i = 0; i < COLS; ++i) | for (int i = 0; i < COLS; ++i) | ||||
ret[i] = a * b[i]; | ret[i] = a * b[i]; | ||||
return ret; | return ret; | ||||
} | } | ||||
template<int N, typename T> | |||||
static inline mat<N, N, T> &operator *=(mat<N, N, T> &a, | |||||
mat<N, N, T> const &b) | |||||
template<typename T, int N> | |||||
static inline mat_t<T, N, N> &operator *=(mat_t<T, N, N> &a, | |||||
mat_t<T, N, N> const &b) | |||||
{ | { | ||||
return a = a * b; | return a = a * b; | ||||
} | } | ||||
@@ -9,8 +9,8 @@ | |||||
// | // | ||||
// | // | ||||
// The complex and quaternion classes | |||||
// ---------------------------------- | |||||
// The complex, quaternion and dual quaternion classes | |||||
// --------------------------------------------------- | |||||
// | // | ||||
#if !defined __LOL_MATH_TRANSFORM_H__ | #if !defined __LOL_MATH_TRANSFORM_H__ | ||||
@@ -18,9 +18,6 @@ | |||||
#include <ostream> | #include <ostream> | ||||
#include <lol/math/half.h> | |||||
#include <lol/math/real.h> | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
@@ -29,162 +26,114 @@ namespace lol | |||||
#endif | #endif | ||||
/* | /* | ||||
* 2-element complexes | |||||
* 2-element transforms: complex numbers | |||||
*/ | */ | ||||
template <typename T> struct Cmplx | |||||
template<typename T> | |||||
struct cmplx_t | |||||
{ | { | ||||
typedef Cmplx<T> type; | |||||
typedef cmplx_t<T> type; | |||||
inline constexpr Cmplx() {} | |||||
inline constexpr Cmplx(T X) : x(X), y(T(0)) {} | |||||
inline constexpr Cmplx(T X, T Y) : x(X), y(Y) {} | |||||
inline constexpr cmplx_t() {} | |||||
inline constexpr cmplx_t(T X) : x(X), y(T(0)) {} | |||||
inline constexpr cmplx_t(T X, T Y) : x(X), y(Y) {} | |||||
template<typename U> | template<typename U> | ||||
explicit inline constexpr Cmplx(Cmplx<U> const &z) | |||||
explicit inline constexpr cmplx_t(cmplx_t<U> const &z) | |||||
: x(z.x), y(z.y) {} | : x(z.x), y(z.y) {} | ||||
LOL_COMMON_MEMBER_OPS(x) | LOL_COMMON_MEMBER_OPS(x) | ||||
LOL_NONVECTOR_MEMBER_OPS() | LOL_NONVECTOR_MEMBER_OPS() | ||||
inline Cmplx<T> operator *(Cmplx<T> const &val) const | |||||
inline cmplx_t<T> operator *(cmplx_t<T> const &val) const | |||||
{ | { | ||||
return Cmplx<T>(x * val.x - y * val.y, x * val.y + y * val.x); | |||||
return cmplx_t<T>(x * val.x - y * val.y, x * val.y + y * val.x); | |||||
} | } | ||||
inline Cmplx<T> operator *=(Cmplx<T> const &val) | |||||
inline cmplx_t<T> operator *=(cmplx_t<T> const &val) | |||||
{ | { | ||||
return *this = (*this) * val; | return *this = (*this) * val; | ||||
} | } | ||||
inline Cmplx<T> operator ~() const | |||||
inline cmplx_t<T> operator ~() const | |||||
{ | { | ||||
return Cmplx<T>(x, -y); | |||||
return cmplx_t<T>(x, -y); | |||||
} | } | ||||
template<typename U> | template<typename U> | ||||
friend std::ostream &operator<<(std::ostream &stream, Cmplx<U> const &v); | |||||
friend std::ostream &operator<<(std::ostream &stream, cmplx_t<U> const &v); | |||||
T x, y; | T x, y; | ||||
}; | }; | ||||
template<typename T> | |||||
static inline T dot(Cmplx<T> const &z1, Cmplx<T> const &z2) | |||||
{ | |||||
T ret(0); | |||||
for (size_t i = 0; i < sizeof(Cmplx<T>) / sizeof(T); ++i) | |||||
ret += z1[i] * z2[i]; | |||||
return ret; | |||||
} | |||||
template<typename T> | |||||
static inline T sqlength(Cmplx<T> const &z) | |||||
{ | |||||
return dot(z, z); | |||||
} | |||||
template<typename T> | |||||
static inline T length(Cmplx<T> const &z) | |||||
{ | |||||
/* FIXME: this is not very nice */ | |||||
return (T)sqrt((double)sqlength(z)); | |||||
} | |||||
template<typename T> | |||||
static inline T norm(Cmplx<T> const &z) | |||||
{ | |||||
return length(z); | |||||
} | |||||
template<typename T> | |||||
static inline Cmplx<T> re(Cmplx<T> const &z) | |||||
{ | |||||
return ~z / sqlength(z); | |||||
} | |||||
template<typename T> | |||||
static inline Cmplx<T> normalize(Cmplx<T> const &z) | |||||
{ | |||||
T norm = (T)length(z); | |||||
return norm ? z / norm : Cmplx<T>(T(0)); | |||||
} | |||||
template<typename T> | |||||
static inline Cmplx<T> operator /(T a, Cmplx<T> const &b) | |||||
{ | |||||
return a * re(b); | |||||
} | |||||
template<typename T> | |||||
static inline Cmplx<T> operator /(Cmplx<T> a, Cmplx<T> const &b) | |||||
{ | |||||
return a * re(b); | |||||
} | |||||
template<typename T> | |||||
static inline bool operator ==(Cmplx<T> const &a, T b) | |||||
{ | |||||
return (a.x == b) && !a.y; | |||||
} | |||||
template<typename T> | |||||
static inline bool operator !=(Cmplx<T> const &a, T b) | |||||
{ | |||||
return (a.x != b) || a.y; | |||||
} | |||||
template<typename T> | |||||
static inline bool operator ==(T a, Cmplx<T> const &b) { return b == a; } | |||||
template<typename T> | |||||
static inline bool operator !=(T a, Cmplx<T> const &b) { return b != a; } | |||||
/* | /* | ||||
* 4-element quaternions | |||||
* 4-element transforms: quaternions | |||||
*/ | */ | ||||
template <typename T> struct Quat | |||||
template<typename T> | |||||
struct quat_t | |||||
{ | { | ||||
typedef Quat<T> type; | |||||
typedef quat_t<T> type; | |||||
inline constexpr Quat() {} | |||||
inline constexpr Quat(T W) : w(W), x(0), y(0), z(0) {} | |||||
inline constexpr Quat(T W, T X, T Y, T Z) : w(W), x(X), y(Y), z(Z) {} | |||||
/* Default constructor and copy constructor */ | |||||
inline constexpr quat_t() : w(), x(), y(), z() {} | |||||
inline constexpr quat_t(quat_t<T> const &q) | |||||
: w(q.w), x(q.x), y(q.y), z(q.z) {} | |||||
/* Explicit constructor for type conversion */ | |||||
template<typename U> | template<typename U> | ||||
explicit inline constexpr Quat(Quat<U> const &q) | |||||
explicit inline constexpr quat_t(quat_t<U> const &q) | |||||
: w(q.w), x(q.x), y(q.y), z(q.z) {} | : w(q.w), x(q.x), y(q.y), z(q.z) {} | ||||
Quat(mat<3,3,T> const &m); | |||||
Quat(mat<4,4,T> const &m); | |||||
/* Various explicit constructors */ | |||||
explicit inline constexpr quat_t(T W, T X, T Y, T Z) | |||||
: w(W), x(X), y(Y), z(Z) {} | |||||
explicit inline constexpr quat_t(T W) | |||||
: w(W), x(0), y(0), z(0) {} | |||||
explicit quat_t(mat_t<T,3,3> const &m); | |||||
explicit quat_t(mat_t<T,4,4> const &m); | |||||
LOL_COMMON_MEMBER_OPS(w) | LOL_COMMON_MEMBER_OPS(w) | ||||
LOL_NONVECTOR_MEMBER_OPS() | LOL_NONVECTOR_MEMBER_OPS() | ||||
inline quat_t operator *(quat_t const &val) const | |||||
{ | |||||
vec_t<T,3> v1(x, y, z); | |||||
vec_t<T,3> v2(val.x, val.y, val.z); | |||||
vec_t<T,3> v3 = cross(v1, v2) + w * v2 + val.w * v1; | |||||
return quat_t(w * val.w - dot(v1, v2), v3.x, v3.y, v3.z); | |||||
} | |||||
inline quat_t operator *=(quat_t const &val) | |||||
{ | |||||
return *this = (*this * val); | |||||
} | |||||
/* Create a unit quaternion representing a rotation around an axis. */ | /* Create a unit quaternion representing a rotation around an axis. */ | ||||
static Quat<T> rotate(T degrees, T x, T y, T z); | |||||
static Quat<T> rotate(T degrees, vec<3,T> const &v); | |||||
static quat_t rotate(T degrees, T x, T y, T z); | |||||
static quat_t rotate(T degrees, vec_t<T,3> const &v); | |||||
/* Create a unit quaternion representing a rotation between two vectors. | /* Create a unit quaternion representing a rotation between two vectors. | ||||
* Input vectors need not be normalised. */ | * Input vectors need not be normalised. */ | ||||
static Quat<T> rotate(vec<3,T> const &src, vec<3,T> const &dst); | |||||
static quat_t rotate(vec_t<T,3> const &src, vec_t<T,3> const &dst); | |||||
/* Convert from Euler angles. The axes in fromeuler_xyx are | /* Convert from Euler angles. The axes in fromeuler_xyx are | ||||
* x, then y', then x", ie. the axes are attached to the model. | * x, then y', then x", ie. the axes are attached to the model. | ||||
* If you want to rotate around static axes, just reverse the order | * If you want to rotate around static axes, just reverse the order | ||||
* of the arguments. Angle values are in degrees. */ | * of the arguments. Angle values are in degrees. */ | ||||
static Quat<T> fromeuler_xyx(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_xzx(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_yxy(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_yzy(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_zxz(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_zyz(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_xyx(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_xzx(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_yxy(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_yzy(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_zxz(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_zyz(T phi, T theta, T psi); | |||||
static quat_t fromeuler_xyx(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_xzx(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_yxy(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_yzy(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_zxz(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_zyz(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_xyx(T phi, T theta, T psi); | |||||
static quat_t fromeuler_xzx(T phi, T theta, T psi); | |||||
static quat_t fromeuler_yxy(T phi, T theta, T psi); | |||||
static quat_t fromeuler_yzy(T phi, T theta, T psi); | |||||
static quat_t fromeuler_zxz(T phi, T theta, T psi); | |||||
static quat_t fromeuler_zyz(T phi, T theta, T psi); | |||||
/* Convert from Tait-Bryan angles (incorrectly called Euler angles, | /* Convert from Tait-Bryan angles (incorrectly called Euler angles, | ||||
* but since everyone does it…). The axes in fromeuler_xyz are | * but since everyone does it…). The axes in fromeuler_xyz are | ||||
@@ -194,67 +143,60 @@ template <typename T> struct Quat | |||||
* If you want to rotate around static axes, reverse the order in | * If you want to rotate around static axes, reverse the order in | ||||
* the function name (_zyx instead of _xyz) AND reverse the order | * the function name (_zyx instead of _xyz) AND reverse the order | ||||
* of the arguments. */ | * of the arguments. */ | ||||
static Quat<T> fromeuler_xyz(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_xzy(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_yxz(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_yzx(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_zxy(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_zyx(vec<3,T> const &v); | |||||
static Quat<T> fromeuler_xyz(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_xzy(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_yxz(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_yzx(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_zxy(T phi, T theta, T psi); | |||||
static Quat<T> fromeuler_zyx(T phi, T theta, T psi); | |||||
inline Quat<T> operator *(Quat<T> const &val) const; | |||||
inline Quat<T> operator *=(Quat<T> const &val) | |||||
{ | |||||
return *this = (*this) * val; | |||||
} | |||||
inline Quat<T> operator ~() const | |||||
static quat_t fromeuler_xyz(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_xzy(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_yxz(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_yzx(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_zxy(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_zyx(vec_t<T,3> const &v); | |||||
static quat_t fromeuler_xyz(T phi, T theta, T psi); | |||||
static quat_t fromeuler_xzy(T phi, T theta, T psi); | |||||
static quat_t fromeuler_yxz(T phi, T theta, T psi); | |||||
static quat_t fromeuler_yzx(T phi, T theta, T psi); | |||||
static quat_t fromeuler_zxy(T phi, T theta, T psi); | |||||
static quat_t fromeuler_zyx(T phi, T theta, T psi); | |||||
inline quat_t operator ~() const | |||||
{ | { | ||||
return Quat<T>(w, -x, -y, -z); | |||||
return quat_t(w, -x, -y, -z); | |||||
} | } | ||||
inline vec<3,T> transform(vec<3,T> const &v) const | |||||
inline vec_t<T,3> transform(vec_t<T,3> const &v) const | |||||
{ | { | ||||
Quat<T> p = Quat<T>(0, v.x, v.y, v.z); | |||||
Quat<T> q = *this * p / *this; | |||||
return vec<3,T>(q.x, q.y, q.z); | |||||
quat_t p = quat_t(0, v.x, v.y, v.z); | |||||
quat_t q = *this * p / *this; | |||||
return vec_t<T,3>(q.x, q.y, q.z); | |||||
} | } | ||||
inline vec<4,T> transform(vec<4,T> const &v) const | |||||
inline vec_t<T,4> transform(vec_t<T,4> const &v) const | |||||
{ | { | ||||
Quat<T> p = Quat<T>(0, v.x, v.y, v.z); | |||||
Quat<T> q = *this * p / *this; | |||||
return vec<4,T>(q.x, q.y, q.z, v.w); | |||||
quat_t p = quat_t(0, v.x, v.y, v.z); | |||||
quat_t q = *this * p / *this; | |||||
return vec_t<T,4>(q.x, q.y, q.z, v.w); | |||||
} | } | ||||
inline vec<3,T> operator *(vec<3,T> const &v) const | |||||
inline vec_t<T,3> operator *(vec_t<T,3> const &v) const | |||||
{ | { | ||||
return transform(v); | return transform(v); | ||||
} | } | ||||
inline vec<4,T> operator *(vec<4,T> const &v) const | |||||
inline vec_t<T,4> operator *(vec_t<T,4> const &v) const | |||||
{ | { | ||||
return transform(v); | return transform(v); | ||||
} | } | ||||
inline vec<3,T> axis() | |||||
inline vec_t<T,3> axis() | |||||
{ | { | ||||
vec<3,T> v(x, y, z); | |||||
vec_t<T,3> v(x, y, z); | |||||
T n2 = sqlength(v); | T n2 = sqlength(v); | ||||
if (n2 <= (T)1e-6) | if (n2 <= (T)1e-6) | ||||
return vec<3,T>::axis_x; | |||||
return vec_t<T,3>::axis_x; | |||||
return normalize(v); | return normalize(v); | ||||
} | } | ||||
inline T angle() | inline T angle() | ||||
{ | { | ||||
vec<3,T> v(x, y, z); | |||||
vec_t<T,3> v(x, y, z); | |||||
T n2 = sqlength(v); | T n2 = sqlength(v); | ||||
if (n2 <= (T)1e-6) | if (n2 <= (T)1e-6) | ||||
return (T)0; | return (T)0; | ||||
@@ -262,78 +204,153 @@ template <typename T> struct Quat | |||||
} | } | ||||
template<typename U> | template<typename U> | ||||
friend std::ostream &operator<<(std::ostream &stream, Quat<U> const &v); | |||||
friend std::ostream &operator<<(std::ostream &stream, quat_t<U> const &v); | |||||
/* XXX: storage order is wxyz, unlike vectors! */ | /* XXX: storage order is wxyz, unlike vectors! */ | ||||
T w, x, y, z; | T w, x, y, z; | ||||
}; | }; | ||||
/* | |||||
* Common operations on transforms | |||||
*/ | |||||
template<typename T> | template<typename T> | ||||
static inline T dot(Quat<T> const &q1, Quat<T> const &q2) | |||||
static inline T dot(cmplx_t<T> const &t1, cmplx_t<T> const &t2) | |||||
{ | { | ||||
T ret(0); | T ret(0); | ||||
for (size_t i = 0; i < sizeof(Quat<T>) / sizeof(T); ++i) | |||||
ret += q1[i] * q2[i]; | |||||
for (size_t i = 0; i < sizeof(t1) / sizeof(T); ++i) | |||||
ret += t1[i] * t2[i]; | |||||
return ret; | return ret; | ||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline T sqlength(Quat<T> const &q) | |||||
static inline T sqlength(cmplx_t<T> const &t) | |||||
{ | { | ||||
return dot(q, q); | |||||
return dot(t, t); | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline T length(Quat<T> const &q) | |||||
static inline T length(cmplx_t<T> const &t) | |||||
{ | { | ||||
/* FIXME: this is not very nice */ | /* FIXME: this is not very nice */ | ||||
return (T)sqrt((double)sqlength(q)); | |||||
return (T)sqrt((double)sqlength(t)); | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline T norm(Quat<T> const &q) | |||||
static inline T norm(cmplx_t<T> const &t) | |||||
{ | { | ||||
return length(q); | |||||
return length(t); | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline Quat<T> re(Quat<T> const &q) | |||||
static inline cmplx_t<T> normalize(cmplx_t<T> const &z) | |||||
{ | { | ||||
return ~q / sqlength(q); | |||||
T norm = (T)length(z); | |||||
return norm ? z / norm : cmplx_t<T>(T(0)); | |||||
} | } | ||||
/* XXX: duplicate */ | |||||
template<typename T> | template<typename T> | ||||
static inline Quat<T> normalize(Quat<T> const &q) | |||||
static inline T dot(quat_t<T> const &t1, quat_t<T> const &t2) | |||||
{ | { | ||||
T norm = (T)length(q); | |||||
return norm ? q / norm : Quat<T>(T(0)); | |||||
T ret(0); | |||||
for (size_t i = 0; i < sizeof(t1) / sizeof(T); ++i) | |||||
ret += t1[i] * t2[i]; | |||||
return ret; | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline Quat<T> operator /(T x, Quat<T> const &y) | |||||
static inline T sqlength(quat_t<T> const &t) | |||||
{ | { | ||||
return x * re(y); | |||||
return dot(t, t); | |||||
} | } | ||||
template<typename T> | template<typename T> | ||||
static inline Quat<T> operator /(Quat<T> const &x, Quat<T> const &y) | |||||
static inline T length(quat_t<T> const &t) | |||||
{ | { | ||||
return x * re(y); | |||||
/* FIXME: this is not very nice */ | |||||
return (T)sqrt((double)sqlength(t)); | |||||
} | |||||
template<typename T> | |||||
static inline T norm(quat_t<T> const &t) | |||||
{ | |||||
return length(t); | |||||
} | |||||
template<typename T> | |||||
static inline quat_t<T> normalize(quat_t<T> const &z) | |||||
{ | |||||
T norm = (T)length(z); | |||||
return norm ? z / norm : quat_t<T>(T(0)); | |||||
} | } | ||||
/* | |||||
* Complex numbers only | |||||
*/ | |||||
template<typename T> | template<typename T> | ||||
extern Quat<T> slerp(Quat<T> const &qa, Quat<T> const &qb, T f); | |||||
static inline cmplx_t<T> re(cmplx_t<T> const &z) | |||||
{ | |||||
return ~z / sqlength(z); | |||||
} | |||||
template<typename T> | |||||
static inline cmplx_t<T> operator /(T a, cmplx_t<T> const &b) | |||||
{ | |||||
return a * re(b); | |||||
} | |||||
template<typename T> | template<typename T> | ||||
inline Quat<T> Quat<T>::operator *(Quat<T> const &val) const | |||||
static inline cmplx_t<T> operator /(cmplx_t<T> a, cmplx_t<T> const &b) | |||||
{ | { | ||||
Quat<T> ret; | |||||
vec<3,T> v1(x, y, z); | |||||
vec<3,T> v2(val.x, val.y, val.z); | |||||
vec<3,T> v3 = cross(v1, v2) + w * v2 + val.w * v1; | |||||
return Quat<T>(w * val.w - dot(v1, v2), v3.x, v3.y, v3.z); | |||||
return a * re(b); | |||||
} | } | ||||
template<typename T> | |||||
static inline bool operator ==(cmplx_t<T> const &a, T b) | |||||
{ | |||||
return (a.x == b) && !a.y; | |||||
} | |||||
template<typename T> | |||||
static inline bool operator !=(cmplx_t<T> const &a, T b) | |||||
{ | |||||
return (a.x != b) || a.y; | |||||
} | |||||
template<typename T> | |||||
static inline bool operator ==(T a, cmplx_t<T> const &b) { return b == a; } | |||||
template<typename T> | |||||
static inline bool operator !=(T a, cmplx_t<T> const &b) { return b != a; } | |||||
/* | |||||
* Quaternions only | |||||
*/ | |||||
template<typename T> | |||||
static inline quat_t<T> re(quat_t<T> const &q) | |||||
{ | |||||
return ~q / sqlength(q); | |||||
} | |||||
template<typename T> | |||||
static inline quat_t<T> operator /(T x, quat_t<T> const &y) | |||||
{ | |||||
return x * re(y); | |||||
} | |||||
template<typename T> | |||||
static inline quat_t<T> operator /(quat_t<T> const &x, quat_t<T> const &y) | |||||
{ | |||||
return x * re(y); | |||||
} | |||||
template<typename T> | |||||
extern quat_t<T> slerp(quat_t<T> const &qa, quat_t<T> const &qb, T f); | |||||
#if !LOL_FEATURE_CXX11_CONSTEXPR | #if !LOL_FEATURE_CXX11_CONSTEXPR | ||||
#undef constexpr | #undef constexpr | ||||
#endif | #endif | ||||
@@ -16,45 +16,45 @@ | |||||
namespace lol { | namespace lol { | ||||
#define LOL_VEC_2_CONST(type, name, a, b) \ | |||||
#define LOL_VEC_2_CONST(T, name, a, b) \ | |||||
template<> \ | template<> \ | ||||
vec<2,type> const vec<2,type>::name = vec<2,type>((type)a, (type)b); | |||||
vec_t<T,2> const vec_t<T,2>::name = vec_t<T,2>((T)a, (T)b); | |||||
#define LOL_VEC_3_CONST(type, name, a, b, c) \ | |||||
#define LOL_VEC_3_CONST(T, name, a, b, c) \ | |||||
template<> \ | template<> \ | ||||
vec<3,type> const vec<3,type>::name = vec<3,type>((type)a, (type)b, (type)c); | |||||
vec_t<T,3> const vec_t<T,3>::name = vec_t<T,3>((T)a, (T)b, (T)c); | |||||
#define LOL_VEC_4_CONST(type, name, a, b, c, d) \ | |||||
#define LOL_VEC_4_CONST(T, name, a, b, c, d) \ | |||||
template<> \ | template<> \ | ||||
vec<4,type> const vec<4,type>::name = vec<4,type>((type)a, (type)b, (type)c, (type)d); | |||||
vec_t<T,4> const vec_t<T,4>::name = vec_t<T,4>((T)a, (T)b, (T)c, (T)d); | |||||
#define LOL_MAT_CONST(type, name, a) \ | |||||
#define LOL_MAT_CONST(T, name, a) \ | |||||
template<> \ | template<> \ | ||||
mat<2,2,type> const mat<2,2,type>::name = mat<2,2,type>((type)a); \ | |||||
mat_t<T,2,2> const mat_t<T,2,2>::name = mat_t<T,2,2>((T)a); \ | |||||
\ | \ | ||||
template<> \ | template<> \ | ||||
mat<3,3,type> const mat<3,3,type>::name = mat<3,3,type>((type)a); \ | |||||
mat_t<T,3,3> const mat_t<T,3,3>::name = mat_t<T,3,3>((T)a); \ | |||||
\ | \ | ||||
template<> \ | template<> \ | ||||
mat<4,4,type> const mat<4,4,type>::name = mat<4,4,type>((type)a); | |||||
mat_t<T,4,4> const mat_t<T,4,4>::name = mat_t<T,4,4>((T)a); | |||||
#define LOL_ALL_CONST_INNER(type) \ | |||||
LOL_VEC_2_CONST(type, zero, 0, 0) \ | |||||
LOL_VEC_2_CONST(type, axis_x, 1, 0) \ | |||||
LOL_VEC_2_CONST(type, axis_y, 0, 1) \ | |||||
#define LOL_ALL_CONST_INNER(T) \ | |||||
LOL_VEC_2_CONST(T, zero, 0, 0) \ | |||||
LOL_VEC_2_CONST(T, axis_x, 1, 0) \ | |||||
LOL_VEC_2_CONST(T, axis_y, 0, 1) \ | |||||
\ | \ | ||||
LOL_VEC_3_CONST(type, zero, 0, 0, 0) \ | |||||
LOL_VEC_3_CONST(type, axis_x, 1, 0, 0) \ | |||||
LOL_VEC_3_CONST(type, axis_y, 0, 1, 0) \ | |||||
LOL_VEC_3_CONST(type, axis_z, 0, 0, 1) \ | |||||
LOL_VEC_3_CONST(T, zero, 0, 0, 0) \ | |||||
LOL_VEC_3_CONST(T, axis_x, 1, 0, 0) \ | |||||
LOL_VEC_3_CONST(T, axis_y, 0, 1, 0) \ | |||||
LOL_VEC_3_CONST(T, axis_z, 0, 0, 1) \ | |||||
\ | \ | ||||
LOL_VEC_4_CONST(type, zero, 0, 0, 0, 0) \ | |||||
LOL_VEC_4_CONST(type, axis_x, 1, 0, 0, 0) \ | |||||
LOL_VEC_4_CONST(type, axis_y, 0, 1, 0, 0) \ | |||||
LOL_VEC_4_CONST(type, axis_z, 0, 0, 1, 0) \ | |||||
LOL_VEC_4_CONST(type, axis_w, 0, 0, 0, 1) \ | |||||
LOL_VEC_4_CONST(T, zero, 0, 0, 0, 0) \ | |||||
LOL_VEC_4_CONST(T, axis_x, 1, 0, 0, 0) \ | |||||
LOL_VEC_4_CONST(T, axis_y, 0, 1, 0, 0) \ | |||||
LOL_VEC_4_CONST(T, axis_z, 0, 0, 1, 0) \ | |||||
LOL_VEC_4_CONST(T, axis_w, 0, 0, 0, 1) \ | |||||
\ | \ | ||||
LOL_MAT_CONST(type, identity, 1) | |||||
LOL_MAT_CONST(T, identity, 1) | |||||
LOL_ALL_CONST_INNER(half) | LOL_ALL_CONST_INNER(half) | ||||
LOL_ALL_CONST_INNER(float) | LOL_ALL_CONST_INNER(float) | ||||
@@ -378,7 +378,7 @@ template<> mat3 mat3::rotate(float degrees, vec3 v) | |||||
return rotate(degrees, v.x, v.y, v.z); | return rotate(degrees, v.x, v.y, v.z); | ||||
} | } | ||||
template<> mat3::mat(quat const &q) | |||||
template<> mat3::mat_t(quat const &q) | |||||
{ | { | ||||
float n = norm(q); | float n = norm(q); | ||||
@@ -405,7 +405,7 @@ template<> mat3::mat(quat const &q) | |||||
(*this)[2][2] = 1.0f - s * (q.x * q.x + q.y * q.y); | (*this)[2][2] = 1.0f - s * (q.x * q.x + q.y * q.y); | ||||
} | } | ||||
template<> mat4::mat(quat const &q) | |||||
template<> mat4::mat_t(quat const &q) | |||||
{ | { | ||||
*this = mat4(mat3(q), 1.f); | *this = mat4(mat3(q), 1.f); | ||||
} | } | ||||
@@ -448,12 +448,12 @@ static inline void MatrixToQuat(quat &that, mat3 const &m) | |||||
} | } | ||||
} | } | ||||
template<> quat::Quat(mat3 const &m) | |||||
template<> quat::quat_t(mat3 const &m) | |||||
{ | { | ||||
MatrixToQuat(*this, m); | MatrixToQuat(*this, m); | ||||
} | } | ||||
template<> quat::Quat(mat4 const &m) | |||||
template<> quat::quat_t(mat4 const &m) | |||||
{ | { | ||||
MatrixToQuat(*this, mat3(m)); | MatrixToQuat(*this, mat3(m)); | ||||
} | } | ||||
@@ -166,7 +166,7 @@ void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol | |||||
{ | { | ||||
mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world[3].xyz); | mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world[3].xyz); | ||||
mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world)); | mat4 ThisMatrixRot = NewMatrixRot * inverse(PreviousMatrixRot) * lol::mat4(lol::quat(m_local_to_world)); | ||||
SetTransform(ThisMatrixLoc[3].xyz, lol::mat4(lol::quat(ThisMatrixRot))); | |||||
SetTransform(ThisMatrixLoc[3].xyz, lol::quat(ThisMatrixRot)); | |||||
} | } | ||||
} | } | ||||