convert quaterinon to xyzw order (part 1)

This commit is contained in:
Recep Aslantas
2018-04-09 18:49:12 +03:00
parent 7615f785ac
commit 3dc93c56e8
6 changed files with 112 additions and 118 deletions

View File

@@ -19,17 +19,11 @@ glmc_quat_identity(versor q);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quat(versor q, glmc_quat(versor q, float angle, float x, float y, float z);
float angle,
float x,
float y,
float z);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quatv(versor q, glmc_quatv(versor q, float angle, vec3 v);
float angle,
vec3 v);
CGLM_EXPORT CGLM_EXPORT
float float
@@ -57,10 +51,7 @@ glmc_quat_mat3(versor q, mat3 dest);
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quat_slerp(versor q, glmc_quat_slerp(versor q, versor r, float t, versor dest);
versor r,
float t,
versor dest);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -198,39 +198,41 @@ void
glm_mat3_quat(mat3 m, versor dest) { glm_mat3_quat(mat3 m, versor dest) {
float trace, r, rinv; float trace, r, rinv;
/* it seems using like m12 instead of m[1][2] causes extra instructions */
trace = m[0][0] + m[1][1] + m[2][2]; trace = m[0][0] + m[1][1] + m[2][2];
if (trace >= 0.0f) { if (trace >= 0.0f) {
r = 2.0f * sqrtf(1 + trace); r = sqrtf(1.0f + trace);
rinv = 1.0f / r; rinv = 0.5f / r;
dest[1] = rinv * (m[1][2] - m[2][1]);
dest[2] = rinv * (m[2][0] - m[0][2]);
dest[3] = rinv * (m[0][1] - m[1][0]);
dest[0] = r * 0.25f;
} else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) {
r = 2.0f * sqrtf(1 - m[1][1] - m[2][2] + m[0][0]);
rinv = 1.0f / r;
dest[1] = r * 0.25f;
dest[2] = rinv * (m[0][1] + m[1][0]);
dest[3] = rinv * (m[0][2] + m[2][0]);
dest[0] = rinv * (m[1][2] - m[2][1]); dest[0] = rinv * (m[1][2] - m[2][1]);
} else if (m[1][1] >= m[2][2]) { dest[1] = rinv * (m[2][0] - m[0][2]);
r = 2.0f * sqrtf(1 - m[0][0] - m[2][2] + m[1][1]); dest[2] = rinv * (m[0][1] - m[1][0]);
rinv = 1.0f / r; dest[3] = r * 0.5f;
} else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) {
r = sqrtf(1.0f - m[1][1] - m[2][2] + m[0][0]);
rinv = 0.5f / r;
dest[0] = r * 0.5f;
dest[1] = rinv * (m[0][1] + m[1][0]); dest[1] = rinv * (m[0][1] + m[1][0]);
dest[2] = r * 0.25f; dest[2] = rinv * (m[0][2] + m[2][0]);
dest[3] = rinv * (m[1][2] + m[2][1]); dest[3] = rinv * (m[1][2] - m[2][1]);
dest[0] = rinv * (m[2][0] - m[0][2]); } else if (m[1][1] >= m[2][2]) {
} else { r = sqrtf(1.0f - m[0][0] - m[2][2] + m[1][1]);
r = 2.0f * sqrtf(1 - m[0][0] - m[1][1] + m[2][2]); rinv = 0.5f / r;
rinv = 1.0f / r;
dest[1] = rinv * (m[0][2] + m[2][0]); dest[0] = rinv * (m[0][1] + m[1][0]);
dest[1] = r * 0.5f;
dest[2] = rinv * (m[1][2] + m[2][1]); dest[2] = rinv * (m[1][2] + m[2][1]);
dest[3] = r * 0.25f; dest[3] = rinv * (m[2][0] - m[0][2]);
dest[0] = rinv * (m[0][1] - m[1][0]); } else {
r = sqrtf(1.0f - m[0][0] - m[1][1] + m[2][2]);
rinv = 0.5f / r;
dest[0] = rinv * (m[0][2] + m[2][0]);
dest[1] = rinv * (m[1][2] + m[2][1]);
dest[2] = r * 0.5f;
dest[3] = rinv * (m[0][1] - m[1][0]);
} }
} }

