Explorar el Código

math: implement all Euler conversions for 3×3 matrices.

legacy
Sam Hocevar sam hace 12 años
padre
commit
f30105e675
Se han modificado 2 ficheros con 150 adiciones y 52 borrados
  1. +51
    -11
      src/lol/math/vector.h
  2. +99
    -41
      src/math/vector.cpp

+ 51
- 11
src/lol/math/vector.h Ver fichero

@@ -1676,8 +1676,32 @@ template <typename T> struct Mat3
static Mat3<T> scale(Vec3<T> v);
static Mat3<T> rotate(T angle, T x, T y, T z);
static Mat3<T> rotate(T angle, Vec3<T> v);
static Mat3<T> fromeuler(T x, T y, T z);
static Mat3<T> fromeuler(Vec3<T> const &v);

static Mat3<T> fromeuler_xyz(Vec3<T> const &v);
static Mat3<T> fromeuler_xzy(Vec3<T> const &v);
static Mat3<T> fromeuler_yxz(Vec3<T> const &v);
static Mat3<T> fromeuler_yzx(Vec3<T> const &v);
static Mat3<T> fromeuler_zxy(Vec3<T> const &v);
static Mat3<T> fromeuler_zyx(Vec3<T> const &v);
static Mat3<T> fromeuler_xyz(T phi, T theta, T psi);
static Mat3<T> fromeuler_xzy(T phi, T theta, T psi);
static Mat3<T> fromeuler_yxz(T phi, T theta, T psi);
static Mat3<T> fromeuler_yzx(T phi, T theta, T psi);
static Mat3<T> fromeuler_zxy(T phi, T theta, T psi);
static Mat3<T> fromeuler_zyx(T phi, T theta, T psi);

static Mat3<T> fromeuler_xyx(Vec3<T> const &v);
static Mat3<T> fromeuler_xzx(Vec3<T> const &v);
static Mat3<T> fromeuler_yxy(Vec3<T> const &v);
static Mat3<T> fromeuler_yzy(Vec3<T> const &v);
static Mat3<T> fromeuler_zxz(Vec3<T> const &v);
static Mat3<T> fromeuler_zyz(Vec3<T> const &v);
static Mat3<T> fromeuler_xyx(T phi, T theta, T psi);
static Mat3<T> fromeuler_xzx(T phi, T theta, T psi);
static Mat3<T> fromeuler_yxy(T phi, T theta, T psi);
static Mat3<T> fromeuler_yzy(T phi, T theta, T psi);
static Mat3<T> fromeuler_zxz(T phi, T theta, T psi);
static Mat3<T> fromeuler_zyz(T phi, T theta, T psi);

static inline Mat3<T> rotate(Mat3<T> mat, T angle, Vec3<T> v)
{
@@ -1816,15 +1840,31 @@ template <typename T> struct Mat4
return rotate(angle, v) * mat;
}

static inline Mat4<T> fromeuler(T x, T y, T z)
{
return Mat4<T>(Mat3<T>::fromeuler(x, y, z), (T)1);
}

static inline Mat4<T> fromeuler(Vec3<T> const &v)
{
return Mat4<T>(Mat3<T>::fromeuler(v), (T)1);
}
static Mat4<T> fromeuler_xyz(Vec3<T> const &v);
static Mat4<T> fromeuler_xzy(Vec3<T> const &v);
static Mat4<T> fromeuler_yxz(Vec3<T> const &v);
static Mat4<T> fromeuler_yzx(Vec3<T> const &v);
static Mat4<T> fromeuler_zxy(Vec3<T> const &v);
static Mat4<T> fromeuler_zyx(Vec3<T> const &v);
static Mat4<T> fromeuler_xyz(T phi, T theta, T psi);
static Mat4<T> fromeuler_xzy(T phi, T theta, T psi);
static Mat4<T> fromeuler_yxz(T phi, T theta, T psi);
static Mat4<T> fromeuler_yzx(T phi, T theta, T psi);
static Mat4<T> fromeuler_zxy(T phi, T theta, T psi);
static Mat4<T> fromeuler_zyx(T phi, T theta, T psi);

