Browse Source

math: make the matrix-to-quaternion code shorter.

undefined
Sam Hocevar 9 years ago
parent
commit
977049a7b3
1 changed files with 25 additions and 32 deletions
  1. +25
    -32
      src/math/transform.cpp

+ 25
- 32
src/math/transform.cpp View File

@@ -13,52 +13,45 @@
namespace lol
{

static inline void MatrixToQuat(quat &that, mat3 const &m)
static inline void mat_to_quat(quat &that, mat3 const &m)
{
/* See http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/christian.htm for a version with no branches */
float t = m[0][0] + m[1][1] + m[2][2];
if (t > 0)
{
that.w = 0.5f * std::sqrt(1.0f + t);
float s = 0.25f / that.w;
that.x = s * (m[1][2] - m[2][1]);
that.y = s * (m[2][0] - m[0][2]);
that.z = s * (m[0][1] - m[1][0]);
}
else if (m[0][0] > m[1][1] && m[0][0] > m[2][2])
{
that.x = 0.5f * std::sqrt(1.0f + m[0][0] - m[1][1] - m[2][2]);
float s = 0.25f / that.x;
that.y = s * (m[0][1] + m[1][0]);
that.z = s * (m[2][0] + m[0][2]);
that.w = s * (m[1][2] - m[2][1]);
}
else if (m[1][1] > m[2][2])
float tr = m[0][0] + m[1][1] + m[2][2];

if (tr > 0)
{
that.y = 0.5f * std::sqrt(1.0f - m[0][0] + m[1][1] - m[2][2]);
float s = 0.25f / that.y;
that.x = s * (m[0][1] + m[1][0]);
that.z = s * (m[1][2] + m[2][1]);
that.w = s * (m[2][0] - m[0][2]);
float const p = 0.5f * std::sqrt(1.0f + tr);
float const q = 0.25f / p;

that.w = p;
that.x = q * (m[1][2] - m[2][1]);
that.y = q * (m[2][0] - m[0][2]);
that.z = q * (m[0][1] - m[1][0]);
}
else
{
that.z = 0.5f * std::sqrt(1.0f - m[0][0] - m[1][1] + m[2][2]);
float s = 0.25f / that.z;
that.x = s * (m[2][0] + m[0][2]);
that.y = s * (m[1][2] + m[2][1]);
that.w = s * (m[0][1] - m[1][0]);
int i = (m[0][0] > m[1][1] && m[0][0] > m[2][2]) ? 0
: (m[1][1] > m[2][2]) ? 1
: 2;
int j = (i + 1) % 3, k = (i + 2) % 3;

float const p = 0.5f * std::sqrt(1.0f - tr + 2.f * m[i][i]);
float const q = 0.25f / p;

that.w = q * (m[j][k] - m[k][j]);
that[1 + i] = p;
that[1 + j] = q * (m[i][j] + m[j][i]);
that[1 + k] = q * (m[k][i] + m[i][k]);
}
}

template<> quat::quat_t(mat3 const &m)
{
MatrixToQuat(*this, m);
mat_to_quat(*this, m);
}

template<> quat::quat_t(mat4 const &m)
{
MatrixToQuat(*this, mat3(m));
mat_to_quat(*this, mat3(m));
}

template<> quat quat::rotate(float degrees, vec3 const &v)


Loading…
Cancel
Save