View File

@@ -345,39 +345,41 @@ void
glm_mat4_quat(mat4 m, versor dest) { glm_mat4_quat(mat4 m, versor dest) {
float trace, r, rinv; float trace, r, rinv;
/* it seems using like m12 instead of m[1][2] causes extra instructions */
trace = m[0][0] + m[1][1] + m[2][2]; trace = m[0][0] + m[1][1] + m[2][2];
if (trace >= 0.0f) { if (trace >= 0.0f) {
r = 2.0f * sqrtf(1 + trace); r = sqrtf(1.0f + trace);
rinv = 1.0f / r; rinv = 0.5f / r;
dest[1] = rinv * (m[1][2] - m[2][1]);
dest[2] = rinv * (m[2][0] - m[0][2]);
dest[3] = rinv * (m[0][1] - m[1][0]);
dest[0] = r * 0.25f;
} else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) {
r = 2.0f * sqrtf(1 - m[1][1] - m[2][2] + m[0][0]);
rinv = 1.0f / r;
dest[1] = r * 0.25f;
dest[2] = rinv * (m[0][1] + m[1][0]);
dest[3] = rinv * (m[0][2] + m[2][0]);
dest[0] = rinv * (m[1][2] - m[2][1]); dest[0] = rinv * (m[1][2] - m[2][1]);
} else if (m[1][1] >= m[2][2]) { dest[1] = rinv * (m[2][0] - m[0][2]);
r = 2.0f * sqrtf(1 - m[0][0] - m[2][2] + m[1][1]); dest[2] = rinv * (m[0][1] - m[1][0]);
rinv = 1.0f / r; dest[3] = r * 0.5f;
} else if (m[0][0] >= m[1][1] && m[0][0] >= m[2][2]) {
r = sqrtf(1.0f - m[1][1] - m[2][2] + m[0][0]);
rinv = 0.5f / r;
dest[0] = r * 0.5f;
dest[1] = rinv * (m[0][1] + m[1][0]); dest[1] = rinv * (m[0][1] + m[1][0]);
dest[2] = r * 0.25f; dest[2] = rinv * (m[0][2] + m[2][0]);
dest[3] = rinv * (m[1][2] + m[2][1]); dest[3] = rinv * (m[1][2] - m[2][1]);
dest[0] = rinv * (m[2][0] - m[0][2]); } else if (m[1][1] >= m[2][2]) {
} else { r = sqrtf(1.0f - m[0][0] - m[2][2] + m[1][1]);
r = 2.0f * sqrtf(1 - m[0][0] - m[1][1] + m[2][2]); rinv = 0.5f / r;
rinv = 1.0f / r;
dest[1] = rinv * (m[0][2] + m[2][0]); dest[0] = rinv * (m[0][1] + m[1][0]);
dest[1] = r * 0.5f;
dest[2] = rinv * (m[1][2] + m[2][1]); dest[2] = rinv * (m[1][2] + m[2][1]);
dest[3] = r * 0.25f; dest[3] = rinv * (m[2][0] - m[0][2]);
dest[0] = rinv * (m[0][1] - m[1][0]); } else {
r = sqrtf(1.0f - m[0][0] - m[1][1] + m[2][2]);
rinv = 0.5f / r;
dest[0] = rinv * (m[0][2] + m[2][0]);
dest[1] = rinv * (m[1][2] + m[2][1]);
dest[2] = r * 0.5f;
dest[3] = rinv * (m[0][1] - m[1][0]);
} }
} }

View File