static Mat4<T> fromeuler_xyx(Vec3<T> const &v);
static Mat4<T> fromeuler_xzx(Vec3<T> const &v);
static Mat4<T> fromeuler_yxy(Vec3<T> const &v);
static Mat4<T> fromeuler_yzy(Vec3<T> const &v);
static Mat4<T> fromeuler_zxz(Vec3<T> const &v);
static Mat4<T> fromeuler_zyz(Vec3<T> const &v);
static Mat4<T> fromeuler_xyx(T phi, T theta, T psi);
static Mat4<T> fromeuler_xzx(T phi, T theta, T psi);
static Mat4<T> fromeuler_yxy(T phi, T theta, T psi);
static Mat4<T> fromeuler_yzy(T phi, T theta, T psi);
static Mat4<T> fromeuler_zxz(T phi, T theta, T psi);
static Mat4<T> fromeuler_zyz(T phi, T theta, T psi);

/* Helpers for view matrices */
static Mat4<T> lookat(Vec3<T> eye, Vec3<T> center, Vec3<T> up);


+ 99
- 41
src/math/vector.cpp Ver fichero

@@ -506,36 +506,74 @@ template<> vec3 vec3::toeuler(quat const &q)
return (180.0f / M_PI / n) * ret;
}

template<> mat3 mat3::fromeuler(vec3 const &v)
static inline mat3 mat3_fromeuler_generic(vec3 const &v, int i, int j, int k)
{
using std::sin;
using std::cos;

mat3 ret;

vec3 radians = (M_PI / 180.0f) * v;
float sx = sin(radians.x), cx = cos(radians.x);
float sy = sin(radians.y), cy = cos(radians.y);
float sz = sin(radians.z), cz = cos(radians.z);
float s0 = sin(radians[0]), c0 = cos(radians[0]);
float s1 = sin(radians[1]), c1 = cos(radians[1]);
float s2 = sin(radians[2]), c2 = cos(radians[2]);

ret[0][0] = cy * cz;
ret[1][0] = - cx * sz + sx * sy * cz;
ret[2][0] = sx * sz + cx * sy * cz;
if (k == i)
{
k = 3 - i - j;

ret[0][1] = cy * sz;
ret[1][1] = cx * cz + sx * sy * sz;
ret[2][1] = - sx * cz + cx * sy * sz;
ret[i][i] = c1;
ret[j][i] = s1 * s2;
ret[i][j] = s0 * s1;
ret[j][j] = c0 * c2 - s0 * c1 * s2;
ret[k][k] = - s0 * s2 + c0 * c1 * c2;

ret[0][2] = - sy;
ret[1][2] = sx * cy;
ret[2][2] = cx * cy;
if ((2 + i - j) % 3)
{
ret[k][i] = s1 * c2;
ret[k][j] = - c0 * s2 - s0 * c1 * c2;
ret[i][k] = - c0 * s1;
ret[j][k] = s0 * c2 + c0 * c1 * s2;
}
else
{
ret[k][i] = - s1 * c2;
ret[k][j] = c0 * s2 + s0 * c1 * c2;
ret[i][k] = c0 * s1;
ret[j][k] = - s0 * c2 - c0 * c1 * s2;
}
}
else
{
ret[i][i] = c1 * c2;
ret[k][k] = c0 * c1;

return ret;
}
if ((2 + i - j) % 3)
{
ret[j][i] = - c1 * s2;
ret[k][i] = s1;

template<> mat3 mat3::fromeuler(float x, float y, float z)
{
return mat3::fromeuler(vec3(x, y, z));
ret[i][j] = c0 * s2 + s0 * s1 * c2;
ret[j][j] = c0 * c2 - s0 * s1 * s2;
ret[k][j] = - s0 * c1;

ret[i][k] = s0 * s2 - c0 * s1 * c2;
ret[j][k] = s0 * c2 + c0 * s1 * s2;
}
else
{
ret[j][i] = c1 * s2;
ret[k][i] = - s1;

ret[i][j] = - c0 * s2 + s0 * s1 * c2;
ret[j][j] = c0 * c2 + s0 * s1 * s2;
ret[k][j] = s0 * c1;

ret[i][k] = s0 * s2 + c0 * s1 * c2;
ret[j][k] = - s0 * c2 + c0 * s1 * s2;
}
}

return ret;
}

static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
@@ -550,15 +588,15 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)

quat ret;

