engine/include/Utils/DataTypes/NewDataTypes.h

1048 lines
22 KiB
C++

#ifndef NEW_DATA_TYPES_H_INCLUDED
#define NEW_DATA_TYPES_H_INCLUDED
#include <math.h>
namespace SE
{
//Find this in DataTypes.h
bool IsFloatEqual(float a, float b);
template<typename TYPENAME1>
class tvec4;
template<typename TYPENAME1>
class tmat3;
template<typename TYPENAME>
class tvec2
{
public:
TYPENAME v[2];
tvec2() { v[0] = 0; v[1] = 0; }
template<typename TYPENAME1, typename TYPENAME2>
tvec2(TYPENAME1 x, TYPENAME2 y) { v[0] = static_cast<TYPENAME>(x); v[1] = static_cast<TYPENAME>(y); }
tvec2<TYPENAME>& operator=(const tvec2<TYPENAME>& vc);
bool operator==(const tvec2<TYPENAME>& vc) const;
bool operator!=(const tvec2<TYPENAME>& vc) const;
tvec2<TYPENAME>& operator+=(const tvec2<TYPENAME>& vc);
tvec2<TYPENAME> operator+(const tvec2<TYPENAME>& a) const;
tvec2<TYPENAME>& operator-=(const tvec2<TYPENAME>& vc);
tvec2<TYPENAME> operator-(const tvec2<TYPENAME>& a) const;
tvec2<TYPENAME> operator-();
tvec2<TYPENAME>& operator*=(TYPENAME c);
};
typedef tvec2<float> vec2;
typedef tvec2<int> ivec2;
vec2 Normalize(const vec2& a);
float Length(const vec2& a);
float DotProduct(const vec2& a,const vec2& b);
template<typename TYPENAME1>
class tvec3
{
public:
TYPENAME1 v[3];
tvec3<TYPENAME1>();
tvec3(TYPENAME1 x, TYPENAME1 y, TYPENAME1 z);
tvec3(const tvec2<TYPENAME1>& vc, TYPENAME1 z);
tvec3(const tvec3<TYPENAME1>& vc);
tvec3(const tvec4<TYPENAME1>& vc);
bool operator==(const tvec3<TYPENAME1>& vc) const;
bool operator!=(const tvec3<TYPENAME1>& vc) const;
tvec3<TYPENAME1>& operator=(const tvec3<TYPENAME1>& vc);
tvec3<TYPENAME1>& operator+=(const tvec3<TYPENAME1>& vc);
tvec3<TYPENAME1>& operator-=(const tvec3<TYPENAME1>& vc);
tvec3<TYPENAME1> operator+(const tvec3<TYPENAME1>& a) const;
tvec3<TYPENAME1> operator-(const tvec3<TYPENAME1>& a) const;
tvec3<TYPENAME1> operator-();
tvec3<TYPENAME1>& operator*=(TYPENAME1 c);
tvec3<TYPENAME1> operator*(const tmat3<TYPENAME1>& mt) const; //MultRowMatrix()
};
typedef tvec3<float> vec3;
float DotProduct(const vec3& a,const vec3& b);
vec3 CrossProduct(const vec3& a,const vec3& b);
vec3 Normalize(const vec3& a);
float Length(const vec3& a);
template<typename TYPENAME1>
class tvec4
{
public:
TYPENAME1 v[4];
tvec4();
tvec4(TYPENAME1 x, TYPENAME1 y, TYPENAME1 z, TYPENAME1 w);
tvec4(const tvec3<TYPENAME1>& vc);
tvec4(const tvec4<TYPENAME1>& vc);
tvec4(const tmat3<TYPENAME1>& m);
bool operator==(const tvec4<TYPENAME1>& vc) const;
bool operator!=(const tvec4<TYPENAME1>& vc) const;
tvec4<TYPENAME1>& operator=(const tvec4<TYPENAME1>& vc);
tvec4<TYPENAME1>& operator+=(const tvec4<TYPENAME1>& vc);
tvec4<TYPENAME1>& operator-=(const tvec4<TYPENAME1>& vc);
const tvec4<TYPENAME1> operator+(const tvec4<TYPENAME1>& a) const;
const tvec4<TYPENAME1> operator-(const tvec4<TYPENAME1>& a) const;
//vec4& operator-(); not so obvious for quaternion :(
tvec4<TYPENAME1>& operator*=(TYPENAME1 c);
tvec4<TYPENAME1>& operator*=(const tvec4<TYPENAME1>& q);
tvec4<TYPENAME1> operator*(const tvec4<TYPENAME1>& q) const;
};
typedef tvec4<float> vec4;
vec4 InverseQuat(const vec4& q);
vec4 NormalizeQuat(const vec4& q);
template<typename TYPENAME1>
class tmat2
{
public:
TYPENAME1 m[4];
tmat2();
tmat2(TYPENAME1 alpha);
tmat2(const tmat2<TYPENAME1>& mt);
bool operator==(const tmat2<TYPENAME1>& mt) const;
bool operator!=(const tmat2<TYPENAME1>& mt) const;
tmat2<TYPENAME1>& operator=(const tmat2<TYPENAME1>& mt);
tmat2<TYPENAME1>& operator*=(const tmat2<TYPENAME1>& mt);
tmat2<TYPENAME1> operator*(const tmat2<TYPENAME1>& mt);
tvec2<TYPENAME1> operator*(const tvec2<TYPENAME1>& vc) const; //MultMatrixCol()
};
typedef tmat2<float> mat2;
template<typename TYPENAME1>
class tmat3
{
public:
TYPENAME1 m[9];
tmat3();
tmat3(const tvec3<TYPENAME1>& col1, const tvec3<TYPENAME1>& col2, const tvec3<TYPENAME1>& col3);
tmat3(const tmat3<TYPENAME1>& mt);
tmat3(const tvec4<TYPENAME1>& q);
bool operator==(const tmat3<TYPENAME1>& mt) const;
bool operator!=(const tmat3<TYPENAME1>& mt) const;
tmat3<TYPENAME1>& operator=(const tmat3<TYPENAME1>& mt);
tmat3<TYPENAME1>& operator*=(const tmat3<TYPENAME1>& mt);
tmat3<TYPENAME1> operator*(const tmat3<TYPENAME1>& mt);
tvec3<TYPENAME1> operator*(const tvec3<TYPENAME1>& vc) const; //MultMatrixCol()
};
typedef tmat3<float> mat3;
mat3 TransposeMatrix(const mat3& m);
mat3 InverseMatrix(const mat3& m);
//Outside:
inline vec2 operator*(const vec2& a, float c)
{
vec2 r;
r.v[0] = a.v[0]*c;
r.v[1] = a.v[1]*c;
return r;
}
inline vec2 operator*(float c, const vec2& a)
{
return a*c;
}
inline vec3 operator*(const vec3& a, float c)
{
vec3 r;
r.v[0] = a.v[0]*c;
r.v[1] = a.v[1]*c;
r.v[2] = a.v[2]*c;
return r;
}
inline vec3 operator*(float c, const vec3& a)
{
return a*c;
}
inline vec4 operator*(const vec4& a, float c)
{
vec4 r;
r.v[0] = a.v[0]*c;
r.v[1] = a.v[1]*c;
r.v[2] = a.v[2]*c;
r.v[3] = a.v[3]*c;
return r;
}
inline vec4 operator*(float c,const vec4& a)
{
return a*c;
}
//============= vec2 ================
template<typename TYPENAME>
inline tvec2<TYPENAME>& tvec2<TYPENAME>::operator=(const tvec2<TYPENAME>& vc)
{
//Self-assignment is ok here
v[0] = vc.v[0];
v[1] = vc.v[1];
return *this;
}
template<typename TYPENAME>
inline bool tvec2<TYPENAME>::operator==(const tvec2<TYPENAME>& vc) const
{
if (IsFloatEqual(static_cast<float>(v[0]), static_cast<float>(vc.v[0])) &&
IsFloatEqual(static_cast<float>(v[1]), static_cast<float>(vc.v[1])))
{
return true;
}
return false;
}
template<typename TYPENAME>
inline bool tvec2<TYPENAME>::operator!=(const tvec2<TYPENAME>& vc) const
{
return !(*this == vc);
}
template<typename TYPENAME>
inline tvec2<TYPENAME>& tvec2<TYPENAME>::operator+=(const tvec2<TYPENAME>& vc)
{
v[0] += vc.v[0];
v[1] += vc.v[1];
return *this;
}
template<typename TYPENAME>
inline tvec2<TYPENAME> tvec2<TYPENAME>::operator+(const tvec2<TYPENAME>& a) const
{
tvec2<TYPENAME> r = *this;
r += a;
return r;
}
template<typename TYPENAME>
inline tvec2<TYPENAME>& tvec2<TYPENAME>::operator-=(const tvec2<TYPENAME>& vc)
{
v[0] -= vc.v[0];
v[1] -= vc.v[1];
return *this;
}
template<typename TYPENAME>
inline tvec2<TYPENAME> tvec2<TYPENAME>::operator-(const tvec2<TYPENAME>& a) const
{
tvec2<TYPENAME> r = *this;
r -= a;
return r;
}
template<typename TYPENAME>
inline tvec2<TYPENAME> tvec2<TYPENAME>::operator-()
{
tvec2<TYPENAME> r = *this;
r.v[0] = -v[0];
r.v[1] = -v[1];
return r;
}
template<typename TYPENAME>
inline tvec2<TYPENAME>& tvec2<TYPENAME>::operator*=(TYPENAME c)
{
v[0] *= c;
v[1] *= c;
return *this;
}
inline vec2 Normalize(const vec2& a)
{
vec2 r;
float d = a.v[0]*a.v[0]+a.v[1]*a.v[1];
if (IsFloatEqual(d, 0.0f))
{
r.v[0] = 0.0f;
r.v[1] = 0.0f;
return r;
}
else
{
d = sqrtf(d);
r.v[0] = a.v[0]/d;
r.v[1] = a.v[1]/d;
return r;
}
}
inline float Length(const vec2& a)
{
return sqrtf(a.v[0]*a.v[0] + a.v[1]*a.v[1]);
}
inline float DotProduct(const vec2& a,const vec2& b)
{
return a.v[0]*b.v[0] + a.v[1]*b.v[1];
}
//============= vec3 ================
template<typename TYPENAME1>
inline tvec3<TYPENAME1>::tvec3()
{
v[0] = 0;
v[1] = 0;
v[2] = 0;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>::tvec3(TYPENAME1 x, TYPENAME1 y, TYPENAME1 z)
{
v[0] = x;
v[1] = y;
v[2] = z;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>::tvec3(const tvec2<TYPENAME1>& vc, TYPENAME1 z)
{
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = z;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>::tvec3(const tvec3<TYPENAME1>& vc)
{
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>::tvec3(const tvec4<TYPENAME1>& vc)
{
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
}
template<typename TYPENAME1>
inline bool tvec3<TYPENAME1>::operator==(const tvec3<TYPENAME1>& vc) const
{
if (IsFloatEqual(static_cast<float>(v[0]), static_cast<float>(vc.v[0])) &&
IsFloatEqual(static_cast<float>(v[1]), static_cast<float>(vc.v[1])) &&
IsFloatEqual(static_cast<float>(v[2]), static_cast<float>(vc.v[2])))
{
return true;
}
return false;
}
template<typename TYPENAME>
inline bool tvec3<TYPENAME>::operator!=(const tvec3<TYPENAME>& vc) const
{
return !(*this == vc);
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>& tvec3<TYPENAME1>::operator=(const tvec3<TYPENAME1>& vc)
{
//Self-assignment is ok here
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
return *this;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>& tvec3<TYPENAME1>::operator+=(const tvec3<TYPENAME1>& vc)
{
v[0] += vc.v[0];
v[1] += vc.v[1];
v[2] += vc.v[2];
return *this;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>& tvec3<TYPENAME1>::operator-=(const tvec3<TYPENAME1>& vc)
{
v[0] -= vc.v[0];
v[1] -= vc.v[1];
v[2] -= vc.v[2];
return *this;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1> tvec3<TYPENAME1>::operator+(const tvec3<TYPENAME1>& a) const
{
tvec3<TYPENAME1> r = *this;
r += a;
return r;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1> tvec3<TYPENAME1>::operator-(const tvec3<TYPENAME1>& a) const
{
tvec3<TYPENAME1> r = *this;
r -= a;
return r;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1> tvec3<TYPENAME1>::operator-()
{
tvec3<TYPENAME1> r = *this;
r.v[0] = -v[0];
r.v[1] = -v[1];
r.v[2] = -v[2];
return r;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1>& tvec3<TYPENAME1>::operator*=(TYPENAME1 c)
{
v[0] *= c;
v[1] *= c;
v[2] *= c;
return *this;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1> tvec3<TYPENAME1>::operator*(const tmat3<TYPENAME1>& mt) const
{
tvec3<TYPENAME1> r = *this;
r.v[0] = v[0]*mt.m[0] + v[1]*mt.m[1] + v[2]*mt.m[2];
r.v[1] = v[0]*mt.m[3] + v[1]*mt.m[4] + v[2]*mt.m[5];
r.v[2] = v[0]*mt.m[6] + v[1]*mt.m[7] + v[2]*mt.m[8];
return r;
}
inline float DotProduct(const vec3& a,const vec3& b)
{
return a.v[0]*b.v[0]+a.v[1]*b.v[1]+a.v[2]*b.v[2];
}
inline vec3 CrossProduct(const vec3& a,const vec3& b)
{
vec3 r;
r.v[0] = a.v[1]*b.v[2] - a.v[2]*b.v[1];
r.v[1] = a.v[2]*b.v[0] - a.v[0]*b.v[2];
r.v[2] = a.v[0]*b.v[1] - a.v[1]*b.v[0];
return r;
}
inline vec3 Normalize(const vec3& a)
{
vec3 r;
float d = a.v[0]*a.v[0]+a.v[1]*a.v[1]+a.v[2]*a.v[2];
if (IsFloatEqual(d,0.0f))
{
r.v[0] = 0.0f;
r.v[1] = 0.0f;
r.v[2] = 0.0f;
return r;
}
else
{
d = sqrtf(d);
r.v[0] = a.v[0]/d;
r.v[1] = a.v[1]/d;
r.v[2] = a.v[2]/d;
return r;
}
}
inline float Length(const vec3& a)
{
return sqrtf(a.v[0]*a.v[0] + a.v[1]*a.v[1] + a.v[2]*a.v[2]);
}
//============= vec4 ================
template<typename TYPENAME1>
inline tvec4<TYPENAME1>::tvec4()
{
v[0] = 0;
v[1] = 0;
v[2] = 0;
v[3] = 1;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>::tvec4(TYPENAME1 x, TYPENAME1 y, TYPENAME1 z, TYPENAME1 w)
{
v[0] = x;
v[1] = y;
v[2] = z;
v[3] = w;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>::tvec4(const tvec4<TYPENAME1>& vc)
{
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
v[3] = vc.v[3];
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>::tvec4(const tvec3<TYPENAME1>& vc)
{
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
v[3] = 0.0f;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>::tvec4(const tmat3<TYPENAME1>& m)
{
TYPENAME1 f;
if (m.m[0] >= m.m[4] && m.m[0] >= m.m[8])
{
f = sqrtf(1.0f + m.m[0] - m.m[4] - m.m[8]);
if (f != 0)
{
v[3] = (m.m[5] - m.m[7]) / (f + f);
v[0] = f/2;
v[1] = (m.m[3] + m.m[1]) / (f + f);
v[2] = (m.m[6] + m.m[2]) / (f + f);
}
else
{
v[3] = 1;
v[2] = 0;
v[1] = 0;
v[0] = 0;
}
}
if (m.m[4] >= m.m[0] && m.m[4] >= m.m[8])
{
f = sqrtf(1.0f + m.m[4] - m.m[0] - m.m[8]);
if (f != 0)
{
v[3] = (m.m[6] - m.m[2]) / (f + f);
v[1] = f/2;
v[0] = (m.m[1] + m.m[3]) / (f + f);
v[2] = (m.m[7] + m.m[5]) / (f + f);
}
else
{
v[3] = 1;
v[2] = 0;
v[1] = 0;
v[0] = 0;
}
}
if (m.m[8] >= m.m[4] && m.m[8] >= m.m[0])
{
f = sqrtf(1.0f + m.m[8] - m.m[2]);
if (f != 0)
{
v[3] = (m.m[1] - m.m[3]) / (f + f);
v[2] = f/2;
v[1] = (m.m[5] + m.m[7]) / (f + f);
v[0] = (m.m[6] + m.m[2]) / (f + f);
}
else
{
v[3] = 1;
v[2] = 0;
v[1] = 0;
v[0] = 0;
}
}
}
template<typename TYPENAME1>
inline bool tvec4<TYPENAME1>::operator==(const tvec4<TYPENAME1>& vc) const
{
if (IsFloatEqual(static_cast<float>(v[0]), static_cast<float>(vc.v[0])) &&
IsFloatEqual(static_cast<float>(v[1]), static_cast<float>(vc.v[1])) &&
IsFloatEqual(static_cast<float>(v[2]), static_cast<float>(vc.v[2])) &&
IsFloatEqual(static_cast<float>(v[3]), static_cast<float>(vc.v[3])))
{
return true;
}
return false;
}
template<typename TYPENAME1>
inline bool tvec4<TYPENAME1>::operator!=(const tvec4<TYPENAME1>& vc) const
{
return !(*this == vc);
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>& tvec4<TYPENAME1>::operator=(const tvec4<TYPENAME1>& vc)
{
//Self-assignment is not actual here...
v[0] = vc.v[0];
v[1] = vc.v[1];
v[2] = vc.v[2];
v[3] = vc.v[3];
return *this;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>& tvec4<TYPENAME1>::operator+=(const tvec4<TYPENAME1>& vc)
{
v[0] += vc.v[0];
v[1] += vc.v[1];
v[2] += vc.v[2];
v[3] += vc.v[3];
return *this;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>& tvec4<TYPENAME1>::operator-=(const tvec4<TYPENAME1>& vc)
{
v[0] -= vc.v[0];
v[1] -= vc.v[1];
v[2] -= vc.v[2];
v[3] -= vc.v[3];
return *this;
}
template<typename TYPENAME1>
inline const tvec4<TYPENAME1> tvec4<TYPENAME1>::operator+(const tvec4<TYPENAME1>& a) const
{
tvec4<TYPENAME1> r = *this;
r += a;
return r;
}
template<typename TYPENAME1>
inline const tvec4<TYPENAME1> tvec4<TYPENAME1>::operator-(const tvec4<TYPENAME1>& a) const
{
tvec4<TYPENAME1> r = *this;
r -= a;
return r;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>& tvec4<TYPENAME1>::operator*=(TYPENAME1 c)
{
v[0] *= c;
v[1] *= c;
v[2] *= c;
v[3] *= c;
return *this;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1>& tvec4<TYPENAME1>::operator*=(const tvec4<TYPENAME1>& q)
{
TYPENAME1 A = (v[3] + v[0]) * (q.v[3] + q.v[0]);
TYPENAME1 B = (v[2] - v[1]) * (q.v[1] - q.v[2]);
TYPENAME1 C = (v[0] - v[3]) * (q.v[1] + q.v[2]);
TYPENAME1 D = (v[1] + v[2]) * (q.v[0] - q.v[3]);
TYPENAME1 E = (v[0] + v[2]) * (q.v[0] + q.v[1]);
TYPENAME1 F = (v[0] - v[2]) * (q.v[0] - q.v[1]);
TYPENAME1 G = (v[3] + v[1]) * (q.v[3] - q.v[2]);
TYPENAME1 H = (v[3] - v[1]) * (q.v[3] + q.v[2]);
v[0] = A - ( E + F + G + H) * 0.5f;
v[1] =-C + ( E - F + G - H) * 0.5f;
v[2] =-D + ( E - F - G + H) * 0.5f;
v[3] = B + (-E - F + G + H) * 0.5f;
return *this;
}
template<typename TYPENAME1>
inline tvec4<TYPENAME1> tvec4<TYPENAME1>::operator*(const tvec4<TYPENAME1>& q) const
{
tvec4<TYPENAME1> r = *this;
r *= q;
return r;
}
inline vec4 InverseQuat(const vec4& q)
{
float n;
vec4 r;
n = (q.v[0]*q.v[0]+q.v[1]*q.v[1]+q.v[2]*q.v[2]+q.v[3]*q.v[3]);
if (n!=0.0f)
{
r.v[0] = -q.v[0] / n;
r.v[1] = -q.v[1] / n;
r.v[2] = -q.v[2] / n;
r.v[3] = q.v[3] / n;
}
else
{
r.v[0] = 0.0f;
r.v[1] = 0.0f;
r.v[2] = 0.0f;
r.v[3] = 1.0f;
};
return r;
}
inline vec4 NormalizeQuat(const vec4& q)
{
float n;
vec4 r;
n = (q.v[0]*q.v[0]+q.v[1]*q.v[1]+q.v[2]*q.v[2]+q.v[3]*q.v[3]);
if (n!=0.0f)
{
r.v[0] = q.v[0] / n;
r.v[1] = q.v[1] / n;
r.v[2] = q.v[2] / n;
r.v[3] = q.v[3] / n;
}
return r;
}
//========== mat2 ===========
template<typename TYPENAME1>
inline tmat2<TYPENAME1>::tmat2()
{
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 1;
}
template<typename TYPENAME1>
inline tmat2<TYPENAME1>::tmat2(TYPENAME1 alpha)
{
m[0] = cosf(alpha);
m[1] = sinf(alpha);
m[2] = -sinf(alpha);
m[3] = cosf(alpha);
}
template<typename TYPENAME1>
inline tmat2<TYPENAME1>::tmat2(const tmat2<TYPENAME1>& mt)
{
m[0] = mt.m[0];
m[1] = mt.m[1];
m[2] = mt.m[2];
m[3] = mt.m[3];
}
template<typename TYPENAME1>
inline bool tmat2<TYPENAME1>::operator==(const tmat2<TYPENAME1>& mt) const
{
if (IsFloatEqual(static_cast<float>(m[0]), static_cast<float>(mt.m[0])) &&
IsFloatEqual(static_cast<float>(m[1]), static_cast<float>(mt.m[1])) &&
IsFloatEqual(static_cast<float>(m[2]), static_cast<float>(mt.m[2])) &&
IsFloatEqual(static_cast<float>(m[3]), static_cast<float>(mt.m[3])))
{
return true;
}
return false;
}
template<typename TYPENAME1>
inline bool tmat2<TYPENAME1>::operator!=(const tmat2<TYPENAME1>& mt) const
{
return !(*this == mt);
}
template<typename TYPENAME1>
inline tmat2<TYPENAME1>& tmat2<TYPENAME1>::operator=(const tmat2<TYPENAME1>& mt)
{
//Self-assignment is not actual here....
m[0] = mt.m[0];
m[1] = mt.m[1];
m[2] = mt.m[2];
m[3] = mt.m[3];
return *this;
}
template<typename TYPENAME1>
inline tmat2<TYPENAME1>& tmat2<TYPENAME1>::operator*=(const tmat2<TYPENAME1>& mt)
{
tmat2<TYPENAME1> a(*this);
m[0] = a.m[0]*mt.m[0] + a.m[2]*mt.m[1];
m[1] = a.m[1]*mt.m[0] + a.m[3]*mt.m[1];
m[2] = a.m[0]*mt.m[2] + a.m[2]*mt.m[3];
m[3] = a.m[1]*mt.m[2] + a.m[3]*mt.m[3];
return *this;
}
template<typename TYPENAME1>
inline tmat2<TYPENAME1> tmat2<TYPENAME1>::operator*(const tmat2<TYPENAME1>& mt)
{
tmat2<TYPENAME1> r = *this;
r *= mt;
return r;
}
template<typename TYPENAME1>
inline tvec2<TYPENAME1> tmat2<TYPENAME1>::operator*(const tvec2<TYPENAME1>& vc) const
{
tvec2<TYPENAME1> r;
r.v[0] = m[0]*vc.v[0] + m[2]*vc.v[1];
r.v[1] = m[1]*vc.v[0] + m[3]*vc.v[1];
return r;
}
//========== mat3 ===========
template<typename TYPENAME1>
inline tmat3<TYPENAME1>::tmat3()
{
m[0] = 1;
m[1] = 0;
m[2] = 0;
m[3] = 0;
m[4] = 1;
m[5] = 0;
m[6] = 0;
m[7] = 0;
m[8] = 1;
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1>::tmat3(const tvec3<TYPENAME1>& col1, const tvec3<TYPENAME1>& col2, const tvec3<TYPENAME1>& col3)
{
m[0] = col1.v[0];
m[1] = col1.v[1];
m[2] = col1.v[2];
m[3] = col2.v[0];
m[4] = col2.v[1];
m[5] = col2.v[2];
m[6] = col3.v[0];
m[7] = col3.v[1];
m[8] = col3.v[2];
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1>::tmat3(const tmat3<TYPENAME1>& mt)
{
m[0] = mt.m[0];
m[1] = mt.m[1];
m[2] = mt.m[2];
m[3] = mt.m[3];
m[4] = mt.m[4];
m[5] = mt.m[5];
m[6] = mt.m[6];
m[7] = mt.m[7];
m[8] = mt.m[8];
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1>::tmat3(const tvec4<TYPENAME1>& q)
{
TYPENAME1 wx, wy, wz, xx, yy, yz, xy, xz, zz,s,x2,y2,z2;
s=2.0f/(q.v[0]*q.v[0]+q.v[1]*q.v[1]+q.v[2]*q.v[2]+q.v[3]*q.v[3]);
x2=q.v[0]*s;
y2=q.v[1]*s;
z2=q.v[2]*s;
wx=q.v[3]*x2; wy=q.v[3]*y2; wz=q.v[3]*z2;
xx=q.v[0]*x2; xy=q.v[1]*x2; xz=q.v[2]*x2;
yy=q.v[1]*y2; yz=q.v[2]*y2;
zz=q.v[2]*z2;
m[0] = 1.0f - (yy + zz);
m[1] = xy + wz;
m[2] = xz - wy;
m[3] = xy - wz;
m[4] = 1.0f - (xx + zz);
m[5] = yz + wx;
m[6] = xz + wy;
m[7] = yz - wx;
m[8] = 1.0f - (xx + yy);
}
template<typename TYPENAME1>
inline bool tmat3<TYPENAME1>::operator==(const tmat3<TYPENAME1>& mt) const
{
if (IsFloatEqual(m[0], mt.m[0]) &&
IsFloatEqual(m[1], mt.m[1]) &&
IsFloatEqual(m[2], mt.m[2]) &&
IsFloatEqual(m[3], mt.m[3]) &&
IsFloatEqual(m[4], mt.m[4]) &&
IsFloatEqual(m[5], mt.m[5]) &&
IsFloatEqual(m[6], mt.m[6]) &&
IsFloatEqual(m[7], mt.m[7]) &&
IsFloatEqual(m[8], mt.m[8]))
{
return true;
}
return false;
}
template<typename TYPENAME1>
inline bool tmat3<TYPENAME1>::operator!=(const tmat3<TYPENAME1>& mt) const
{
return !(*this == mt);
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1>& tmat3<TYPENAME1>::operator=(const tmat3<TYPENAME1>& mt)
{
//Self-assignment is not actual here....
m[0] = mt.m[0];
m[1] = mt.m[1];
m[2] = mt.m[2];
m[3] = mt.m[3];
m[4] = mt.m[4];
m[5] = mt.m[5];
m[6] = mt.m[6];
m[7] = mt.m[7];
m[8] = mt.m[8];
return *this;
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1>& tmat3<TYPENAME1>::operator*=(const tmat3<TYPENAME1>& mt)
{
tmat3<TYPENAME1> a(*this);
m[0] = a.m[0]*mt.m[0] + a.m[1]*mt.m[3] + a.m[2]*mt.m[6];
m[1] = a.m[0]*mt.m[1] + a.m[1]*mt.m[4] + a.m[2]*mt.m[7];
m[2] = a.m[0]*mt.m[2] + a.m[1]*mt.m[5] + a.m[2]*mt.m[8];
m[3] = a.m[3]*mt.m[0] + a.m[4]*mt.m[3] + a.m[5]*mt.m[6];
m[4] = a.m[3]*mt.m[1] + a.m[4]*mt.m[4] + a.m[5]*mt.m[7];
m[5] = a.m[3]*mt.m[2] + a.m[4]*mt.m[5] + a.m[5]*mt.m[8];
m[6] = a.m[6]*mt.m[0] + a.m[7]*mt.m[3] + a.m[8]*mt.m[6];
m[7] = a.m[6]*mt.m[1] + a.m[7]*mt.m[4] + a.m[8]*mt.m[7];
m[8] = a.m[6]*mt.m[2] + a.m[7]*mt.m[5] + a.m[8]*mt.m[8];
return *this;
}
template<typename TYPENAME1>
inline tmat3<TYPENAME1> tmat3<TYPENAME1>::operator*(const tmat3<TYPENAME1>& mt)
{
tmat3<TYPENAME1> r = *this;
r *= mt;
return r;
}
template<typename TYPENAME1>
inline tvec3<TYPENAME1> tmat3<TYPENAME1>::operator*(const tvec3<TYPENAME1>& vc) const
{
tvec3<TYPENAME1> r;
r.v[0] = m[0]*vc.v[0] + m[3]*vc.v[1] + m[6]*vc.v[2];
r.v[1] = m[1]*vc.v[0] + m[4]*vc.v[1] + m[7]*vc.v[2];
r.v[2] = m[2]*vc.v[0] + m[5]*vc.v[1] + m[8]*vc.v[2];
return r;
}
mat3 TransposeMatrix(const mat3& m);
mat3 InverseMatrix(const mat3& m);
} //namespace SE
#endif