mirror of
https://github.com/recp/cglm.git
synced 2025-10-04 17:09:40 +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
|
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
|
||||||
}
|
}
|
||||||
|
@@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
12
src/quat.c
12
src/quat.c
@@ -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
|
||||||
|
Reference in New Issue
Block a user