if (i == k)
if (k == i)
{
k = 3 - i - j;

ret[0] = c1 * (c0 * c2 - s0 * s2);
ret[1 + i] = c1 * (c0 * s2 + s0 * c2);
ret[1 + j] = s1 * (c0 * c2 + s0 * s2);
if ((2 + i - j) % 3)
ret[4 - i - j] = s1 * (s0 * c2 - c0 * s2);
else
ret[4 - i - j] = s1 * (c0 * s2 - s0 * c2);
ret[1 + k] = ((2 + i - j) % 3) ? s1 * (s0 * c2 - c0 * s2)
: s1 * (c0 * s2 - s0 * c2);
}
else
{
@@ -573,13 +611,13 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
ret[0] = v1[0];
ret[1 + i] = v1[1];
ret[1 + j] = v1[2];
ret[4 - i - j] = v1[3];
ret[1 + k] = v1[3];
}

return ret;
}

#define QUAT_FROMEULER_GENERIC(name, i, j, k) \
#define DEFINE_FROMEULER_GENERIC(name, i, j, k) \
template<> quat quat::fromeuler_##name(vec3 const &v) \
{ \
return quat_fromeuler_generic(v, i, j, k); \
@@ -588,23 +626,43 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
template<> quat quat::fromeuler_##name(float phi, float theta, float psi) \
{ \
return quat::fromeuler_##name(vec3(phi, theta, psi)); \
} \
\
template<> mat3 mat3::fromeuler_##name(vec3 const &v) \
{ \
return mat3_fromeuler_generic(v, i, j, k); \
} \
\
template<> mat3 mat3::fromeuler_##name(float phi, float theta, float psi) \
{ \
return mat3::fromeuler_##name(vec3(phi, theta, psi)); \
} \
\
template<> mat4 mat4::fromeuler_##name(vec3 const &v) \
{ \
return mat4(mat3_fromeuler_generic(v, i, j, k), 1.f); \
} \
\
template<> mat4 mat4::fromeuler_##name(float phi, float theta, float psi) \
{ \
return mat4::fromeuler_##name(vec3(phi, theta, psi)); \
}

QUAT_FROMEULER_GENERIC(xyx, 0, 1, 0)
QUAT_FROMEULER_GENERIC(xzx, 0, 2, 0)
QUAT_FROMEULER_GENERIC(yxy, 1, 0, 1)
QUAT_FROMEULER_GENERIC(yzy, 1, 2, 1)
QUAT_FROMEULER_GENERIC(zxz, 2, 0, 2)
QUAT_FROMEULER_GENERIC(zyz, 2, 1, 2)

QUAT_FROMEULER_GENERIC(xyz, 0, 1, 2)
QUAT_FROMEULER_GENERIC(xzy, 0, 2, 1)
QUAT_FROMEULER_GENERIC(yxz, 1, 0, 2)
QUAT_FROMEULER_GENERIC(yzx, 1, 2, 0)
QUAT_FROMEULER_GENERIC(zxy, 2, 0, 1)
QUAT_FROMEULER_GENERIC(zyx, 2, 1, 0)

#undef QUAT_FROMEULER_GENERIC
DEFINE_FROMEULER_GENERIC(xyx, 0, 1, 0)
DEFINE_FROMEULER_GENERIC(xzx, 0, 2, 0)
DEFINE_FROMEULER_GENERIC(yxy, 1, 0, 1)
DEFINE_FROMEULER_GENERIC(yzy, 1, 2, 1)
DEFINE_FROMEULER_GENERIC(zxz, 2, 0, 2)
DEFINE_FROMEULER_GENERIC(zyz, 2, 1, 2)
DEFINE_FROMEULER_GENERIC(xyz, 0, 1, 2)
DEFINE_FROMEULER_GENERIC(xzy, 0, 2, 1)
DEFINE_FROMEULER_GENERIC(yxz, 1, 0, 2)
DEFINE_FROMEULER_GENERIC(yzx, 1, 2, 0)
DEFINE_FROMEULER_GENERIC(zxy, 2, 0, 1)
DEFINE_FROMEULER_GENERIC(zyx, 2, 1, 0)
#undef DEFINE_FROMEULER_GENERIC

template<> mat4 mat4::lookat(vec3 eye, vec3 center, vec3 up)
{


Cargando…
Cancelar
Guardar