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[].undefined
@@ -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[] = | |||
@@ -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 | |||
@@ -34,7 +34,10 @@ class half; | |||
* Forward declaration of vec and matrix | |||
*/ | |||
template<int N, typename T, int MASK = -1> struct vec; | |||
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 matrix; | |||
template<typename T> struct Cmplx; | |||
template<typename T> 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; | |||
@@ -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<int COLS, int ROWS, typename T> | |||
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<T> 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<T> 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<typename T> T determinant(matrix<2,2,T> const &); | |||
template<typename T> T determinant(matrix<3,3,T> const &); | |||
template<typename T> T determinant(matrix<4,4,T> const &); | |||
template<typename T> matrix<2,2,T> transpose(matrix<2,2,T> const &); | |||
template<typename T> matrix<3,3,T> transpose(matrix<3,3,T> const &); | |||
template<typename T> matrix<4,4,T> transpose(matrix<4,4,T> const &); | |||
template<typename T> matrix<2,2,T> inverse(matrix<2,2,T> const &); | |||
template<typename T> matrix<3,3,T> inverse(matrix<3,3,T> const &); | |||
template<typename T> matrix<4,4,T> inverse(matrix<4,4,T> const &); | |||
template<int COLS, int ROWS, typename T> | |||
static inline matrix<ROWS, COLS, T> transpose(matrix<COLS, ROWS, T> const &m) | |||
{ | |||
matrix<ROWS, COLS, T> 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<COLS, ROWS, T> operator -(matrix<COLS, ROWS, T> const &m) | |||
} | |||
/* | |||
* Matrix-vector multiplication | |||
* Matrix-vector and vector-matrix multiplication | |||
*/ | |||
template<int COLS, int ROWS, int MASK, typename T> | |||
@@ -396,6 +473,16 @@ static inline vec<ROWS, T> operator *(matrix<COLS, ROWS, T> const &m, | |||
return ret; | |||
} | |||
template<int COLS, int ROWS, int MASK, typename T> | |||
static inline vec<COLS, T> operator *(vec<ROWS, T, MASK> const &v, | |||
matrix<COLS, ROWS, T> const &m) | |||
{ | |||
vec<COLS, T> ret(T(0)); | |||
for (int i = 0; i < COLS; ++i) | |||
ret[i] = dot(v, m[i]); | |||
return ret; | |||
} | |||
/* | |||
* Matrix-matrix multiplication | |||
*/ | |||
@@ -48,15 +48,15 @@ namespace lol | |||
* fuck it. | |||
*/ | |||
template<int N, typename T, int MASK> | |||
template<int N, typename T, int SWIZZLE> | |||
struct vec | |||
{ | |||
typedef vec<N,T> type; | |||
inline vec<N, T, MASK>& operator =(vec<N, T> that); | |||
inline vec<N, T, SWIZZLE>& operator =(vec<N, T> that); | |||
#if LOL_FEATURE_CXX11_RELAXED_UNIONS | |||
inline vec<N, T, MASK>& operator =(vec<N, T, MASK> const &that) | |||
inline vec<N, T, SWIZZLE>& operator =(vec<N, T, SWIZZLE> const &that) | |||
{ | |||
/* Pass by value in case this == &that */ | |||
return *this = (vec<N,T>)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<T*>(static_cast<void*>(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<T const*>(static_cast<void const *>(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<int N, typename T> | |||
struct vec<N, T, -1> | |||
{ | |||
@@ -218,10 +219,41 @@ private: | |||
* 2-element vectors | |||
*/ | |||
template <typename T> struct base_vec2 | |||
template <typename T> | |||
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<int SWIZZLE> | |||
inline constexpr vec(vec<2, T, SWIZZLE> const &v) | |||
: x(v[0]), y(v[1]) {} | |||
/* Explicit constructor for type conversion */ | |||
template<typename U, int SWIZZLE> | |||
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<typename U> | |||
friend std::ostream &operator<<(std::ostream &stream, vec<2,U> const &v); | |||
union | |||
{ | |||
@@ -264,59 +296,86 @@ template <typename T> struct base_vec2 | |||
}; | |||
}; | |||
template <> struct base_vec2<half> | |||
{ | |||
explicit inline base_vec2() {} | |||
explicit inline base_vec2(half X, half Y) : x(X), y(Y) {} | |||
half x, y; | |||
}; | |||
template <> struct base_vec2<real> | |||
{ | |||
explicit inline base_vec2() {} | |||
explicit inline base_vec2(real X, real Y) : x(X), y(Y) {} | |||
real x, y; | |||
}; | |||
/* | |||
* 3-element vectors | |||
*/ | |||
template <typename T> | |||
struct vec<2,T> : base_vec2<T> | |||
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<T>(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<int SWIZZLE> | |||
inline constexpr vec(vec<3, T, SWIZZLE> const &v) | |||
: x(v[0]), y(v[1]), z(v[2]) {} | |||
/* Explicit constructor for type conversion */ | |||
template<typename U, int SWIZZLE> | |||
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<T>(X, X) {} | |||
LOL_COMMON_MEMBER_OPS(x) | |||
LOL_VECTOR_MEMBER_OPS() | |||
template<int MASK> | |||
inline constexpr vec(vec<2, T, MASK> const &v) | |||
: base_vec2<T>(v[0], v[1]) {} | |||
static vec<3,T> toeuler_xyx(Quat<T> const &q); | |||
static vec<3,T> toeuler_xzx(Quat<T> const &q); | |||
static vec<3,T> toeuler_yxy(Quat<T> const &q); | |||
static vec<3,T> toeuler_yzy(Quat<T> const &q); | |||
static vec<3,T> toeuler_zxz(Quat<T> const &q); | |||
static vec<3,T> toeuler_zyz(Quat<T> const &q); | |||
template<typename U, int MASK> | |||
explicit inline constexpr vec(vec<2, U, MASK> const &v) | |||
: base_vec2<T>(v[0], v[1]) {} | |||
static vec<3,T> toeuler_xyz(Quat<T> const &q); | |||
static vec<3,T> toeuler_xzy(Quat<T> const &q); | |||
static vec<3,T> toeuler_yxz(Quat<T> const &q); | |||
static vec<3,T> toeuler_yzx(Quat<T> const &q); | |||
static vec<3,T> toeuler_zxy(Quat<T> const &q); | |||
static vec<3,T> toeuler_zyx(Quat<T> 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<typename U> | |||
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 <typename T> 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<typename U> | |||
friend std::ostream &operator<<(std::ostream &stream, vec<3,U> const &v); | |||
union | |||
{ | |||
@@ -448,100 +507,59 @@ template <typename T> struct base_vec3 | |||
}; | |||
}; | |||
template <> struct base_vec3<half> | |||
{ | |||
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<real> | |||
{ | |||
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 <typename T> | |||
struct vec<3,T> : base_vec3<T> | |||
struct vec<4,T> | |||
{ | |||
typedef vec<3,T> type; | |||
inline constexpr vec() {} | |||
inline constexpr vec(T X, T Y, T Z) : base_vec3<T>(X, Y, Z) {} | |||
inline constexpr vec(vec<2,T> XY, T Z) : base_vec3<T>(XY.x, XY.y, Z) {} | |||
inline constexpr vec(T X, vec<2,T> YZ) : base_vec3<T>(X, YZ.x, YZ.y) {} | |||
explicit inline constexpr vec(T X) : base_vec3<T>(X, X, X) {} | |||
template<int MASK> | |||
inline constexpr vec(vec<3, T, MASK> const &v) | |||
: base_vec3<T>(v[0], v[1], v[2]) {} | |||
typedef vec<4,T> type; | |||
template<typename U, int MASK> | |||
explicit inline constexpr vec(vec<3, U, MASK> const &v) | |||
: base_vec3<T>(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<int SWIZZLE> | |||
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<typename U, int SWIZZLE> | |||
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<T> const &q); | |||
static vec<3,T> toeuler_xzx(Quat<T> const &q); | |||
static vec<3,T> toeuler_yxy(Quat<T> const &q); | |||
static vec<3,T> toeuler_yzy(Quat<T> const &q); | |||
static vec<3,T> toeuler_zxz(Quat<T> const &q); | |||
static vec<3,T> toeuler_zyz(Quat<T> const &q); | |||
static vec<3,T> toeuler_xyz(Quat<T> const &q); | |||
static vec<3,T> toeuler_xzy(Quat<T> const &q); | |||
static vec<3,T> toeuler_yxz(Quat<T> const &q); | |||
static vec<3,T> toeuler_yzx(Quat<T> const &q); | |||
static vec<3,T> toeuler_zxy(Quat<T> const &q); | |||
static vec<3,T> toeuler_zyx(Quat<T> 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<typename U> | |||
friend std::ostream &operator<<(std::ostream &stream, vec<3,U> const &v); | |||
}; | |||
/* | |||
* 4-element vectors | |||
*/ | |||
template <typename T> 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 <typename T> struct base_vec4 | |||
}; | |||
}; | |||
template <> struct base_vec4<half> | |||
{ | |||
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<real> | |||
{ | |||
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 <typename T> | |||
struct vec<4,T> : base_vec4<T> | |||
{ | |||
typedef vec<4,T> type; | |||
inline constexpr vec() {} | |||
inline constexpr vec(T X, T Y, T Z, T W) | |||
: base_vec4<T>(X, Y, Z, W) {} | |||
inline constexpr vec(vec<2,T> XY, T Z, T W) | |||
: base_vec4<T>(XY.x, XY.y, Z, W) {} | |||
inline constexpr vec(T X, vec<2,T> YZ, T W) | |||
: base_vec4<T>(X, YZ.x, YZ.y, W) {} | |||
inline constexpr vec(T X, T Y, vec<2,T> ZW) | |||
: base_vec4<T>(X, Y, ZW.x, ZW.y) {} | |||
inline constexpr vec(vec<2,T> XY, vec<2,T> ZW) | |||
: base_vec4<T>(XY.x, XY.y, ZW.x, ZW.y) {} | |||
inline constexpr vec(vec<3,T> XYZ, T W) | |||
: base_vec4<T>(XYZ.x, XYZ.y, XYZ.z, W) {} | |||
inline constexpr vec(T X, vec<3,T> YZW) | |||
: base_vec4<T>(X, YZW.x, YZW.y, YZW.z) {} | |||
explicit inline constexpr vec(T X) : base_vec4<T>(X, X, X, X) {} | |||
template<int MASK> | |||
inline constexpr vec(vec<4, T, MASK> const &v) | |||
: base_vec4<T>(v[0], v[1], v[2], v[3]) {} | |||
template<typename U, int MASK> | |||
explicit inline constexpr vec(vec<4, U, MASK> const &v) | |||
: base_vec4<T>(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<typename U> | |||
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<int N, int MASK1, int MASK2, typename T> | |||
static inline bool operator ==(vec<N,T,MASK1> const &a, | |||
vec<N,T,MASK2> const &b) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline bool operator ==(vec<N,T,SWIZZLE1> const &a, | |||
vec<N,T,SWIZZLE2> const &b) | |||
{ | |||
for (size_t i = 0; i < N; ++i) | |||
if (!(a[i] == b[i])) | |||
@@ -970,9 +926,9 @@ static inline bool operator ==(vec<N,T,MASK1> const &a, | |||
return true; | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline bool operator !=(vec<N,T,MASK1> const &a, | |||
vec<N,T,MASK2> const &b) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline bool operator !=(vec<N,T,SWIZZLE1> const &a, | |||
vec<N,T,SWIZZLE2> const &b) | |||
{ | |||
for (size_t i = 0; i < N; ++i) | |||
if (a[i] != b[i]) | |||
@@ -981,15 +937,15 @@ static inline bool operator !=(vec<N,T,MASK1> const &a, | |||
} | |||
#define LOL_SWIZZLE_V_VV_OP(op) \ | |||
template<int N, int MASK1, int MASK2, typename T> \ | |||
inline vec<N,T> operator op(vec<N,T,MASK1> const &a, \ | |||
vec<N,T,MASK2> const &b) \ | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> \ | |||
inline vec<N,T> operator op(vec<N,T,SWIZZLE1> const &a, \ | |||
vec<N,T,SWIZZLE2> const &b) \ | |||
{ \ | |||
return vec<N,T>(a) op vec<N,T>(b); \ | |||
} \ | |||
\ | |||
template<int N, int MASK, typename T> \ | |||
inline vec<N,T> operator op(vec<N,T,MASK> a, T const &b) \ | |||
template<int N, int SWIZZLE, typename T> \ | |||
inline vec<N,T> operator op(vec<N,T,SWIZZLE> a, T const &b) \ | |||
{ \ | |||
return vec<N,T>(a) op b; \ | |||
} | |||
@@ -1001,8 +957,8 @@ LOL_SWIZZLE_V_VV_OP(/) | |||
#undef LOL_SWIZZLE_V_VV_OP | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> operator *(T const &val, vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> operator *(T const &val, vec<N,T,SWIZZLE> const &a) | |||
{ | |||
vec<N,T> ret; | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1016,8 +972,9 @@ static inline vec<N,T> operator *(T const &val, vec<N,T,MASK> const &a) | |||
*/ | |||
#define LOL_SWIZZLE_V_VV_FUN(fun) \ | |||
template<int N, int MASK1, int MASK2, typename T> \ | |||
inline vec<N,T> fun(vec<N,T,MASK1> const &a, vec<N,T,MASK2> const &b) \ | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> \ | |||
inline vec<N,T> fun(vec<N,T,SWIZZLE1> const &a, \ | |||
vec<N,T,SWIZZLE2> const &b) \ | |||
{ \ | |||
using lol::fun; \ | |||
vec<N,T> ret; \ | |||
@@ -1026,8 +983,8 @@ static inline vec<N,T> operator *(T const &val, vec<N,T,MASK> const &a) | |||
return ret; \ | |||
} \ | |||
\ | |||
template<int N, int MASK, typename T> \ | |||
inline vec<N,T> fun(vec<N,T,MASK> const &a, T const &b) \ | |||
template<int N, int SWIZZLE, typename T> \ | |||
inline vec<N,T> fun(vec<N,T,SWIZZLE> const &a, T const &b) \ | |||
{ \ | |||
using lol::fun; \ | |||
vec<N,T> ret; \ | |||
@@ -1036,8 +993,8 @@ static inline vec<N,T> operator *(T const &val, vec<N,T,MASK> const &a) | |||
return ret; \ | |||
} \ | |||
\ | |||
template<int N, int MASK, typename T> \ | |||
inline vec<N,T> fun(T const &a, vec<N,T,MASK> const &b) \ | |||
template<int N, int SWIZZLE, typename T> \ | |||
inline vec<N,T> fun(T const &a, vec<N,T,SWIZZLE> const &b) \ | |||
{ \ | |||
using lol::fun; \ | |||
vec<N,T> ret; \ | |||
@@ -1059,32 +1016,32 @@ LOL_SWIZZLE_V_VV_FUN(fmod) | |||
* vec clamp(vec, scalar, scalar) | |||
*/ | |||
template<int N, int MASK1, int MASK2, int MASK3, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,MASK1> const &x, | |||
vec<N,T,MASK2> const &a, | |||
vec<N,T,MASK3> const &b) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,SWIZZLE1> const &x, | |||
vec<N,T,SWIZZLE2> const &a, | |||
vec<N,T,SWIZZLE3> const &b) | |||
{ | |||
return max(min(x, b), a); | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,MASK1> const &x, | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,SWIZZLE1> const &x, | |||
T const &a, | |||
vec<N,T,MASK2> const &b) | |||
vec<N,T,SWIZZLE2> const &b) | |||
{ | |||
return max(min(x, b), a); | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,MASK1> const &x, | |||
vec<N,T,MASK2> const &a, | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,SWIZZLE1> const &x, | |||
vec<N,T,SWIZZLE2> const &a, | |||
T const &b) | |||
{ | |||
return max(min(x, b), a); | |||
} | |||
template<int N, int MASK1, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,MASK1> const &x, | |||
template<int N, int SWIZZLE1, typename T> | |||
static inline vec<N,T> clamp(vec<N,T,SWIZZLE1> const &x, | |||
T const &a, | |||
T const &b) | |||
{ | |||
@@ -1096,17 +1053,17 @@ static inline vec<N,T> clamp(vec<N,T,MASK1> const &x, | |||
* vec mix(vec, vec, scalar) | |||
*/ | |||
template<int N, int MASK1, int MASK2, int MASK3, typename T> | |||
static inline vec<N,T> mix(vec<N,T,MASK1> const &x, | |||
vec<N,T,MASK2> const &y, | |||
vec<N,T,MASK3> const &a) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, int SWIZZLE3, typename T> | |||
static inline vec<N,T> mix(vec<N,T,SWIZZLE1> const &x, | |||
vec<N,T,SWIZZLE2> const &y, | |||
vec<N,T,SWIZZLE3> const &a) | |||
{ | |||
return x + a * (y - x); | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline vec<N,T> mix(vec<N,T,MASK1> const &x, | |||
vec<N,T,MASK2> const &y, | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline vec<N,T> mix(vec<N,T,SWIZZLE1> const &x, | |||
vec<N,T,SWIZZLE2> const &y, | |||
T const &a) | |||
{ | |||
return x + a * (y - x); | |||
@@ -1116,8 +1073,8 @@ static inline vec<N,T> mix(vec<N,T,MASK1> const &x, | |||
* Some GLSL-like functions. | |||
*/ | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline T dot(vec<N,T,MASK1> const &a, vec<N,T,MASK2> const &b) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline T dot(vec<N,T,SWIZZLE1> const &a, vec<N,T,SWIZZLE2> const &b) | |||
{ | |||
T ret(0); | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1125,22 +1082,22 @@ static inline T dot(vec<N,T,MASK1> const &a, vec<N,T,MASK2> const &b) | |||
return ret; | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline T sqlength(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline T sqlength(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
return dot(a, a); | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline T length(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline T length(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
/* FIXME: this is not very nice */ | |||
return (T)sqrt((double)sqlength(a)); | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline vec<N,T> lerp(vec<N,T,MASK1> const &a, | |||
vec<N,T,MASK2> const &b, | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline vec<N,T> lerp(vec<N,T,SWIZZLE1> const &a, | |||
vec<N,T,SWIZZLE2> const &b, | |||
T const &s) | |||
{ | |||
vec<N,T> ret; | |||
@@ -1149,14 +1106,14 @@ static inline vec<N,T> lerp(vec<N,T,MASK1> const &a, | |||
return ret; | |||
} | |||
template<int N, int MASK1, int MASK2, typename T> | |||
static inline T distance(vec<N,T,MASK1> const &a, vec<N,T,MASK2> const &b) | |||
template<int N, int SWIZZLE1, int SWIZZLE2, typename T> | |||
static inline T distance(vec<N,T,SWIZZLE1> const &a, vec<N,T,SWIZZLE2> const &b) | |||
{ | |||
return length(a - b); | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> fract(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> fract(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
vec<N,T> ret; | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1164,15 +1121,15 @@ static inline vec<N,T> fract(vec<N,T,MASK> const &a) | |||
return ret; | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> normalize(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> normalize(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
T norm = (T)length(a); | |||
return norm ? a / norm : vec<N,T>(T(0)); | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> abs(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> abs(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
vec<N,T> ret; | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1180,8 +1137,8 @@ static inline vec<N,T> abs(vec<N,T,MASK> const &a) | |||
return ret; | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> degrees(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> degrees(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
vec<N,T> ret; | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1189,8 +1146,8 @@ static inline vec<N,T> degrees(vec<N,T,MASK> const &a) | |||
return ret; | |||
} | |||
template<int N, int MASK, typename T> | |||
static inline vec<N,T> radians(vec<N,T,MASK> const &a) | |||
template<int N, int SWIZZLE, typename T> | |||
static inline vec<N,T> radians(vec<N,T,SWIZZLE> const &a) | |||
{ | |||
vec<N,T> ret; | |||
for (size_t i = 0; i < N; ++i) | |||
@@ -1203,8 +1160,8 @@ static inline vec<N,T> radians(vec<N,T,MASK> const &a) | |||
*/ | |||
#if LOL_FEATURE_CXX11_RELAXED_UNIONS | |||
template<int N, typename T, int MASK> | |||
inline vec<N, T, MASK>& vec<N, T, MASK>::operator =(vec<N,T> that) | |||
template<int N, typename T, int SWIZZLE> | |||
inline vec<N, T, SWIZZLE>& vec<N, T, SWIZZLE>::operator =(vec<N,T> that) | |||
{ | |||
for (int i = 0; i < N; ++i) | |||
(*this)[i] = that[i]; | |||
@@ -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) | |||
@@ -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; | |||
} | |||
@@ -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)); | |||
} | |||
} | |||
@@ -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); | |||
@@ -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; | |||
} | |||
@@ -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()); | |||
} | |||
@@ -17,38 +17,33 @@ using namespace lol; | |||
* naive inversion and is used for the Remez inversion method. | |||
*/ | |||
template<typename T> struct Matrix | |||
template<typename T> struct LinearSystem | |||
{ | |||
inline Matrix<T>(int cols, int rows) | |||
: m_cols(cols), | |||
m_rows(rows) | |||
inline LinearSystem<T>(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<T>(Matrix<T> const &other) | |||
inline LinearSystem<T>(LinearSystem<T> 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<T> inv() const | |||
LinearSystem<T> 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<typename T> 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<T> m_data; | |||
@@ -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<real> mat(m_order + 1, m_order + 1); | |||
LinearSystem<real> 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<real> mat(m_order + 2, m_order + 2); | |||
LinearSystem<real> 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) | |||
@@ -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 | |||