@@ -13,7 +13,7 @@
Functions: Functions:
CGLM_INLINE void glm_quat_identity(versor q); CGLM_INLINE void glm_quat_identity(versor q);
CGLM_INLINE void glm_quat(versor q, float angle, float x, float y, float z); CGLM_INLINE void glm_quat(versor q, float angle, float x, float y, float z);
CGLM_INLINE void glm_quatv(versor q, float angle, vec3 v); CGLM_INLINE void glm_quatv(versor q, float angle, vec3 axis);
CGLM_INLINE float glm_quat_norm(versor q); CGLM_INLINE float glm_quat_norm(versor q);
CGLM_INLINE void glm_quat_normalize(versor q); CGLM_INLINE void glm_quat_normalize(versor q);
CGLM_INLINE float glm_quat_dot(versor q, versor r); CGLM_INLINE float glm_quat_dot(versor q, versor r);
@@ -33,19 +33,16 @@
#endif #endif
/* /*
* IMPORTANT! cglm stores quat as [w, x, y, z] * IMPORTANT:
* ----------------------------------------------------------------------------
* cglm stores quat as [x, y, z, w] since v0.3.6
* *
* Possible changes (these may be changed in the future): * it was [w, x, y, z] before v0.3.6 it has been changed to [x, y, z, w]
* - versor is identity quat, we can define new type for quat. * with v0.3.6 version.
* it can't be quat or quaternion becuase someone can use that name for * ----------------------------------------------------------------------------
* variable name. maybe just vec4.
* - it stores [w, x, y, z] but it may change to [x, y, z, w] if we get enough
* feedback to change it.
* - in general we use last param as dest, but this header used first param
* as dest this may be changed but decided yet
*/ */
#define GLM_QUAT_IDENTITY_INIT {1.0f, 0.0f, 0.0f, 0.0f} #define GLM_QUAT_IDENTITY_INIT {0.0f, 0.0f, 0.0f, 1.0f}
#define GLM_QUAT_IDENTITY ((versor)GLM_QUAT_IDENTITY_INIT) #define GLM_QUAT_IDENTITY ((versor)GLM_QUAT_IDENTITY_INIT)
/*! /*!
@@ -60,6 +57,24 @@ glm_quat_identity(versor q) {
glm_vec4_copy(v, q); glm_vec4_copy(v, q);
} }
/*!
* @brief inits quaterion with raw values
*
* @param[out] q quaternion
* @param[in] x x
* @param[in] y y
* @param[in] z z
* @param[in] w w (real part)
*/
CGLM_INLINE
void
glm_quat_init(versor q, float x, float y, float z, float w) {
q[0] = x;
q[1] = y;
q[2] = z;
q[3] = w;
}
/*! /*!
* @brief creates NEW quaternion with individual axis components * @brief creates NEW quaternion with individual axis components
* *
@@ -71,21 +86,17 @@ glm_quat_identity(versor q) {
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_quat(versor q, glm_quat(versor q, float angle, float x, float y, float z) {
float angle,
float x,
float y,
float z) {
float a, c, s; float a, c, s;
a = angle * 0.5f; a = angle * 0.5f;
c = cosf(a); c = cosf(a);
s = sinf(a); s = sinf(a);
q[0] = c; q[0] = s * x;
q[1] = s * x; q[1] = s * y;
q[2] = s * y; q[2] = s * z;
q[3] = s * z; q[3] = c;
} }
/*! /*!
@@ -93,23 +104,21 @@ glm_quat(versor q,
* *
* @param[out] q quaternion * @param[out] q quaternion
* @param[in] angle angle (radians) * @param[in] angle angle (radians)
* @param[in] v axis * @param[in] axis axis
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_quatv(versor q, glm_quatv(versor q, float angle, vec3 axis) {
float angle,
vec3 v) {
float a, c, s; float a, c, s;
a = angle * 0.5f; a = angle * 0.5f;
c = cosf(a); c = cosf(a);
s = sinf(a); s = sinf(a);
q[0] = c; q[0] = s * axis[0];
q[1] = s * v[0]; q[1] = s * axis[1];
q[2] = s * v[1]; q[2] = s * axis[2];
q[3] = s * v[2]; q[3] = c;
} }
/*! /*!
@@ -146,13 +155,13 @@ glm_quat_normalize(versor q) {
/*! /*!
* @brief dot product of two quaternion * @brief dot product of two quaternion
* *
* @param[in] q quaternion 1 * @param[in] q1 quaternion 1
* @param[in] r quaternion 2 * @param[in] q2 quaternion 2
*/ */
CGLM_INLINE CGLM_INLINE
float float
glm_quat_dot(versor q, versor r) { glm_quat_dot(versor q1, versor q2) {
return glm_vec4_dot(q, r); return glm_vec4_dot(q1, q2);
} }
/*! /*!
@@ -190,10 +199,10 @@ glm_quat_mat4(versor q, mat4 dest) {
norm = glm_quat_norm(q); norm = glm_quat_norm(q);
s = norm > 0.0f ? 2.0f / norm : 0.0f; s = norm > 0.0f ? 2.0f / norm : 0.0f;
w = q[0]; x = q[0];
x = q[1]; y = q[1];
y = q[2]; z = q[2];
z = q[3]; w = q[3];
xx = s * x * x; xy = s * x * y; wx = s * w * x; xx = s * x * x; xy = s * x * y; wx = s * w * x;
yy = s * y * y; yz = s * y * z; wy = s * w * y; yy = s * y * y; yz = s * y * z; wy = s * w * y;
@@ -237,10 +246,10 @@ glm_quat_mat3(versor q, mat3 dest) {
norm = glm_quat_norm(q); norm = glm_quat_norm(q);
s = norm > 0.0f ? 2.0f / norm : 0.0f; s = norm > 0.0f ? 2.0f / norm : 0.0f;
w = q[0]; x = q[0];
x = q[1]; y = q[1];
y = q[2]; z = q[2];
z = q[3]; w = q[3];
xx = s * x * x; xy = s * x * y; wx = s * w * x; xx = s * x * x; xy = s * x * y; wx = s * w * x;
yy = s * y * y; yz = s * y * z; wy = s * w * y; yy = s * y * y; yz = s * y * z; wy = s * w * y;
@@ -270,10 +279,8 @@ glm_quat_mat3(versor q, mat3 dest) {
*/ */
CGLM_INLINE CGLM_INLINE
void void
glm_quat_slerp(versor q, glm_quat_slerp(versor q, versor r, float t, versor dest) {
versor r,
float t,
versor dest) {
/* https://en.wikipedia.org/wiki/Slerp */ /* https://en.wikipedia.org/wiki/Slerp */
#if defined( __SSE__ ) || defined( __SSE2__ ) #if defined( __SSE__ ) || defined( __SSE2__ )
glm_quat_slerp_sse2(q, r, t, dest); glm_quat_slerp_sse2(q, r, t, dest);

View File

@@ -327,9 +327,7 @@ glm_vec_angle(vec3 v1, vec3 v2) {
CGLM_INLINE CGLM_INLINE
void void
glm_quatv(versor q, glm_quatv(versor q, float angle, vec3 axis);
float angle,
vec3 v);
/*! /*!
* @brief rotate vec3 around axis by angle using Rodrigues' rotation formula * @brief rotate vec3 around axis by angle using Rodrigues' rotation formula

View File

@@ -16,19 +16,13 @@ glmc_quat_identity(versor q) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quat(versor q, glmc_quat(versor q, float angle, float x, float y, float z) {
float angle,
float x,
float y,
float z) {
glm_quat(q, angle, x, y, z); glm_quat(q, angle, x, y, z);
} }
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quatv(versor q, glmc_quatv(versor q, float angle, vec3 v) {
float angle,
vec3 v) {
glm_quatv(q, angle, v); glm_quatv(q, angle, v);
} }
@@ -53,7 +47,7 @@ glmc_quat_dot(versor q, versor r) {
CGLM_EXPORT CGLM_EXPORT
void void
glmc_quat_mulv(versor q1, versor q2, versor dest) { glmc_quat_mulv(versor q1, versor q2, versor dest) {
glm_quat_mulv(q1, q2, dest); glm_quat_mul(q1, q2, dest);
} }
CGLM_EXPORT CGLM_EXPORT