Parcourir la source

math: refactor more shit, I have no idea what I’m doing.

undefined
Sam Hocevar il y a 10 ans
Parent
révision
4f28047fc4
8 fichiers modifiés avec 1137 ajouts et 1118 suppressions
  1. +26
    -27
      src/lol/base/types.h
  2. +16
    -16
      src/lol/math/geometry.h
  3. +198
    -198
      src/lol/math/matrix.h
  4. +192
    -175
      src/lol/math/transform.h
  5. +676
    -673
      src/lol/math/vector.h
  6. +24
    -24
      src/math/constants.cpp
  7. +4
    -4
      src/math/vector.cpp
  8. +1
    -1
      test/physics/easyphysics.cpp

+ 26
- 27
src/lol/base/types.h Voir le fichier

@@ -16,10 +16,7 @@
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;

/* The “real” type used for real numbers. It’s a specialisation of the
@@ -31,22 +28,23 @@ typedef Real<16> real;
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 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
*/

#define LOL_VECTOR_TYPEDEFS(tleft, tright, suffix) \
#define _T(tleft, tright, suffix) \
typedef tleft half tright f16##suffix; \
typedef tleft float tright suffix; \
typedef tleft double tright d##suffix; \
@@ -62,28 +60,29 @@ template<typename T> struct Quat;
typedef tleft real tright r##suffix;

/* 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


+ 16
- 16
src/lol/math/geometry.h Voir le fichier

@@ -49,7 +49,7 @@ template <typename T> struct Box2
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),
B(b)
{}
@@ -59,32 +59,32 @@ template <typename T> struct Box2
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);
}

Box2<T> &operator +=(vec<2,T> const &v)
Box2<T> &operator +=(vec_t<T,2> const &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);
}

Box2<T> &operator -=(vec<2,T> const &v)
Box2<T> &operator -=(vec_t<T,2> const &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);
}

Box2<T> &operator *=(vec<2,T> const &v)
Box2<T> &operator *=(vec_t<T,2> const &v)
{
return *this = *this * v;
}
@@ -99,7 +99,7 @@ template <typename T> struct Box2
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))
{}

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),
B(b)
{}
@@ -124,32 +124,32 @@ template <typename T> struct Box3
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);
}

Box3<T> &operator +=(vec<3,T> const &v)
Box3<T> &operator +=(vec_t<T,3> const &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);
}

Box3<T> &operator -=(vec<3,T> const &v)
Box3<T> &operator -=(vec_t<T,3> const &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);
}

Box3<T> &operator *=(vec<3,T> const &v)
Box3<T> &operator *=(vec_t<T,3> const &v)
{
return *this = *this * v;
}
@@ -164,7 +164,7 @@ template <typename T> struct Box3
return A != box.A || B != box.B;
}

vec<3,T> A, B;
vec_t<T,3> A, B;
};

/*


+ 198
- 198
src/lol/math/matrix.h Voir le fichier

@@ -29,17 +29,17 @@ namespace lol
#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);
for (int i = 0; i < COLS; ++i)
@@ -47,11 +47,11 @@ struct mat
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:
vec<ROWS,T> m_data[COLS];
vec_t<T,ROWS> m_data[COLS];
};

/*
@@ -59,28 +59,28 @@ private:
*/

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
: m_data{ v0, v1 } {}
#else
: m_v0(v0), m_v1(v1) {}
#endif

explicit inline mat(T const &val)
explicit inline mat_t(T const &val)
#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
: m_v0(val, T(0)),
m_v1(T(0), val) {}
#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
: m_data{ m[0].xy, m[1].xy } {}
#else
@@ -88,16 +88,16 @@ struct mat<2, 2, T>
#endif

#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
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

/* 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;
}
@@ -107,15 +107,15 @@ struct mat<2, 2, T>

template<class U>
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:
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS
vec<2,T> m_data[2];
vec_t<T,2> m_data[2];
#else
vec<2,T> m_v0, m_v1;
vec_t<T,2> m_v0, m_v1;
#endif
};

@@ -124,91 +124,91 @@ private:
*/

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
: m_data{ v0, v1, v2 } {}
#else
: m_v0(v0), m_v1(v1), m_v2(v2) {}
#endif

explicit inline mat(T const &val)
explicit inline mat_t(T const &val)
#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
: m_v0(val, (T)0, (T)0),
m_v1((T)0, val, (T)0),
m_v2((T)0, (T)0, val) {}
#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
: 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
: m_v0(m[0], (T)0),
m_v1(m[1], (T)0),
m_v2((T)0, (T)0, val) {}
#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
: m_data{ m[0].xyz, m[1].xyz, m[2].xyz } {}
#else
: m_v0(m[0].xyz), m_v1(m[1].xyz), m_v2(m[2].xyz) {}
#endif

