Quellcode durchsuchen

math: implement vec3::toeuler_* for Tait-Bryan angles.

undefined
Sam Hocevar vor 11 Jahren
Ursprung
Commit
6adf553806
3 geänderte Dateien mit 49 neuen und 8 gelöschten Zeilen
  1. +1
    -1
      src/camera.cpp
  2. +13
    -1
      src/lol/math/vector.h
  3. +35
    -6
      src/math/vector.cpp

+ 1
- 1
src/camera.cpp Datei anzeigen

@@ -210,7 +210,7 @@ vec3 Camera::GetUp()

vec3 Camera::GetRotationEuler()
{
return vec3::toeuler(GetRotation());
return vec3::toeuler_zyx(GetRotation());
}

quat Camera::GetRotation()


+ 13
- 1
src/lol/math/vector.h Datei anzeigen

@@ -503,7 +503,19 @@ template <typename T> struct Vec3 : BVec3<T>
explicit inline Vec3(XVec3<U, N> const &v)
: BVec3<T>(v[0], v[1], v[2]) {}

static Vec3<T> toeuler(Quat<T> const &q);
static Vec3<T> toeuler_xyx(Quat<T> const &q);
static Vec3<T> toeuler_xzx(Quat<T> const &q);
static Vec3<T> toeuler_yxy(Quat<T> const &q);
static Vec3<T> toeuler_yzy(Quat<T> const &q);
static Vec3<T> toeuler_zxz(Quat<T> const &q);
static Vec3<T> toeuler_zyz(Quat<T> const &q);

static Vec3<T> toeuler_xyz(Quat<T> const &q);
static Vec3<T> toeuler_xzy(Quat<T> const &q);
static Vec3<T> toeuler_yxz(Quat<T> const &q);
static Vec3<T> toeuler_yzx(Quat<T> const &q);
static Vec3<T> toeuler_zxy(Quat<T> const &q);
static Vec3<T> toeuler_zyx(Quat<T> const &q);

LOL_MEMBER_OPS(Vec3, x)



+ 35
- 6
src/math/vector.cpp Datei anzeigen

@@ -530,18 +530,38 @@ template<> quat slerp(quat const &qa, quat const &qb, float f)
return qa * (s0 * d) + qb * (s1 * d);
}

template<> vec3 vec3::toeuler(quat const &q)
static inline vec3 quat_toeuler_generic(quat const &q, int i, int j, int k)
{
float n = norm(q);

if (!n)
return vec3(0.f);

vec3 ret(atan2(2.f * (q.w * q.x + q.y * q.z),
1.f - 2.f * (q.x * q.x + q.y * q.y)),
asin(2.f * (q.w * q.y - q.z * q.x)),
atan2(2.f * (q.w * q.z + q.y * q.x),
1.f - 2.f * (q.z * q.z + q.y * q.y)));
vec3 v(q.x, q.y, q.z), ret;

if (i != k)
{
if ((2 + i - j) % 3)
{
ret[0] = atan2(2.f * (q.w * v[i] - v[j] * v[k]),
1.f - 2.f * (v[i] * v[i] + v[j] * v[j]));
ret[1] = asin(2.f * (q.w * v[j] + v[i] * v[k]));
ret[2] = atan2(2.f * (q.w * v[k] - v[j] * v[i]),
1.f - 2.f * (v[k] * v[k] + v[j] * v[j]));
}
else
{
ret[0] = atan2(2.f * (q.w * v[i] + v[j] * v[k]),
1.f - 2.f * (v[i] * v[i] + v[j] * v[j]));
ret[1] = asin(2.f * (q.w * v[j] - v[i] * v[k]));
ret[2] = atan2(2.f * (q.w * v[k] + v[j] * v[i]),
1.f - 2.f * (v[k] * v[k] + v[j] * v[j]));
}
}
else
{
/* FIXME: TODO */
}

return (180.0f / F_PI / n) * ret;
}
@@ -653,6 +673,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
}

#define DEFINE_FROMEULER_GENERIC(name, i, j, k) \
/* Create quaternions from Euler angles */ \
template<> quat quat::fromeuler_##name(vec3 const &v) \
{ \
return quat_fromeuler_generic(v, i, j, k); \
@@ -663,6 +684,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
return quat::fromeuler_##name(vec3(phi, theta, psi)); \
} \
\
/* Create 3×3 matrices from Euler angles */ \
template<> mat3 mat3::fromeuler_##name(vec3 const &v) \
{ \
return mat3_fromeuler_generic(v, i, j, k); \
@@ -673,6 +695,7 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
return mat3::fromeuler_##name(vec3(phi, theta, psi)); \
} \
\
/* Create 4×4 matrices from Euler angles */ \
template<> mat4 mat4::fromeuler_##name(vec3 const &v) \
{ \
return mat4(mat3_fromeuler_generic(v, i, j, k), 1.f); \
@@ -681,6 +704,12 @@ static inline quat quat_fromeuler_generic(vec3 const &v, int i, int j, int k)
template<> mat4 mat4::fromeuler_##name(float phi, float theta, float psi) \
{ \
return mat4::fromeuler_##name(vec3(phi, theta, psi)); \
} \
\
/* Retrieve Euler angles from a quaternion */ \
template<> vec3 vec3::toeuler_##name(quat const &q) \
{ \
return quat_toeuler_generic(q, i, j, k); \
}

DEFINE_FROMEULER_GENERIC(xyx, 0, 1, 0)


Laden…
Abbrechen
Speichern