mirror of
https://github.com/recp/cglm.git
synced 2025-10-04 09:08:53 +00:00
convert quaterinon to xyzw order (part 1)
This commit is contained in:
@@ -19,17 +19,11 @@ glmc_quat_identity(versor q);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat(versor q,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z);
|
||||
glmc_quat(versor q, float angle, float x, float y, float z);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v);
|
||||
glmc_quatv(versor q, float angle, vec3 v);
|
||||
|
||||
CGLM_EXPORT
|
||||
float
|
||||
@@ -57,10 +51,7 @@ glmc_quat_mat3(versor q, mat3 dest);
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_slerp(versor q,
|
||||
versor r,
|
||||
float t,
|
||||
versor dest);
|
||||
glmc_quat_slerp(versor q, versor r, float t, versor dest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -198,39 +198,41 @@ void
|
||||
glm_mat3_quat(mat3 m, versor dest) {
|
||||
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];
|
||||
if (trace >= 0.0f) {
|
||||
r = 2.0f * sqrtf(1 + trace);
|
||||
rinv = 1.0f / r;
|
||||
r = sqrtf(1.0f + trace);
|
||||
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]);
|
||||
} else if (m[1][1] >= m[2][2]) {
|
||||
r = 2.0f * sqrtf(1 - m[0][0] - m[2][2] + m[1][1]);
|
||||
rinv = 1.0f / r;
|
||||
dest[1] = rinv * (m[2][0] - m[0][2]);
|
||||
dest[2] = rinv * (m[0][1] - m[1][0]);
|
||||
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[2] = r * 0.25f;
|
||||
dest[3] = rinv * (m[1][2] + m[2][1]);
|
||||
dest[0] = rinv * (m[2][0] - m[0][2]);
|
||||
} else {
|
||||
r = 2.0f * sqrtf(1 - m[0][0] - m[1][1] + m[2][2]);
|
||||
rinv = 1.0f / r;
|
||||
dest[2] = rinv * (m[0][2] + m[2][0]);
|
||||
dest[3] = rinv * (m[1][2] - m[2][1]);
|
||||
} else if (m[1][1] >= m[2][2]) {
|
||||
r = sqrtf(1.0f - m[0][0] - m[2][2] + m[1][1]);
|
||||
rinv = 0.5f / 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[3] = r * 0.25f;
|
||||
dest[0] = rinv * (m[0][1] - m[1][0]);
|
||||
dest[3] = rinv * (m[2][0] - m[0][2]);
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -345,39 +345,41 @@ void
|
||||
glm_mat4_quat(mat4 m, versor dest) {
|
||||
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];
|
||||
if (trace >= 0.0f) {
|
||||
r = 2.0f * sqrtf(1 + trace);
|
||||
rinv = 1.0f / r;
|
||||
r = sqrtf(1.0f + trace);
|
||||
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]);
|
||||
} else if (m[1][1] >= m[2][2]) {
|
||||
r = 2.0f * sqrtf(1 - m[0][0] - m[2][2] + m[1][1]);
|
||||
rinv = 1.0f / r;
|
||||
dest[1] = rinv * (m[2][0] - m[0][2]);
|
||||
dest[2] = rinv * (m[0][1] - m[1][0]);
|
||||
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[2] = r * 0.25f;
|
||||
dest[3] = rinv * (m[1][2] + m[2][1]);
|
||||
dest[0] = rinv * (m[2][0] - m[0][2]);
|
||||
} else {
|
||||
r = 2.0f * sqrtf(1 - m[0][0] - m[1][1] + m[2][2]);
|
||||
rinv = 1.0f / r;
|
||||
dest[2] = rinv * (m[0][2] + m[2][0]);
|
||||
dest[3] = rinv * (m[1][2] - m[2][1]);
|
||||
} else if (m[1][1] >= m[2][2]) {
|
||||
r = sqrtf(1.0f - m[0][0] - m[2][2] + m[1][1]);
|
||||
rinv = 0.5f / 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[3] = r * 0.25f;
|
||||
dest[0] = rinv * (m[0][1] - m[1][0]);
|
||||
dest[3] = rinv * (m[2][0] - m[0][2]);
|
||||
} 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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
Functions:
|
||||
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_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 void glm_quat_normalize(versor q);
|
||||
CGLM_INLINE float glm_quat_dot(versor q, versor r);
|
||||
@@ -33,19 +33,16 @@
|
||||
#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):
|
||||
* - versor is identity quat, we can define new type for quat.
|
||||
* 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
|
||||
* it was [w, x, y, z] before v0.3.6 it has been changed to [x, y, z, w]
|
||||
* with v0.3.6 version.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#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)
|
||||
|
||||
/*!
|
||||
@@ -60,6 +57,24 @@ glm_quat_identity(versor 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
|
||||
*
|
||||
@@ -71,21 +86,17 @@ glm_quat_identity(versor q) {
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quat(versor q,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z) {
|
||||
glm_quat(versor q, float angle, float x, float y, float z) {
|
||||
float a, c, s;
|
||||
|
||||
a = angle * 0.5f;
|
||||
c = cosf(a);
|
||||
s = sinf(a);
|
||||
|
||||
q[0] = c;
|
||||
q[1] = s * x;
|
||||
q[2] = s * y;
|
||||
q[3] = s * z;
|
||||
q[0] = s * x;
|
||||
q[1] = s * y;
|
||||
q[2] = s * z;
|
||||
q[3] = c;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -93,23 +104,21 @@ glm_quat(versor q,
|
||||
*
|
||||
* @param[out] q quaternion
|
||||
* @param[in] angle angle (radians)
|
||||
* @param[in] v axis
|
||||
* @param[in] axis axis
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v) {
|
||||
glm_quatv(versor q, float angle, vec3 axis) {
|
||||
float a, c, s;
|
||||
|
||||
a = angle * 0.5f;
|
||||
c = cosf(a);
|
||||
s = sinf(a);
|
||||
|
||||
q[0] = c;
|
||||
q[1] = s * v[0];
|
||||
q[2] = s * v[1];
|
||||
q[3] = s * v[2];
|
||||
q[0] = s * axis[0];
|
||||
q[1] = s * axis[1];
|
||||
q[2] = s * axis[2];
|
||||
q[3] = c;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -146,13 +155,13 @@ glm_quat_normalize(versor q) {
|
||||
/*!
|
||||
* @brief dot product of two quaternion
|
||||
*
|
||||
* @param[in] q quaternion 1
|
||||
* @param[in] r quaternion 2
|
||||
* @param[in] q1 quaternion 1
|
||||
* @param[in] q2 quaternion 2
|
||||
*/
|
||||
CGLM_INLINE
|
||||
float
|
||||
glm_quat_dot(versor q, versor r) {
|
||||
return glm_vec4_dot(q, r);
|
||||
glm_quat_dot(versor q1, versor q2) {
|
||||
return glm_vec4_dot(q1, q2);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -190,10 +199,10 @@ glm_quat_mat4(versor q, mat4 dest) {
|
||||
norm = glm_quat_norm(q);
|
||||
s = norm > 0.0f ? 2.0f / norm : 0.0f;
|
||||
|
||||
w = q[0];
|
||||
x = q[1];
|
||||
y = q[2];
|
||||
z = q[3];
|
||||
x = q[0];
|
||||
y = q[1];
|
||||
z = q[2];
|
||||
w = q[3];
|
||||
|
||||
xx = s * x * x; xy = s * x * y; wx = s * w * x;
|
||||
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);
|
||||
s = norm > 0.0f ? 2.0f / norm : 0.0f;
|
||||
|
||||
w = q[0];
|
||||
x = q[1];
|
||||
y = q[2];
|
||||
z = q[3];
|
||||
x = q[0];
|
||||
y = q[1];
|
||||
z = q[2];
|
||||
w = q[3];
|
||||
|
||||
xx = s * x * x; xy = s * x * y; wx = s * w * x;
|
||||
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
|
||||
void
|
||||
glm_quat_slerp(versor q,
|
||||
versor r,
|
||||
float t,
|
||||
versor dest) {
|
||||
glm_quat_slerp(versor q, versor r, float t, versor dest) {
|
||||
|
||||
/* https://en.wikipedia.org/wiki/Slerp */
|
||||
#if defined( __SSE__ ) || defined( __SSE2__ )
|
||||
glm_quat_slerp_sse2(q, r, t, dest);
|
||||
|
@@ -327,9 +327,7 @@ glm_vec_angle(vec3 v1, vec3 v2) {
|
||||
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v);
|
||||
glm_quatv(versor q, float angle, vec3 axis);
|
||||
|
||||
/*!
|
||||
* @brief rotate vec3 around axis by angle using Rodrigues' rotation formula
|
||||
|
12
src/quat.c
12
src/quat.c
@@ -16,19 +16,13 @@ glmc_quat_identity(versor q) {
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat(versor q,
|
||||
float angle,
|
||||
float x,
|
||||
float y,
|
||||
float z) {
|
||||
glmc_quat(versor q, float angle, float x, float y, float z) {
|
||||
glm_quat(q, angle, x, y, z);
|
||||
}
|
||||
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quatv(versor q,
|
||||
float angle,
|
||||
vec3 v) {
|
||||
glmc_quatv(versor q, float angle, vec3 v) {
|
||||
glm_quatv(q, angle, v);
|
||||
}
|
||||
|
||||
@@ -53,7 +47,7 @@ glmc_quat_dot(versor q, versor r) {
|
||||
CGLM_EXPORT
|
||||
void
|
||||
glmc_quat_mulv(versor q1, versor q2, versor dest) {
|
||||
glm_quat_mulv(q1, q2, dest);
|
||||
glm_quat_mul(q1, q2, dest);
|
||||
}
|
||||
|
||||
CGLM_EXPORT
|
||||
|
Reference in New Issue
Block a user