explicit mat(Quat<T> const &q);
explicit mat_t(quat_t<T> const &q);

#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
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

/* 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;
}
@@ -218,15 +218,15 @@ struct mat<3,3,T>

template<class U>
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:
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS
vec<3,T> m_data[3];
vec_t<T,3> m_data[3];
#else
vec<3,T> m_v0, m_v1, m_v2;
vec_t<T,3> m_v0, m_v1, m_v2;
#endif
};

@@ -235,24 +235,24 @@ private:
*/

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
: m_data{ v0, v1, v2, v3 } {}
#else
: m_v0(v0), m_v1(v1), m_v2(v2), m_v3(v3) {}
#endif

explicit inline mat(T const &val)
explicit inline mat_t(T const &val)
#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
: m_v0(val, (T)0, (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) {}
#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
: 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
: m_v0(m[0], (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) {}
#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
: 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
: m_v0(m[0], (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) {}
#endif

explicit mat(Quat<T> const &q);
explicit mat_t(quat_t<T> const &q);

#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
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

/* 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;
}

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;
}

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 */
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 */
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;
String tostring() const;

template<class U>
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:
#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS
vec<4,T> m_data[4];
vec_t<T,4> m_data[4];
#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
};

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 j = 0; j < ROWS; ++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
*/

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)
a[i] += b[i];
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;
}

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;
}

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)
a[i] -= b[i];
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;
}

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)
ret[i] = -m[i];
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
*/

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)
ret += m[i] * v[i];
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)
ret[i] = dot(v, m[i]);
return ret;
@@ -487,19 +487,19 @@ static inline vec<COLS, T> operator *(vec<ROWS, T, MASK> const &v,
* 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)
ret[i] = a * b[i];
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;
}


+ 192
- 175
src/lol/math/transform.h Voir le fichier

@@ -9,8 +9,8 @@
//

//
// The complex and quaternion classes
// ----------------------------------
// The complex, quaternion and dual quaternion classes
// ---------------------------------------------------
//

#if !defined __LOL_MATH_TRANSFORM_H__
@@ -18,9 +18,6 @@

#include <ostream>

#include <lol/math/half.h>
#include <lol/math/real.h>

namespace lol
{

@@ -29,162 +26,114 @@ namespace lol
#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>
explicit inline constexpr Cmplx(Cmplx<U> const &z)
explicit inline constexpr cmplx_t(cmplx_t<U> const &z)
: x(z.x), y(z.y) {}

LOL_COMMON_MEMBER_OPS(x)
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;
}

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>
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;
};

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>
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) {}

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_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. */
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.
* 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
* 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
* 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,
* 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
* the function name (_zyx instead of _xyz) AND reverse the order
* 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);
}

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);
}

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);
if (n2 <= (T)1e-6)
return vec<3,T>::axis_x;
return vec_t<T,3>::axis_x;
return normalize(v);
}

inline T angle()
{
vec<3,T> v(x, y, z);
vec_t<T,3> v(x, y, z);
T n2 = sqlength(v);
if (n2 <= (T)1e-6)
return (T)0;
@@ -262,78 +204,153 @@ template <typename T> struct Quat
}

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! */
T w, x, y, z;
};

/*
* Common operations on transforms
*/

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);
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;
}

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>
static inline T length(Quat<T> const &q)
static inline T length(cmplx_t<T> const &t)
{
/* FIXME: this is not very nice */
return (T)sqrt((double)sqlength(q));
return (T)sqrt((double)sqlength(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>
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>
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>
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>
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>
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>
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
#undef constexpr
#endif


+ 676
- 673
src/lol/math/vector.h
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 24
- 24
src/math/constants.cpp Voir le fichier

@@ -16,45 +16,45 @@

namespace lol {

#define LOL_VEC_2_CONST(type, name, a, b) \
#define LOL_VEC_2_CONST(T, name, a, b) \
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<> \
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<> \
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<> \
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<> \
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<> \
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(float)


+ 4
- 4
src/math/vector.cpp Voir le fichier

@@ -378,7 +378,7 @@ template<> mat3 mat3::rotate(float degrees, vec3 v)
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);

@@ -405,7 +405,7 @@ template<> mat3::mat(quat const &q)
(*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);
}
@@ -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);
}

template<> quat::Quat(mat4 const &m)
template<> quat::quat_t(mat4 const &m)
{
MatrixToQuat(*this, mat3(m));
}


+ 1
- 1
test/physics/easyphysics.cpp Voir le fichier

@@ -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 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));
}
}



Chargement…
Annuler
Enregistrer