From 7a28671deeadee7fae66563780261cf6ee3e9459 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 3 Jul 2014 18:11:18 +0000 Subject: [PATCH] math: get rid of the base_vec* classes (thanks to relaxed unions), rename MASK to SWIZZLE in the vector templates, rename matrix<> to mat<> for consistency, implement transposition for all matrix sizes, make matrix columns private and only accessible through operator[]. --- src/easymesh/easymesh.cpp | 10 +- src/lol/base/features.h | 5 + src/lol/base/types.h | 18 +- src/lol/math/matrix.h | 249 ++++++++---- src/lol/math/vector.h | 471 ++++++++++------------- src/math/vector.cpp | 115 +++--- test/btphystest.cpp | 24 +- test/meshviewer.cpp | 16 +- test/physics/easycharactercontroller.cpp | 6 +- test/physics/easyconstraint.h | 18 +- test/physics/easyphysics.cpp | 10 +- tools/lolremez/matrix.h | 27 +- tools/lolremez/solver.cpp | 22 +- tools/vimlol/vimlol.vim | 2 +- 14 files changed, 513 insertions(+), 480 deletions(-) diff --git a/src/easymesh/easymesh.cpp b/src/easymesh/easymesh.cpp index d85bace7..d2569903 100644 --- a/src/easymesh/easymesh.cpp +++ b/src/easymesh/easymesh.cpp @@ -1449,15 +1449,15 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) /* Fill in the icosahedron vertices, rotating them so that there * is a vertex at [0 1 0] and [0 -1 0] after normalisation. */ float phi = 0.5f + 0.5f * sqrt(5.f); - mat3 mat = mat3::rotate(degrees(asin(1.f / sqrt(2.f + phi))), - vec3(0.f, 0.f, 1.f)); + mat3 m = mat3::rotate(degrees(asin(1.f / sqrt(2.f + phi))), + vec3(0.f, 0.f, 1.f)); for (int i = 0; i < 4; i++) { float x = (i & 1) ? 0.5f : -0.5f; float y = (i & 2) ? phi * 0.5f : phi * -0.5f; - vertices << mat * vec3(x, y, 0.f); - vertices << mat * vec3(0.f, x, y); - vertices << mat * vec3(y, 0.f, x); + vertices << m * vec3(x, y, 0.f); + vertices << m * vec3(0.f, x, y); + vertices << m * vec3(y, 0.f, x); } static int const trilist[] = diff --git a/src/lol/base/features.h b/src/lol/base/features.h index 3e7c770f..58cf315a 100644 --- a/src/lol/base/features.h +++ b/src/lol/base/features.h @@ -42,6 +42,7 @@ * (planned for Visual Studion 14) */ #define LOL_FEATURE_CXX11_RELAXED_UNIONS 0 #define LOL_FEATURE_CXX11_INHERIT_CONSTRUCTORS 0 +#define LOL_FEATURE_CXX11_ARRAY_INITIALIZERS 0 #define LOL_FEATURE_CXX11_CONSTEXPR 0 #define LOL_FEATURE_CXX11_ISNAN 0 @@ -54,6 +55,8 @@ # define LOL_FEATURE_CXX11_CONSTEXPR 1 # undef LOL_FEATURE_CXX11_ISNAN # define LOL_FEATURE_CXX11_ISNAN 1 +# undef LOL_FEATURE_CXX11_ARRAY_INITIALIZERS +# define LOL_FEATURE_CXX11_ARRAY_INITIALIZERS 1 # endif # if (__GNUC__ * 100 + __GNUC_MINOR__) < 470 # undef LOL_FEATURE_CXX11_TEMPLATE_ALIASES @@ -64,6 +67,8 @@ # undef LOL_FEATURE_CXX11_CONSTEXPR # define LOL_FEATURE_CXX11_CONSTEXPR 1 # endif +# undef LOL_FEATURE_CXX11_ARRAY_INITIALIZERS +# define LOL_FEATURE_CXX11_ARRAY_INITIALIZERS 1 #endif diff --git a/src/lol/base/types.h b/src/lol/base/types.h index 0d932487..687ec775 100644 --- a/src/lol/base/types.h +++ b/src/lol/base/types.h @@ -34,7 +34,10 @@ class half; * Forward declaration of vec and matrix */ -template struct vec; +int const FULL_SWIZZLE = 0xaaaa; +int const NO_SWIZZLE = 0xbbbb; + +template struct vec; template struct matrix; template struct Cmplx; template struct Quat; @@ -99,6 +102,19 @@ typedef mat3x4 float3x4; typedef mat4x2 float4x2; typedef mat4x3 float4x3; +typedef f16vec2 half2; +typedef f16vec3 half3; +typedef f16vec4 half4; +typedef f16mat2 half2x2; +typedef f16mat3 half3x3; +typedef f16mat4 half4x4; +typedef f16mat2x3 half2x3; +typedef f16mat2x4 half2x4; +typedef f16mat3x2 half3x2; +typedef f16mat3x4 half3x4; +typedef f16mat4x2 half4x2; +typedef f16mat4x3 half4x3; + typedef ivec2 int2; typedef ivec3 int3; typedef ivec4 int4; diff --git a/src/lol/math/matrix.h b/src/lol/math/matrix.h index bb2b5c8f..ff66dc2e 100644 --- a/src/lol/math/matrix.h +++ b/src/lol/math/matrix.h @@ -28,7 +28,10 @@ namespace lol # define constexpr /* */ #endif -/* The generic "matrix" type, which is a fixed-size matrix */ +/* + * The generic "matrix" type, which is fixed-size + */ + template struct matrix { @@ -61,25 +64,42 @@ struct matrix<2, 2, T> typedef matrix<2,2,T> type; inline matrix() {} - inline matrix(vec<2,T> V0, vec<2,T> V1) - : v0(V0), v1(V1) {} + inline matrix(vec<2,T> v0, vec<2,T> v1) +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + : m_data{ v0, v1 } {} +#else + : m_v0(v0), m_v1(v1) {} +#endif explicit inline matrix(T const &val) - : v0(val, (T)0), - v1((T)0, val) {} +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + : m_data{ vec<2,T>(val, T(0)), + vec<2,T>(T(0), val) } {} +#else + : m_v0(val, T(0)), + m_v1(T(0), val) {} +#endif - explicit inline matrix(matrix<4,4,T> const &mat) - : v0(mat[0].xy), - v1(mat[1].xy) {} + explicit inline matrix(matrix<4,4,T> const &m) +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + : m_data{ m[0].xy, m[1].xy } {} +#else + : m_v0(m[0].xy), m_v1(m[1].xy) {} +#endif - inline vec<2,T>& operator[](size_t n) { return (&v0)[n]; } - inline vec<2,T> const& operator[](size_t n) const { return (&v0)[n]; } +#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]; } +#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]; } +#endif /* Helpers for transformation matrices */ static matrix<2,2,T> rotate(T degrees); - static inline matrix<2,2,T> rotate(matrix<2,2,T> mat, T degrees) + static inline matrix<2,2,T> rotate(matrix<2,2,T> m, T degrees) { - return rotate(degrees) * mat; + return rotate(degrees) * m; } void printf() const; @@ -89,9 +109,14 @@ struct matrix<2, 2, T> friend std::ostream &operator<<(std::ostream &stream, matrix<2,2,U> const &m); - vec<2,T> v0, v1; - static const matrix<2,2,T> identity; + +private: +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + vec<2,T> m_data[2]; +#else + vec<2,T> m_v0, m_v1; +#endif }; /* @@ -104,33 +129,51 @@ struct matrix<3,3,T> typedef matrix<3,3,T> type; inline matrix() {} - inline matrix(vec<3,T> V0, vec<3,T> V1, vec<3,T> V2) - : v0(V0), v1(V1), v2(V2) {} + inline matrix(vec<3,T> v0, vec<3,T> v1, vec<3,T> 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 matrix(T const &val) - : v0(val, (T)0, (T)0), - v1((T)0, val, (T)0), - v2((T)0, (T)0, val) {} - - explicit inline matrix(matrix<2,2,T> mat) - : v0(mat[0], (T)0), - v1(mat[1], (T)0), - v2((T)0, (T)0, (T)0) {} +#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) } {} +#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 matrix(matrix<2,2,T> mat, T const &val) - : v0(vec<3,T>(mat[0], (T)0)), - v1(vec<3,T>(mat[1], (T)0)), - v2((T)0, (T)0, val) {} + explicit inline matrix(matrix<2,2,T> 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) } {} +#else + : m_v0(m[0], (T)0), + m_v1(m[1], (T)0), + m_v2((T)0, (T)0, val) {} +#endif - explicit inline matrix(matrix<4,4,T> const &mat) - : v0(mat[0].xyz), - v1(mat[1].xyz), - v2(mat[2].xyz) {} + explicit inline matrix(matrix<4,4,T> 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 matrix(Quat const &q); - inline vec<3,T>& operator[](size_t n) { return (&v0)[n]; } - inline vec<3,T> const& operator[](size_t n) const { return (&v0)[n]; } +#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]; } +#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]; } +#endif /* Helpers for transformation matrices */ static matrix<3,3,T> scale(T x); @@ -165,9 +208,9 @@ struct matrix<3,3,T> static matrix<3,3,T> fromeuler_zxz(T phi, T theta, T psi); static matrix<3,3,T> fromeuler_zyz(T phi, T theta, T psi); - static inline matrix<3,3,T> rotate(matrix<3,3,T> mat, T degrees, vec<3,T> v) + static inline matrix<3,3,T> rotate(matrix<3,3,T> m, T degrees, vec<3,T> v) { - return rotate(degrees, v) * mat; + return rotate(degrees, v) * m; } void printf() const; @@ -177,9 +220,14 @@ struct matrix<3,3,T> friend std::ostream &operator<<(std::ostream &stream, matrix<3,3,U> const &m); - vec<3,T> v0, v1, v2; - static const matrix<3,3,T> identity; + +private: +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + vec<3,T> m_data[3]; +#else + vec<3,T> m_v0, m_v1, m_v2; +#endif }; /* @@ -192,43 +240,61 @@ struct matrix<4, 4, T> typedef matrix<4,4,T> type; inline matrix() {} - inline matrix(vec<4,T> V0, vec<4,T> V1, vec<4,T> V2, vec<4,T> V3) - : v0(V0), v1(V1), v2(V2), v3(V3) {} + inline matrix(vec<4,T> v0, vec<4,T> v1, vec<4,T> v2, vec<4,T> 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 matrix(T const &val) - : v0(val, (T)0, (T)0, (T)0), - v1((T)0, val, (T)0, (T)0), - v2((T)0, (T)0, val, (T)0), - v3((T)0, (T)0, (T)0, val) {} - - explicit inline matrix(matrix<2,2,T> mat) - : v0(mat[0], (T)0, (T)0), - v1(mat[1], (T)0, (T)0), - v2((T)0, (T)0, (T)0, (T)0), - v3((T)0, (T)0, (T)0, (T)0) {} - - explicit inline matrix(matrix<2,2,T> mat, T const &val1, T const &val2) - : v0(mat[0], (T)0, (T)0), - v1(mat[1], (T)0, (T)0), - v2((T)0, (T)0, val1, (T)0), - v3((T)0, (T)0, (T)0, val2) {} - - explicit inline matrix(matrix<3,3,T> mat) - : v0(mat[0], (T)0), - v1(mat[1], (T)0), - v2(mat[2], (T)0), - v3((T)0, (T)0, (T)0, (T)0) {} - - explicit inline matrix(matrix<3,3,T> mat, T const &val) - : v0(mat[0], (T)0), - v1(mat[1], (T)0), - v2(mat[2], (T)0), - v3((T)0, (T)0, (T)0, 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) } {} +#else + : m_v0(val, (T)0, (T)0, (T)0), + m_v1((T)0, val, (T)0, (T)0), + m_v2((T)0, (T)0, val, (T)0), + m_v3((T)0, (T)0, (T)0, val) {} +#endif + + explicit inline matrix(matrix<2,2,T> 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) } {} +#else + : m_v0(m[0], (T)0, (T)0), + m_v1(m[1], (T)0, (T)0), + m_v2((T)0, (T)0, val, (T)0), + m_v3((T)0, (T)0, (T)0, val) {} +#endif + + explicit inline matrix(matrix<3,3,T> 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) } {} +#else + : m_v0(m[0], (T)0), + m_v1(m[1], (T)0), + m_v2(m[2], (T)0), + m_v3((T)0, (T)0, (T)0, val) {} +#endif explicit matrix(Quat const &q); - inline vec<4,T>& operator[](size_t n) { return (&v0)[n]; } - inline vec<4,T> const& operator[](size_t n) const { return (&v0)[n]; } +#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]; } +#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]; } +#endif /* Helpers for transformation matrices */ static matrix<4,4,T> translate(T x, T y, T z); @@ -249,9 +315,9 @@ struct matrix<4, 4, T> return matrix<4,4,T>(matrix<3,3,T>::scale(v), (T)1); } - static inline matrix<4,4,T> translate(matrix<4,4,T> const &mat, vec<3,T> v) + static inline matrix<4,4,T> translate(matrix<4,4,T> const &m, vec<3,T> v) { - return translate(v) * mat; + return translate(v) * m; } static inline matrix<4,4,T> rotate(T degrees, T x, T y, T z) @@ -264,9 +330,9 @@ struct matrix<4, 4, T> return matrix<4,4,T>(matrix<3,3,T>::rotate(degrees, v), (T)1); } - static inline matrix<4,4,T> rotate(matrix<4,4,T> &mat, T degrees, vec<3,T> v) + static inline matrix<4,4,T> rotate(matrix<4,4,T> &m, T degrees, vec<3,T> v) { - return rotate(degrees, v) * mat; + return rotate(degrees, v) * m; } static matrix<4,4,T> fromeuler_xyz(vec<3,T> const &v); @@ -312,23 +378,34 @@ struct matrix<4, 4, T> friend std::ostream &operator<<(std::ostream &stream, matrix<4,4,U> const &m); - vec<4,T> v0, v1, v2, v3; - static const matrix<4,4,T> identity; + +private: +#if LOL_FEATURE_CXX11_ARRAY_INITIALIZERS + vec<4,T> m_data[4]; +#else + vec<4,T> m_v0, m_v1, m_v2, m_v3; +#endif }; template T determinant(matrix<2,2,T> const &); template T determinant(matrix<3,3,T> const &); template T determinant(matrix<4,4,T> const &); -template matrix<2,2,T> transpose(matrix<2,2,T> const &); -template matrix<3,3,T> transpose(matrix<3,3,T> const &); -template matrix<4,4,T> transpose(matrix<4,4,T> const &); - template matrix<2,2,T> inverse(matrix<2,2,T> const &); template matrix<3,3,T> inverse(matrix<3,3,T> const &); template matrix<4,4,T> inverse(matrix<4,4,T> const &); +template +static inline matrix transpose(matrix const &m) +{ + matrix ret; + for (int i = 0; i < COLS; ++i) + for (int j = 0; j < ROWS; ++j) + ret[j][i] = m[i][j]; + return ret; +} + /* * Addition/subtraction/unary */ @@ -383,7 +460,7 @@ static inline matrix operator -(matrix const &m) } /* - * Matrix-vector multiplication + * Matrix-vector and vector-matrix multiplication */ template @@ -396,6 +473,16 @@ static inline vec operator *(matrix const &m, return ret; } +template +static inline vec operator *(vec const &v, + matrix const &m) +{ + vec ret(T(0)); + for (int i = 0; i < COLS; ++i) + ret[i] = dot(v, m[i]); + return ret; +} + /* * Matrix-matrix multiplication */ diff --git a/src/lol/math/vector.h b/src/lol/math/vector.h index dfdce022..a70609cd 100644 --- a/src/lol/math/vector.h +++ b/src/lol/math/vector.h @@ -48,15 +48,15 @@ namespace lol * fuck it. */ -template +template struct vec { typedef vec type; - inline vec& operator =(vec that); + inline vec& operator =(vec that); #if LOL_FEATURE_CXX11_RELAXED_UNIONS - inline vec& operator =(vec const &that) + inline vec& operator =(vec const &that) { /* Pass by value in case this == &that */ return *this = (vec)that; @@ -65,18 +65,19 @@ struct vec inline T& operator[](size_t n) { - int i = (MASK >> (4 * (N - 1 - n))) & 3; + int i = (SWIZZLE >> (4 * (N - 1 - n))) & 3; return static_cast(static_cast(this))[i]; } inline T const& operator[](size_t n) const { - int i = (MASK >> (4 * (N - 1 - n))) & 3; + int i = (SWIZZLE >> (4 * (N - 1 - n))) & 3; return static_cast(static_cast(this))[i]; } }; -/* The generic "vec" type, which is a fixed-size vector */ +/* The generic "vec" type, which is a fixed-size vector with no + * swizzling. There's an override for N=2, N=3, N=4 that has swizzling. */ template struct vec { @@ -218,10 +219,41 @@ private: * 2-element vectors */ -template struct base_vec2 +template +struct vec<2,T> { - explicit inline constexpr base_vec2() {} - explicit inline constexpr base_vec2(T X, T Y) : x(X), y(Y) {} + typedef vec<2,T> type; + + /* Default constructor, copy constructor, and destructor */ + inline constexpr vec() : x(), y() {} + inline constexpr vec(vec<2,T> const &v) : x(v.x), y(v.y) {} + inline ~vec() { x.~T(); y.~T(); } + + /* Implicit constructor for swizzling */ + template + inline constexpr vec(vec<2, T, SWIZZLE> const &v) + : x(v[0]), y(v[1]) {} + + /* Explicit constructor for type conversion */ + template + explicit inline constexpr vec(vec<2, U, SWIZZLE> const &v) + : x(v[0]), y(v[1]) {} + + /* Various explicit constructors */ + explicit inline constexpr vec(T X, T Y) + : x(X), y(Y) {} + explicit inline constexpr vec(T X) + : x(X), y(X) {} + + LOL_COMMON_MEMBER_OPS(x) + LOL_VECTOR_MEMBER_OPS() + + static const vec<2,T> zero; + static const vec<2,T> axis_x; + static const vec<2,T> axis_y; + + template + friend std::ostream &operator<<(std::ostream &stream, vec<2,U> const &v); union { @@ -264,59 +296,86 @@ template struct base_vec2 }; }; -template <> struct base_vec2 -{ - explicit inline base_vec2() {} - explicit inline base_vec2(half X, half Y) : x(X), y(Y) {} - - half x, y; -}; - -template <> struct base_vec2 -{ - explicit inline base_vec2() {} - explicit inline base_vec2(real X, real Y) : x(X), y(Y) {} - - real x, y; -}; +/* + * 3-element vectors + */ template -struct vec<2,T> : base_vec2 +struct vec<3,T> { - typedef vec<2,T> type; + typedef vec<3,T> type; - inline constexpr vec() {} - inline constexpr vec(T X, T Y) : base_vec2(X, Y) {} + /* Default constructor, copy constructor, and destructor */ + inline constexpr vec() : x(), y(), z() {} + inline constexpr vec(vec<3,T> const &v) : x(v.x), y(v.y), z(v.z) {} + inline ~vec() { x.~T(); y.~T(); z.~T(); } + + /* Implicit constructor for swizzling */ + template + inline constexpr vec(vec<3, T, SWIZZLE> const &v) + : x(v[0]), y(v[1]), z(v[2]) {} + + /* Explicit constructor for type conversion */ + template + explicit inline constexpr vec(vec<3, U, SWIZZLE> const &v) + : x(v[0]), y(v[1]), z(v[2]) {} + + /* Various explicit constructors */ + explicit inline constexpr vec(T X) + : x(X), y(X), z(X) {} + explicit inline constexpr vec(T X, T Y, T Z) + : x(X), y(Y), z(Z) {} + explicit inline constexpr vec(vec<2,T> XY, T Z) + : x(XY.x), y(XY.y), z(Z) {} + explicit inline constexpr vec(T X, vec<2,T> YZ) + : x(X), y(YZ.x), z(YZ.y) {} - explicit inline constexpr vec(T X) : base_vec2(X, X) {} + LOL_COMMON_MEMBER_OPS(x) + LOL_VECTOR_MEMBER_OPS() - template - inline constexpr vec(vec<2, T, MASK> const &v) - : base_vec2(v[0], v[1]) {} + static vec<3,T> toeuler_xyx(Quat const &q); + static vec<3,T> toeuler_xzx(Quat const &q); + static vec<3,T> toeuler_yxy(Quat const &q); + static vec<3,T> toeuler_yzy(Quat const &q); + static vec<3,T> toeuler_zxz(Quat const &q); + static vec<3,T> toeuler_zyz(Quat const &q); - template - explicit inline constexpr vec(vec<2, U, MASK> const &v) - : base_vec2(v[0], v[1]) {} + static vec<3,T> toeuler_xyz(Quat const &q); + static vec<3,T> toeuler_xzy(Quat const &q); + static vec<3,T> toeuler_yxz(Quat const &q); + static vec<3,T> toeuler_yzx(Quat const &q); + static vec<3,T> toeuler_zxy(Quat const &q); + static vec<3,T> toeuler_zyx(Quat const &q); - LOL_COMMON_MEMBER_OPS(x) - LOL_VECTOR_MEMBER_OPS() + /* Return the cross product (vector product) of "a" and "b" */ \ + friend inline type cross(type const &a, type const &b) + { + return type(a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x); + } - static const vec<2,T> zero; - static const vec<2,T> axis_x; - static const vec<2,T> axis_y; + /* Return a vector that is orthogonal to "a" */ + friend inline type orthogonal(type const &a) + { + return lol::abs(a.x) > lol::abs(a.z) + ? type(-a.y, a.x, (T)0) + : type((T)0, -a.z, a.y); + } - template - friend std::ostream &operator<<(std::ostream &stream, vec<2,U> const &v); -}; + /* Return a vector that is orthonormal to "a" */ + friend inline type orthonormal(type const &a) + { + return normalize(orthogonal(a)); + } -/* - * 3-element vectors - */ + static const vec<3,T> zero; + static const vec<3,T> axis_x; + static const vec<3,T> axis_y; + static const vec<3,T> axis_z; -template struct base_vec3 -{ - explicit inline constexpr base_vec3() {} - explicit inline constexpr base_vec3(T X, T Y, T Z) : x(X), y(Y), z(Z) {} + template + friend std::ostream &operator<<(std::ostream &stream, vec<3,U> const &v); union { @@ -448,100 +507,59 @@ template struct base_vec3 }; }; -template <> struct base_vec3 -{ - explicit inline base_vec3() {} - explicit inline base_vec3(half X, half Y, half Z) - : x(X), y(Y), z(Z) {} - - half x, y, z; -}; - -template <> struct base_vec3 -{ - explicit inline base_vec3() {} - explicit inline base_vec3(real X, real Y, real Z) : x(X), y(Y), z(Z) {} - - real x, y, z; -}; +/* + * 4-element vectors + */ template -struct vec<3,T> : base_vec3 +struct vec<4,T> { - typedef vec<3,T> type; - - inline constexpr vec() {} - inline constexpr vec(T X, T Y, T Z) : base_vec3(X, Y, Z) {} - inline constexpr vec(vec<2,T> XY, T Z) : base_vec3(XY.x, XY.y, Z) {} - inline constexpr vec(T X, vec<2,T> YZ) : base_vec3(X, YZ.x, YZ.y) {} - - explicit inline constexpr vec(T X) : base_vec3(X, X, X) {} - - template - inline constexpr vec(vec<3, T, MASK> const &v) - : base_vec3(v[0], v[1], v[2]) {} + typedef vec<4,T> type; - template - explicit inline constexpr vec(vec<3, U, MASK> const &v) - : base_vec3(v[0], v[1], v[2]) {} + /* Default constructor, copy constructor, and destructor */ + inline constexpr vec() : x(), y(), z(), w() {} + inline constexpr vec(vec<4,T> const &v) : x(v.x), y(v.y), z(v.z), w(v.w) {} + inline ~vec() { x.~T(); y.~T(); z.~T(); w.~T(); } + + /* Implicit constructor for swizzling */ + template + inline constexpr vec(vec<4, T, SWIZZLE> const &v) + : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {} + + /* Explicit constructor for type conversion */ + template + explicit inline constexpr vec(vec<4, U, SWIZZLE> const &v) + : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {} + + /* Various explicit constructors */ + explicit inline constexpr vec(T X) + : x(X), y(X), z(X), w(X) {} + explicit inline constexpr vec(T X, T Y, T Z, T W) + : x(X), y(Y), z(Z), w(W) {} + explicit inline constexpr vec(vec<2,T> XY, T Z, T W) + : x(XY.x), y(XY.y), z(Z), w(W) {} + explicit inline constexpr vec(T X, vec<2,T> YZ, T W) + : x(X), y(YZ.x), z(YZ.y), w(W) {} + explicit inline constexpr vec(T X, T Y, vec<2,T> ZW) + : x(X), y(Y), z(ZW.x), w(ZW.y) {} + explicit inline constexpr vec(vec<2,T> XY, vec<2,T> ZW) + : x(XY.x), y(XY.y), z(ZW.x), w(ZW.y) {} + explicit inline constexpr vec(vec<3,T> XYZ, T W) + : x(XYZ.x), y(XYZ.y), z(XYZ.z), w(W) {} + explicit inline constexpr vec(T X, vec<3,T> YZW) + : x(X), y(YZW.x), z(YZW.y), w(YZW.z) {} LOL_COMMON_MEMBER_OPS(x) LOL_VECTOR_MEMBER_OPS() - static vec<3,T> toeuler_xyx(Quat const &q); - static vec<3,T> toeuler_xzx(Quat const &q); - static vec<3,T> toeuler_yxy(Quat const &q); - static vec<3,T> toeuler_yzy(Quat const &q); - static vec<3,T> toeuler_zxz(Quat const &q); - static vec<3,T> toeuler_zyz(Quat const &q); - - static vec<3,T> toeuler_xyz(Quat const &q); - static vec<3,T> toeuler_xzy(Quat const &q); - static vec<3,T> toeuler_yxz(Quat const &q); - static vec<3,T> toeuler_yzx(Quat const &q); - static vec<3,T> toeuler_zxy(Quat const &q); - static vec<3,T> toeuler_zyx(Quat const &q); - - /* Return the cross product (vector product) of "a" and "b" */ \ - friend inline type cross(type const &a, type const &b) - { - return type(a.y * b.z - a.z * b.y, - a.z * b.x - a.x * b.z, - a.x * b.y - a.y * b.x); - } - - /* Return a vector that is orthogonal to "a" */ - friend inline type orthogonal(type const &a) - { - return lol::abs(a.x) > lol::abs(a.z) - ? type(-a.y, a.x, (T)0) - : type((T)0, -a.z, a.y); - } - - /* Return a vector that is orthonormal to "a" */ - friend inline type orthonormal(type const &a) - { - return normalize(orthogonal(a)); - } - - static const vec<3,T> zero; - static const vec<3,T> axis_x; - static const vec<3,T> axis_y; - static const vec<3,T> axis_z; + static const vec<4,T> zero; + static const vec<4,T> axis_x; + static const vec<4,T> axis_y; + static const vec<4,T> axis_z; + static const vec<4,T> axis_w; template - friend std::ostream &operator<<(std::ostream &stream, vec<3,U> const &v); -}; - -/* - * 4-element vectors - */ - -template struct base_vec4 -{ - explicit inline constexpr base_vec4() {} - explicit inline constexpr base_vec4(T X, T Y, T Z, T W) - : x(X), y(Y), z(Z), w(W) {} + friend std::ostream &operator<<(std::ostream &stream, vec<4,U> const &v); union { @@ -892,77 +910,15 @@ template struct base_vec4 }; }; -template <> struct base_vec4 -{ - explicit inline base_vec4() {} - explicit inline base_vec4(half X, half Y, half Z, half W) - : x(X), y(Y), z(Z), w(W) {} - - half x, y, z, w; -}; - -template <> struct base_vec4 -{ - explicit inline base_vec4() {} - explicit inline base_vec4(real X, real Y, real Z, real W) - : x(X), y(Y), z(Z), w(W) {} - - real x, y, z, w; -}; - -template -struct vec<4,T> : base_vec4 -{ - typedef vec<4,T> type; - - inline constexpr vec() {} - inline constexpr vec(T X, T Y, T Z, T W) - : base_vec4(X, Y, Z, W) {} - inline constexpr vec(vec<2,T> XY, T Z, T W) - : base_vec4(XY.x, XY.y, Z, W) {} - inline constexpr vec(T X, vec<2,T> YZ, T W) - : base_vec4(X, YZ.x, YZ.y, W) {} - inline constexpr vec(T X, T Y, vec<2,T> ZW) - : base_vec4(X, Y, ZW.x, ZW.y) {} - inline constexpr vec(vec<2,T> XY, vec<2,T> ZW) - : base_vec4(XY.x, XY.y, ZW.x, ZW.y) {} - inline constexpr vec(vec<3,T> XYZ, T W) - : base_vec4(XYZ.x, XYZ.y, XYZ.z, W) {} - inline constexpr vec(T X, vec<3,T> YZW) - : base_vec4(X, YZW.x, YZW.y, YZW.z) {} - - explicit inline constexpr vec(T X) : base_vec4(X, X, X, X) {} - - template - inline constexpr vec(vec<4, T, MASK> const &v) - : base_vec4(v[0], v[1], v[2], v[3]) {} - - template - explicit inline constexpr vec(vec<4, U, MASK> const &v) - : base_vec4(v[0], v[1], v[2], v[3]) {} - - LOL_COMMON_MEMBER_OPS(x) - LOL_VECTOR_MEMBER_OPS() - - static const vec<4,T> zero; - static const vec<4,T> axis_x; - static const vec<4,T> axis_y; - static const vec<4,T> axis_z; - static const vec<4,T> axis_w; - - template - friend std::ostream &operator<<(std::ostream &stream, vec<4,U> const &v); -}; - /* * Operators for swizzled vectors. Since template deduction cannot be * done for two arbitrary vec<> values, we help the compiler understand * the expected type. */ -template -static inline bool operator ==(vec const &a, - vec const &b) +template +static inline bool operator ==(vec const &a, + vec const &b) { for (size_t i = 0; i < N; ++i) if (!(a[i] == b[i])) @@ -970,9 +926,9 @@ static inline bool operator ==(vec const &a, return true; } -template -static inline bool operator !=(vec const &a, - vec const &b) +template +static inline bool operator !=(vec const &a, + vec const &b) { for (size_t i = 0; i < N; ++i) if (a[i] != b[i]) @@ -981,15 +937,15 @@ static inline bool operator !=(vec const &a, } #define LOL_SWIZZLE_V_VV_OP(op) \ - template \ - inline vec operator op(vec const &a, \ - vec const &b) \ + template \ + inline vec operator op(vec const &a, \ + vec const &b) \ { \ return vec(a) op vec(b); \ } \ \ - template \ - inline vec operator op(vec a, T const &b) \ + template \ + inline vec operator op(vec a, T const &b) \ { \ return vec(a) op b; \ } @@ -1001,8 +957,8 @@ LOL_SWIZZLE_V_VV_OP(/) #undef LOL_SWIZZLE_V_VV_OP -template -static inline vec operator *(T const &val, vec const &a) +template +static inline vec operator *(T const &val, vec const &a) { vec ret; for (size_t i = 0; i < N; ++i) @@ -1016,8 +972,9 @@ static inline vec operator *(T const &val, vec const &a) */ #define LOL_SWIZZLE_V_VV_FUN(fun) \ - template \ - inline vec fun(vec const &a, vec const &b) \ + template \ + inline vec fun(vec const &a, \ + vec const &b) \ { \ using lol::fun; \ vec ret; \ @@ -1026,8 +983,8 @@ static inline vec operator *(T const &val, vec const &a) return ret; \ } \ \ - template \ - inline vec fun(vec const &a, T const &b) \ + template \ + inline vec fun(vec const &a, T const &b) \ { \ using lol::fun; \ vec ret; \ @@ -1036,8 +993,8 @@ static inline vec operator *(T const &val, vec const &a) return ret; \ } \ \ - template \ - inline vec fun(T const &a, vec const &b) \ + template \ + inline vec fun(T const &a, vec const &b) \ { \ using lol::fun; \ vec ret; \ @@ -1059,32 +1016,32 @@ LOL_SWIZZLE_V_VV_FUN(fmod) * vec clamp(vec, scalar, scalar) */ -template -static inline vec clamp(vec const &x, - vec const &a, - vec const &b) +template +static inline vec clamp(vec const &x, + vec const &a, + vec const &b) { return max(min(x, b), a); } -template -static inline vec clamp(vec const &x, +template +static inline vec clamp(vec const &x, T const &a, - vec const &b) + vec const &b) { return max(min(x, b), a); } -template -static inline vec clamp(vec const &x, - vec const &a, +template +static inline vec clamp(vec const &x, + vec const &a, T const &b) { return max(min(x, b), a); } -template -static inline vec clamp(vec const &x, +template +static inline vec clamp(vec const &x, T const &a, T const &b) { @@ -1096,17 +1053,17 @@ static inline vec clamp(vec const &x, * vec mix(vec, vec, scalar) */ -template -static inline vec mix(vec const &x, - vec const &y, - vec const &a) +template +static inline vec mix(vec const &x, + vec const &y, + vec const &a) { return x + a * (y - x); } -template -static inline vec mix(vec const &x, - vec const &y, +template +static inline vec mix(vec const &x, + vec const &y, T const &a) { return x + a * (y - x); @@ -1116,8 +1073,8 @@ static inline vec mix(vec const &x, * Some GLSL-like functions. */ -template -static inline T dot(vec const &a, vec const &b) +template +static inline T dot(vec const &a, vec const &b) { T ret(0); for (size_t i = 0; i < N; ++i) @@ -1125,22 +1082,22 @@ static inline T dot(vec const &a, vec const &b) return ret; } -template -static inline T sqlength(vec const &a) +template +static inline T sqlength(vec const &a) { return dot(a, a); } -template -static inline T length(vec const &a) +template +static inline T length(vec const &a) { /* FIXME: this is not very nice */ return (T)sqrt((double)sqlength(a)); } -template -static inline vec lerp(vec const &a, - vec const &b, +template +static inline vec lerp(vec const &a, + vec const &b, T const &s) { vec ret; @@ -1149,14 +1106,14 @@ static inline vec lerp(vec const &a, return ret; } -template -static inline T distance(vec const &a, vec const &b) +template +static inline T distance(vec const &a, vec const &b) { return length(a - b); } -template -static inline vec fract(vec const &a) +template +static inline vec fract(vec const &a) { vec ret; for (size_t i = 0; i < N; ++i) @@ -1164,15 +1121,15 @@ static inline vec fract(vec const &a) return ret; } -template -static inline vec normalize(vec const &a) +template +static inline vec normalize(vec const &a) { T norm = (T)length(a); return norm ? a / norm : vec(T(0)); } -template -static inline vec abs(vec const &a) +template +static inline vec abs(vec const &a) { vec ret; for (size_t i = 0; i < N; ++i) @@ -1180,8 +1137,8 @@ static inline vec abs(vec const &a) return ret; } -template -static inline vec degrees(vec const &a) +template +static inline vec degrees(vec const &a) { vec ret; for (size_t i = 0; i < N; ++i) @@ -1189,8 +1146,8 @@ static inline vec degrees(vec const &a) return ret; } -template -static inline vec radians(vec const &a) +template +static inline vec radians(vec const &a) { vec ret; for (size_t i = 0; i < N; ++i) @@ -1203,8 +1160,8 @@ static inline vec radians(vec const &a) */ #if LOL_FEATURE_CXX11_RELAXED_UNIONS -template -inline vec& vec::operator =(vec that) +template +inline vec& vec::operator =(vec that) { for (int i = 0; i < N; ++i) (*this)[i] = that[i]; diff --git a/src/math/vector.cpp b/src/math/vector.cpp index 23176980..61f1f56c 100644 --- a/src/math/vector.cpp +++ b/src/math/vector.cpp @@ -46,125 +46,98 @@ static inline float det3(float a, float b, float c, /* * Return the cofactor of the (i,j) entry in a 2×2 matrix. */ -static inline float cofact(mat2 const &mat, int i, int j) +static inline float cofact(mat2 const &m, int i, int j) { - float tmp = mat[(i + 1) & 1][(j + 1) & 1]; + float tmp = m[(i + 1) & 1][(j + 1) & 1]; return ((i + j) & 1) ? -tmp : tmp; } /* * Return the cofactor of the (i,j) entry in a 3×3 matrix. */ -static inline float cofact(mat3 const &mat, int i, int j) +static inline float cofact(mat3 const &m, int i, int j) { - return det2(mat[(i + 1) % 3][(j + 1) % 3], - mat[(i + 2) % 3][(j + 1) % 3], - mat[(i + 1) % 3][(j + 2) % 3], - mat[(i + 2) % 3][(j + 2) % 3]); + return det2(m[(i + 1) % 3][(j + 1) % 3], + m[(i + 2) % 3][(j + 1) % 3], + m[(i + 1) % 3][(j + 2) % 3], + m[(i + 2) % 3][(j + 2) % 3]); } /* * Return the cofactor of the (i,j) entry in a 4×4 matrix. */ -static inline float cofact(mat4 const &mat, int i, int j) +static inline float cofact(mat4 const &m, int i, int j) { - return det3(mat[(i + 1) & 3][(j + 1) & 3], - mat[(i + 2) & 3][(j + 1) & 3], - mat[(i + 3) & 3][(j + 1) & 3], - mat[(i + 1) & 3][(j + 2) & 3], - mat[(i + 2) & 3][(j + 2) & 3], - mat[(i + 3) & 3][(j + 2) & 3], - mat[(i + 1) & 3][(j + 3) & 3], - mat[(i + 2) & 3][(j + 3) & 3], - mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f); + return det3(m[(i + 1) & 3][(j + 1) & 3], + m[(i + 2) & 3][(j + 1) & 3], + m[(i + 3) & 3][(j + 1) & 3], + m[(i + 1) & 3][(j + 2) & 3], + m[(i + 2) & 3][(j + 2) & 3], + m[(i + 3) & 3][(j + 2) & 3], + m[(i + 1) & 3][(j + 3) & 3], + m[(i + 2) & 3][(j + 3) & 3], + m[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f); } -template<> float determinant(mat2 const &mat) +template<> float determinant(mat2 const &m) { - return det2(mat[0][0], mat[0][1], - mat[1][0], mat[1][1]); + return det2(m[0][0], m[0][1], + m[1][0], m[1][1]); } -template<> mat2 transpose(mat2 const &mat) +template<> mat2 inverse(mat2 const &m) { mat2 ret; - for (int j = 0; j < 2; j++) - for (int i = 0; i < 2; i++) - ret[j][i] = mat[i][j]; - return ret; -} - -template<> mat2 inverse(mat2 const &mat) -{ - mat2 ret; - float d = determinant(mat); + float d = determinant(m); if (d) { d = 1.0f / d; for (int j = 0; j < 2; j++) for (int i = 0; i < 2; i++) - ret[j][i] = cofact(mat, i, j) * d; + ret[j][i] = cofact(m, i, j) * d; } return ret; } -template<> float determinant(mat3 const &mat) +template<> float determinant(mat3 const &m) { - return det3(mat[0][0], mat[0][1], mat[0][2], - mat[1][0], mat[1][1], mat[1][2], - mat[2][0], mat[2][1], mat[2][2]); + return det3(m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); } -template<> mat3 transpose(mat3 const &mat) +template<> mat3 inverse(mat3 const &m) { mat3 ret; - for (int j = 0; j < 3; j++) - for (int i = 0; i < 3; i++) - ret[j][i] = mat[i][j]; - return ret; -} - -template<> mat3 inverse(mat3 const &mat) -{ - mat3 ret; - float d = determinant(mat); + float d = determinant(m); if (d) { d = 1.0f / d; for (int j = 0; j < 3; j++) for (int i = 0; i < 3; i++) - ret[j][i] = cofact(mat, i, j) * d; + ret[j][i] = cofact(m, i, j) * d; } return ret; } -template<> float determinant(mat4 const &mat) +template<> float determinant(mat4 const &m) { float ret = 0; for (int n = 0; n < 4; n++) - ret += mat[n][0] * cofact(mat, n, 0); - return ret; -} - -template<> mat4 transpose(mat4 const &mat) -{ - mat4 ret; - for (int j = 0; j < 4; j++) - for (int i = 0; i < 4; i++) - ret[j][i] = mat[i][j]; + ret += m[n][0] * cofact(m, n, 0); return ret; } -template<> mat4 inverse(mat4 const &mat) +template<> mat4 inverse(mat4 const &m) { mat4 ret; - float d = determinant(mat); + float d = determinant(m); if (d) { d = 1.0f / d; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) - ret[j][i] = cofact(mat, i, j) * d; + ret[j][i] = cofact(m, i, j) * d; } return ret; } @@ -419,17 +392,17 @@ template<> mat3::matrix(quat const &q) float s = 2.0f / n; - v0[0] = 1.0f - s * (q.y * q.y + q.z * q.z); - v0[1] = s * (q.x * q.y + q.z * q.w); - v0[2] = s * (q.x * q.z - q.y * q.w); + (*this)[0][0] = 1.0f - s * (q.y * q.y + q.z * q.z); + (*this)[0][1] = s * (q.x * q.y + q.z * q.w); + (*this)[0][2] = s * (q.x * q.z - q.y * q.w); - v1[0] = s * (q.x * q.y - q.z * q.w); - v1[1] = 1.0f - s * (q.z * q.z + q.x * q.x); - v1[2] = s * (q.y * q.z + q.x * q.w); + (*this)[1][0] = s * (q.x * q.y - q.z * q.w); + (*this)[1][1] = 1.0f - s * (q.z * q.z + q.x * q.x); + (*this)[1][2] = s * (q.y * q.z + q.x * q.w); - v2[0] = s * (q.x * q.z + q.y * q.w); - v2[1] = s * (q.y * q.z - q.x * q.w); - v2[2] = 1.0f - s * (q.x * q.x + q.y * q.y); + (*this)[2][0] = s * (q.x * q.z + q.y * q.w); + (*this)[2][1] = s * (q.y * q.z - q.x * q.w); + (*this)[2][2] = 1.0f - s * (q.x * q.x + q.y * q.y); } template<> mat4::matrix(quat const &q) diff --git a/test/btphystest.cpp b/test/btphystest.cpp index 38842cd5..2baf1bfd 100644 --- a/test/btphystest.cpp +++ b/test/btphystest.cpp @@ -285,8 +285,8 @@ void BtPhysTest::InitApp() { EasyConstraint* new_constraint = new EasyConstraint(); - vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform().v3.xyz - - RopeElements[i - 1]->GetPhysic()->GetTransform().v3.xyz); + vec3 A2B = .5f * (RopeElements[i]->GetPhysic()->GetTransform()[3].xyz - + RopeElements[i - 1]->GetPhysic()->GetTransform()[3].xyz); new_constraint->SetPhysObjA(RopeElements[i - 1]->GetPhysic(), lol::mat4::translate(A2B)); new_constraint->SetPhysObjB(RopeElements[i]->GetPhysic(), lol::mat4::translate(-A2B)); new_constraint->InitConstraintToPoint2Point(); @@ -349,7 +349,7 @@ void BtPhysTest::TickGame(float seconds) PhysicsObject* PhysObj = m_physobj_list[i].m1; float &Timer = m_physobj_list[i].m2; - vec3 obj_loc = PhysObj->GetPhysic()->GetTransform().v3.xyz; + vec3 obj_loc = PhysObj->GetPhysic()->GetTransform()[3].xyz; if (m_cam_target == -1 || m_cam_target == i) { @@ -371,7 +371,7 @@ void BtPhysTest::TickGame(float seconds) LocalPos = mat4::translate(vec3(4.f)) * LocalPos0; LocalPos = cam_screen * LocalPos; - vpos = (LocalPos.v3 / LocalPos.v3.w).xyz; + vpos = (LocalPos[3] / LocalPos[3].w).xyz; screen_min_max[0] = min(vpos.xy, screen_min_max[0]); screen_min_max[1] = max(vpos.xy, screen_min_max[1]); } @@ -427,7 +427,7 @@ void BtPhysTest::TickGame(float seconds) PhysicsObject* PhysObj = m_ground_list[i]; mat4 GroundMat = PhysObj->GetTransform(); - GroundBarycenter += GroundMat.v3.xyz; + GroundBarycenter += GroundMat[3].xyz; factor += 1.f; } @@ -438,7 +438,7 @@ void BtPhysTest::TickGame(float seconds) PhysicsObject* PhysObj = m_ground_list[i]; mat4 GroundMat = PhysObj->GetTransform(); - vec3 CenterToGround = GroundMat.v3.xyz - GroundBarycenter; + vec3 CenterToGround = GroundMat[3].xyz - GroundBarycenter; vec3 CenterToCam = m_camera->GetPosition() - GroundBarycenter; if (dot(normalize(CenterToCam - CenterToGround), @@ -462,7 +462,7 @@ void BtPhysTest::TickGame(float seconds) GroundMat = CenterMx * mat4(quat::fromeuler_xyz(vec3(.0f, 20.f, 20.0f) * seconds)) * GroundMat; - PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); + PhysObj->SetTransform(GroundMat[3].xyz, quat(GroundMat)); } } #endif //USE_ROTATION @@ -477,14 +477,14 @@ void BtPhysTest::TickGame(float seconds) if (i == 0) { GroundMat = GroundMat * mat4(quat::fromeuler_xyz(vec3(20.f, .0f, .0f) * seconds)); - PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); + PhysObj->SetTransform(GroundMat[3].xyz, quat(GroundMat)); } else if (i == 1) { GroundMat = mat4::translate(vec3(-15.0f, 5.0f, lol::cos(m_loop_value) * 8.f)) * mat4(quat::fromeuler_xyz(vec3(.0f, lol::cos(m_loop_value) * 20.f, .0f))); - PhysObj->SetTransform(GroundMat.v3.xyz, quat(GroundMat)); + PhysObj->SetTransform(GroundMat[3].xyz, quat(GroundMat)); } } } @@ -512,7 +512,7 @@ void BtPhysTest::TickGame(float seconds) Character->SetMovementForFrame(CharMove); RayCastResult HitResult; - if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform().v3.xyz, (Character->GetTransform().v3.xyz + vec3(.0f, -1.f, .0f)), Character)) + if (m_simulation->RayHits(HitResult, ERT_Closest, Character->GetTransform()[3].xyz, (Character->GetTransform()[3].xyz + vec3(.0f, -1.f, .0f)), Character)) Character->AttachTo(HitResult.m_collider_list[0], true, true); else Character->AttachTo(NULL); @@ -530,7 +530,7 @@ void BtPhysTest::TickGame(float seconds) PhysicsObject* PhysObj = m_character_list[i]; mat4 GroundMat = PhysObj->GetTransform(); - PhysObjBarycenter += GroundMat.v3.xyz; + PhysObjBarycenter += GroundMat[3].xyz; factor += 1.f; } @@ -550,7 +550,7 @@ void BtPhysTest::TickGame(float seconds) PhysicsObject* PhysObj = m_physobj_list[i].m1; mat4 GroundMat = PhysObj->GetTransform(); - PhysObjBarycenter += GroundMat.v3.xyz; + PhysObjBarycenter += GroundMat[3].xyz; factor += 1.f; } diff --git a/test/meshviewer.cpp b/test/meshviewer.cpp index fc3cb104..a7a2d186 100644 --- a/test/meshviewer.cpp +++ b/test/meshviewer.cpp @@ -493,7 +493,7 @@ public: TargetCamera tc; if (m_meshes.Count() && m_mesh_id >= 0) for (int i = 0; i < m_meshes[m_mesh_id].m1->GetVertexCount(); i++) - tc.AddTarget((m_mat * mat4::translate(m_meshes[m_mesh_id].m1->GetVertexLocation(i))).v3.xyz); + tc.AddTarget((m_mat * mat4::translate(m_meshes[m_mesh_id].m1->GetVertexLocation(i)))[3].xyz); tc.AddTarget(box3(vec3(0.f), vec3(1.f))); for (int k = 0; k < m_ssetup->m_lights.Count() && m_ssetup->m_show_lights; ++k) { @@ -525,13 +525,13 @@ public: //Get location in cam coordinates target_mx = world_cam * target_mx; - vpos = target_mx.v3.xyz; + vpos = target_mx[3].xyz; local_min_max[0] = min(vpos.xyz, local_min_max[0]); local_min_max[1] = max(vpos.xyz, local_min_max[1]); //Get location in screen coordinates target_mx = cam_screen * target_mx; - vpos = (target_mx.v3 / target_mx.v3.w).xyz; + vpos = (target_mx[3] / target_mx[3].w).xyz; screen_min_max[0] = min(screen_min_max[0], vpos.xy * vec2(RATIO_WH, 1.f)); screen_min_max[1] = max(screen_min_max[1], vpos.xy * vec2(RATIO_WH, 1.f)); @@ -846,7 +846,7 @@ public: { Light* ltmp = m_ssetup->m_lights[k]; mat4 world = mat4::translate(ltmp->GetPosition()); - mat4 local = mat4::translate((inverse(m_mat) * world).v3.xyz); + mat4 local = mat4::translate((inverse(m_mat) * world)[3].xyz); //dir light if (ltmp->GetType() == LightType::Directional) { @@ -873,14 +873,14 @@ public: m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j+2]] }; for (int k = 0; k < 3; k++) - Debug::DrawLine((m_mat * mat4::translate(v[k].m_coord)).v3.xyz, - (m_mat * mat4::translate(v[(k+1)%3].m_coord)).v3.xyz, vec4(vec3((v[k].m_coord.z + 1.f)*.5f),1.f)); + Debug::DrawLine((m_mat * mat4::translate(v[k].m_coord))[3].xyz, + (m_mat * mat4::translate(v[(k+1)%3].m_coord))[3].xyz, vec4(vec3((v[k].m_coord.z + 1.f)*.5f),1.f)); } for (int j = 0; j < m_meshes[i].m1->m_vert.Count(); j++) { VertexData &v = m_meshes[i].m1->m_vert[m_meshes[i].m1->m_indices[j]]; - Debug::DrawLine((m_mat * mat4::translate(v.m_coord)).v3.xyz, - (m_mat * mat4::translate(v.m_coord)).v3.xyz + + Debug::DrawLine((m_mat * mat4::translate(v.m_coord))[3].xyz, + (m_mat * mat4::translate(v.m_coord))[3].xyz + (m_mat * vec4(v.m_normal * 5.f, 0.f)).xyz, vec4(lol::abs(v.m_normal), 1.f)); } } diff --git a/test/physics/easycharactercontroller.cpp b/test/physics/easycharactercontroller.cpp index bc6281e0..7d389c07 100644 --- a/test/physics/easycharactercontroller.cpp +++ b/test/physics/easycharactercontroller.cpp @@ -107,10 +107,10 @@ void EasyCharacterController::SetTransform(const lol::vec3& base_location, const { if (m_base_is_updating) { - m_base_cached_movement = base_location - m_local_to_world.v3.xyz; - m_local_to_world = lol::mat4::translate(m_local_to_world.v3.xyz) * lol::mat4(base_rotation); + m_base_cached_movement = base_location - m_local_to_world[3].xyz; + m_local_to_world = lol::mat4::translate(m_local_to_world[3].xyz) * lol::mat4(base_rotation); if (m_ghost_object) - m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world.v3.xyz))); + m_ghost_object->setWorldTransform(btTransform(LOL2BT_QUAT(base_rotation), LOL2BT_VEC3(LOL2BT_UNIT * m_local_to_world[3].xyz))); } else EasyPhysic::SetTransform(base_location, base_rotation); diff --git a/test/physics/easyconstraint.h b/test/physics/easyconstraint.h index a4de819c..80379b49 100644 --- a/test/physics/easyconstraint.h +++ b/test/physics/easyconstraint.h @@ -83,15 +83,15 @@ private: void CustomInitConstraintToPoint2Point() { m_p2p_constraint = new btPoint2PointConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, - LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)); + LOL2BT_VEC3(m_a_transform[3].xyz * LOL2BT_UNIT), LOL2BT_VEC3(m_b_transform[3].xyz * LOL2BT_UNIT)); m_typed_constraint = m_p2p_constraint; } void CustomInitConstraintToHinge() { m_hinge_constraint = new btHingeConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, - btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), - btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform[3].xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform[3].xyz * LOL2BT_UNIT)), m_using_ref_a); m_typed_constraint = m_hinge_constraint; } @@ -99,8 +99,8 @@ private: void CustomInitConstraintToSlider() { m_slider_constraint = new btSliderConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, - btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), - btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform[3].xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform[3].xyz * LOL2BT_UNIT)), m_using_ref_a); m_typed_constraint = m_slider_constraint; } @@ -108,16 +108,16 @@ private: void CustomInitConstraintToConeTwist() { m_cone_twist_constraint = new btConeTwistConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, - btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), - btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT))); + btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform[3].xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform[3].xyz * LOL2BT_UNIT))); m_typed_constraint = m_cone_twist_constraint; } void CustomInitConstraintTo6Dof() { m_6dof_constraint = new btGeneric6DofConstraint(*m_a_physobj->m_rigid_body, *m_b_physobj->m_rigid_body, - btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform.v3.xyz * LOL2BT_UNIT)), - btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform.v3.xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_a_transform)), LOL2BT_VEC3(m_a_transform[3].xyz * LOL2BT_UNIT)), + btTransform(LOL2BT_QUAT(quat(m_b_transform)), LOL2BT_VEC3(m_b_transform[3].xyz * LOL2BT_UNIT)), m_using_ref_a); m_typed_constraint = m_6dof_constraint; } diff --git a/test/physics/easyphysics.cpp b/test/physics/easyphysics.cpp index 61bc96ce..976554b7 100644 --- a/test/physics/easyphysics.cpp +++ b/test/physics/easyphysics.cpp @@ -157,16 +157,16 @@ void EasyPhysic::SetTransform(const lol::vec3& base_location, const lol::quat& b //Internal callback when Base transform has changed. void EasyPhysic::BaseTransformChanged(const lol::mat4& PreviousMatrix, const lol::mat4& NewMatrix) { - mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix.v3.xyz))); + mat4 PreviousMatrixLoc = ((m_base_lock_location)?(PreviousMatrix):(lol::mat4::translate(PreviousMatrix[3].xyz))); mat4 PreviousMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(PreviousMatrix))):(lol::mat4(1.f))); - mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix.v3.xyz))); + mat4 NewMatrixLoc = ((m_base_lock_location)?(NewMatrix):(lol::mat4::translate(NewMatrix[3].xyz))); mat4 NewMatrixRot = ((m_base_lock_rotation)?(lol::mat4(lol::quat(NewMatrix))):(lol::mat4(1.f))); if (m_ghost_object || (m_rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT)) { - mat4 ThisMatrixLoc = NewMatrixLoc * inverse(PreviousMatrixLoc) * lol::mat4::translate(m_local_to_world.v3.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)); - SetTransform(ThisMatrixLoc.v3.xyz, lol::mat4(lol::quat(ThisMatrixRot))); + SetTransform(ThisMatrixLoc[3].xyz, lol::mat4(lol::quat(ThisMatrixRot))); } } @@ -247,7 +247,7 @@ void EasyPhysic::InitBodyToGhost() m_collision_object = m_ghost_object; m_collision_object->setUserPointer(this); - SetTransform(m_local_to_world.v3.xyz, lol::quat(m_local_to_world)); + SetTransform(m_local_to_world[3].xyz, lol::quat(m_local_to_world)); m_ghost_object->setCollisionFlags(m_ghost_object->getCollisionFlags()); } diff --git a/tools/lolremez/matrix.h b/tools/lolremez/matrix.h index 08b66ab1..b1541cb9 100644 --- a/tools/lolremez/matrix.h +++ b/tools/lolremez/matrix.h @@ -17,38 +17,33 @@ using namespace lol; * naive inversion and is used for the Remez inversion method. */ -template struct Matrix +template struct LinearSystem { - inline Matrix(int cols, int rows) - : m_cols(cols), - m_rows(rows) + inline LinearSystem(int cols) + : m_cols(cols) { ASSERT(cols > 0); - ASSERT(rows > 0); - m_data.Resize(m_cols * m_rows); + m_data.Resize(m_cols * m_cols); } - inline Matrix(Matrix const &other) + inline LinearSystem(LinearSystem const &other) { m_cols = other.m_cols; - m_rows = other.m_rows; m_data = other.m_data; } void Init(T const &x) { - for (int j = 0; j < m_rows; j++) + for (int j = 0; j < m_cols; j++) for (int i = 0; i < m_cols; i++) m(i, j) = (i == j) ? x : (T)0; } /* Naive matrix inversion */ - Matrix inv() const + LinearSystem inv() const { - ASSERT(m_cols == m_rows); - - Matrix a(*this), b(m_cols, m_rows); + LinearSystem a(*this), b(m_cols); b.Init((T)1); @@ -100,10 +95,10 @@ template struct Matrix return b; } - inline T & m(int i, int j) { return m_data[m_rows * j + i]; } - inline T const & m(int i, int j) const { return m_data[m_rows * j + i]; } + inline T & m(int i, int j) { return m_data[m_cols * j + i]; } + inline T const & m(int i, int j) const { return m_data[m_cols * j + i]; } - int m_cols, m_rows; + int m_cols; private: array m_data; diff --git a/tools/lolremez/solver.cpp b/tools/lolremez/solver.cpp index 025cc4e9..7875a178 100644 --- a/tools/lolremez/solver.cpp +++ b/tools/lolremez/solver.cpp @@ -105,7 +105,7 @@ void RemezSolver::Init() /* We build a matrix of Chebishev evaluations: row i contains the * evaluations of x_i for polynomial order n = 0, 1, ... */ - Matrix mat(m_order + 1, m_order + 1); + LinearSystem system(m_order + 1); for (int i = 0; i < m_order + 1; i++) { /* Compute the powers of x_i */ @@ -120,19 +120,19 @@ void RemezSolver::Init() real sum = 0.0; for (int k = 0; k < m_order + 1; k++) sum += (real)Cheby(n, k) * powers[k]; - mat.m(i, n) = sum; + system.m(i, n) = sum; } } /* Solve the system */ - mat = mat.inv(); + system = system.inv(); /* Compute interpolation coefficients */ for (int j = 0; j < m_order + 1; j++) { m_coeff[j] = 0; for (int i = 0; i < m_order + 1; i++) - m_coeff[j] += mat.m(j, i) * fxn[i]; + m_coeff[j] += system.m(j, i) * fxn[i]; } } @@ -245,7 +245,7 @@ void RemezSolver::Step() /* We build a matrix of Chebishev evaluations: row i contains the * evaluations of x_i for polynomial order n = 0, 1, ... */ - Matrix mat(m_order + 2, m_order + 2); + LinearSystem system(m_order + 2); for (int i = 0; i < m_order + 2; i++) { /* Compute the powers of x_i */ @@ -260,29 +260,29 @@ void RemezSolver::Step() real sum = 0.0; for (int k = 0; k < m_order + 1; k++) sum += (real)Cheby(n, k) * powers[k]; - mat.m(i, n) = sum; + system.m(i, n) = sum; } if (i & 1) - mat.m(i, m_order + 1) = fabs(Weight(m_control[i])); + system.m(i, m_order + 1) = fabs(Weight(m_control[i])); else - mat.m(i, m_order + 1) = -fabs(Weight(m_control[i])); + system.m(i, m_order + 1) = -fabs(Weight(m_control[i])); } /* Solve the system */ - mat = mat.inv(); + system = system.inv(); /* Compute interpolation coefficients */ for (int j = 0; j < m_order + 1; j++) { m_coeff[j] = 0; for (int i = 0; i < m_order + 2; i++) - m_coeff[j] += mat.m(j, i) * fxn[i]; + m_coeff[j] += system.m(j, i) * fxn[i]; } /* Compute the error */ real error = 0; for (int i = 0; i < m_order + 2; i++) - error += mat.m(m_order + 1, i) * fxn[i]; + error += system.m(m_order + 1, i) * fxn[i]; } int RemezSolver::Cheby(int n, int k) diff --git a/tools/vimlol/vimlol.vim b/tools/vimlol/vimlol.vim index ec088481..61c365ac 100644 --- a/tools/vimlol/vimlol.vim +++ b/tools/vimlol/vimlol.vim @@ -28,7 +28,7 @@ au Syntax cpp " HLSL types au Syntax cpp \ syn match cType - \ "\<\(int\|float\)[234]\(\|x[234]\)\>" + \ "\<\(int\|half\|float\)[234]\(\|x[234]\)\>" " More GLSL-like types from the Lol Engine au Syntax cpp