/* * Copyright (c), Recep Aslantas. * * MIT License (MIT), http://opensource.org/licenses/MIT * Full license can be found in the LICENSE file */ /* Macros: GLMS_QUAT_IDENTITY_INIT GLMS_QUAT_IDENTITY Functions: CGLM_INLINE versors glms_quat_identity(void) CGLM_INLINE void glms_quat_identity_array(versor *q, size_t count) CGLM_INLINE versors glms_quat_init(float x, float y, float z, float w) CGLM_INLINE versors glms_quatv(float angle, vec3s axis) CGLM_INLINE versors glms_quat(float angle, float x, float y, float z) CGLM_INLINE float glms_quat_norm(versors q) CGLM_INLINE versors glms_quat_normalize(versors q) CGLM_INLINE float glms_quat_dot(versors p, versors q) CGLM_INLINE versors glms_quat_conjugate(versors q) CGLM_INLINE versors glms_quat_inv(versors q) CGLM_INLINE versors glms_quat_add(versors p, versors q) CGLM_INLINE versors glms_quat_sub(versors p, versors q) CGLM_INLINE vec3s glms_quat_imagn(versors q) CGLM_INLINE float glms_quat_imaglen(versors q) CGLM_INLINE float glms_quat_angle(versors q) CGLM_INLINE vec3s glms_quat_axis(versors q) CGLM_INLINE versors glms_quat_mul(versors p, versors q) CGLM_INLINE mat4s glms_quat_mat4(versors q) CGLM_INLINE mat4s glms_quat_mat4t(versors q) CGLM_INLINE mat3s glms_quat_mat3(versors q) CGLM_INLINE mat3s glms_quat_mat3t(versors q) CGLM_INLINE versors glms_quat_lerp(versors from, versors to, float t) CGLM_INLINE versors glms_quat_lerpc(versors from, versors to, float t) CGLM_INLINE versors glms_quat_slerp(versors from, versors to, float t) CGLM_INLINE mat4s. glms_quat_look(vec3s eye, versors ori) CGLM_INLINE versors glms_quat_for(vec3s dir, vec3s fwd, vec3s up) CGLM_INLINE versors glms_quat_forp(vec3s from, vec3s to, vec3s fwd, vec3s up) CGLM_INLINE vec3s glms_quat_rotatev(versors q, vec3s v) CGLM_INLINE mat4s glms_quat_rotate(mat4s m, versors q) CGLM_INLINE mat4s glms_quat_rotate_at(mat4s m, versors q, vec3s pivot) CGLM_INLINE mat4s glms_quat_rotate_atm(versors q, vec3s pivot) */ #ifndef cglms_quat_h #define cglms_quat_h #include "../common.h" #include "../types-struct.h" #include "../plane.h" #include "../quat.h" /* * IMPORTANT: * ---------------------------------------------------------------------------- * cglm stores quat as [x, y, z, w] since v0.3.6 * * 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 GLMS_QUAT_IDENTITY_INIT {GLM_QUAT_IDENTITY_INIT} #define GLMS_QUAT_IDENTITY ((versors)GLMS_QUAT_IDENTITY_INIT) /*! * @brief makes given quat to identity * * @returns identity quaternion */ CGLM_INLINE versors glms_quat_identity(void) { versors dest; glm_quat_identity(dest.raw); return dest; } /*! * @brief make given quaternion array's each element identity quaternion * * @param[in, out] q quat array (must be aligned (16) * if alignment is not disabled) * * @param[in] count count of quaternions */ CGLM_INLINE void glms_quat_identity_array(versors * __restrict q, size_t count) { CGLM_ALIGN(16) versor v = GLM_QUAT_IDENTITY_INIT; size_t i; for (i = 0; i < count; i++) { glm_vec4_copy(v, q[i].raw); } } /*! * @brief inits quaterion with raw values * * @param[in] x x * @param[in] y y * @param[in] z z * @param[in] w w (real part) * @returns quaternion */ CGLM_INLINE versors glms_quat_init(float x, float y, float z, float w) { versors dest; glm_quat_init(dest.raw, x, y, z, w); return dest; } /*! * @brief creates NEW quaternion with axis vector * * @param[in] angle angle (radians) * @param[in] axis axis * @returns quaternion */ CGLM_INLINE versors glms_quatv(float angle, vec3s axis) { versors dest; glm_quatv(dest.raw, angle, axis.raw); return dest; } /*! * @brief creates NEW quaternion with individual axis components * * @param[in] angle angle (radians) * @param[in] x axis.x * @param[in] y axis.y * @param[in] z axis.z * @returns quaternion */ CGLM_INLINE versors glms_quat(float angle, float x, float y, float z) { versors dest; glm_quat(dest.raw, angle, x, y, z); return dest; } /*! * @brief returns norm (magnitude) of quaternion * * @param[out] q quaternion */ CGLM_INLINE float glms_quat_norm(versors q) { return glm_quat_norm(q.raw); } /*! * @brief normalize quaternion * * @param[in] q quaternion * @returns quaternion */ CGLM_INLINE versors glms_quat_normalize(versors q) { versors dest; glm_quat_normalize_to(q.raw, dest.raw); return dest; } /*! * @brief dot product of two quaternion * * @param[in] p quaternion 1 * @param[in] q quaternion 2 * @returns dot product */ CGLM_INLINE float glms_quat_dot(versors p, versors q) { return glm_quat_dot(p.raw, q.raw); } /*! * @brief conjugate of quaternion * * @param[in] q quaternion * @returns conjugate */ CGLM_INLINE versors glms_quat_conjugate(versors q) { versors dest; glm_quat_conjugate(q.raw, dest.raw); return dest; } /*! * @brief inverse of non-zero quaternion * * @param[in] q quaternion * @returns inverse quaternion */ CGLM_INLINE versors glms_quat_inv(versors q) { versors dest; glm_quat_inv(q.raw, dest.raw); return dest; } /*! * @brief add (componentwise) two quaternions and store result in dest * * @param[in] p quaternion 1 * @param[in] q quaternion 2 * @returns result quaternion */ CGLM_INLINE versors glms_quat_add(versors p, versors q) { versors dest; glm_quat_add(p.raw, q.raw, dest.raw); return dest; } /*! * @brief subtract (componentwise) two quaternions and store result in dest * * @param[in] p quaternion 1 * @param[in] q quaternion 2 * @returns result quaternion */ CGLM_INLINE versors glms_quat_sub(versors p, versors q) { versors dest; glm_quat_sub(p.raw, q.raw, dest.raw); return dest; } /*! * @brief returns normalized imaginary part of quaternion * * @param[in] q quaternion */ CGLM_INLINE vec3s glms_quat_imagn(versors q) { vec3s dest; glm_normalize_to(q.raw, dest.raw); return dest; } /*! * @brief returns length of imaginary part of quaternion * * @param[in] q quaternion */ CGLM_INLINE float glms_quat_imaglen(versors q) { return glm_quat_imaglen(q.raw); } /*! * @brief returns angle of quaternion * * @param[in] q quaternion */ CGLM_INLINE float glms_quat_angle(versors q) { return glm_quat_angle(q.raw); } /*! * @brief axis of quaternion * * @param[in] q quaternion * @returns axis of quaternion */ CGLM_INLINE vec3s glms_quat_axis(versors q) { vec3s dest; glm_quat_axis(q.raw, dest.raw); return dest; } /*! * @brief multiplies two quaternion and stores result in dest * this is also called Hamilton Product * * According to WikiPedia: * The product of two rotation quaternions [clarification needed] will be * equivalent to the rotation q followed by the rotation p * * @param[in] p quaternion 1 * @param[in] q quaternion 2 * @returns result quaternion */ CGLM_INLINE versors glms_quat_mul(versors p, versors q) { versors dest; glm_quat_mul(p.raw, q.raw, dest.raw); return dest; } /*! * @brief convert quaternion to mat4 * * @param[in] q quaternion * @returns result matrix */ CGLM_INLINE mat4s glms_quat_mat4(versors q) { mat4s dest; glm_quat_mat4(q.raw, dest.raw); return dest; } /*! * @brief convert quaternion to mat4 (transposed) * * @param[in] q quaternion * @returns result matrix as transposed */ CGLM_INLINE mat4s glms_quat_mat4t(versors q) { mat4s dest; glm_quat_mat4t(q.raw, dest.raw); return dest; } /*! * @brief convert quaternion to mat3 * * @param[in] q quaternion * @returns result matrix */ CGLM_INLINE mat3s glms_quat_mat3(versors q) { mat3s dest; glm_quat_mat3(q.raw, dest.raw); return dest; } /*! * @brief convert quaternion to mat3 (transposed) * * @param[in] q quaternion * @returns result matrix */ CGLM_INLINE mat3s glms_quat_mat3t(versors q) { mat3s dest; glm_quat_mat3t(q.raw, dest.raw); return dest; } /*! * @brief interpolates between two quaternions * using linear interpolation (LERP) * * @param[in] from from * @param[in] to to * @param[in] t interpolant (amount) * @returns result quaternion */ CGLM_INLINE versors glms_quat_lerp(versors from, versors to, float t) { versors dest; glm_quat_lerp(from.raw, to.raw, t, dest.raw); return dest; } /*! * @brief interpolates between two quaternions * using linear interpolation (LERP) * * @param[in] from from * @param[in] to to * @param[in] t interpolant (amount) clamped between 0 and 1 * @returns result quaternion */ CGLM_INLINE versors glms_quat_lerpc(versors from, versors to, float t) { versors dest; glm_quat_lerpc(from.raw, to.raw, t, dest.raw); return dest; } /*! * @brief interpolates between two quaternions * using spherical linear interpolation (SLERP) * * @param[in] from from * @param[in] to to * @param[in] t amout * @returns result quaternion */ CGLM_INLINE versors glms_quat_slerp(versors from, versors to, float t) { versors dest; glm_quat_slerp(from.raw, to.raw, t, dest.raw); return dest; } /*! * @brief creates view matrix using quaternion as camera orientation * * @param[in] eye eye * @param[in] ori orientation in world space as quaternion * @returns view matrix */ CGLM_INLINE mat4s glms_quat_look(vec3s eye, versors ori) { mat4s dest; glm_quat_look(eye.raw, ori.raw, dest.raw); return dest; } /*! * @brief creates look rotation quaternion * * @param[in] dir direction to look * @param[in] up up vector * @returns destination quaternion */ CGLM_INLINE versors glms_quat_for(vec3s dir, vec3s up) { versors dest; glm_quat_for(dir.raw, up.raw, dest.raw); return dest; } /*! * @brief creates look rotation quaternion using source and * destination positions p suffix stands for position * * @param[in] from source point * @param[in] to destination point * @param[in] up up vector * @returns destination quaternion */ CGLM_INLINE versors glms_quat_forp(vec3s from, vec3s to, vec3s up) { versors dest; glm_quat_forp(from.raw, to.raw, up.raw, dest.raw); return dest; } /*! * @brief rotate vector using using quaternion * * @param[in] q quaternion * @param[in] v vector to rotate * @returns rotated vector */ CGLM_INLINE vec3s glms_quat_rotatev(versors q, vec3s v) { vec3s dest; glm_quat_rotatev(q.raw, v.raw, dest.raw); return dest; } /*! * @brief rotate existing transform matrix using quaternion * * @param[in] m existing transform matrix * @param[in] q quaternion * @returns rotated matrix/transform */ CGLM_INLINE mat4s glms_quat_rotate(mat4s m, versors q) { glm_quat_rotate(m.raw, q.raw, m.raw); return m; } /*! * @brief rotate existing transform matrix using quaternion at pivot point * * @param[in, out] m existing transform matrix * @param[in] q quaternion * @returns pivot */ CGLM_INLINE mat4s glms_quat_rotate_at(mat4s m, versors q, vec3s pivot) { glm_quat_rotate_at(m.raw, q.raw, pivot.raw); return m; } /*! * @brief rotate NEW transform matrix using quaternion at pivot point * * this creates rotation matrix, it assumes you don't have a matrix * * this should work faster than glm_quat_rotate_at because it reduces * one glm_translate. * * @param[in] q quaternion * @returns pivot */ CGLM_INLINE mat4s glms_quat_rotate_atm(versors q, vec3s pivot) { mat4s dest; glm_quat_rotate_atm(dest.raw, q.raw, pivot.raw); return dest; } #endif /* cglms_quat_h */