diff --git a/include/cglm/affine.h b/include/cglm/affine.h index 39c4290..a5abbb6 100644 --- a/include/cglm/affine.h +++ b/include/cglm/affine.h @@ -38,6 +38,11 @@ #include "vec4.h" #include "affine-mat.h" #include "util.h" +#include "mat4.h" + +CGLM_INLINE +void +glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest); /*! * @brief translate existing transform matrix by v vector @@ -459,19 +464,46 @@ glm_rotate(mat4 m, float angle, vec3 axis) { * around given axis by angle at given pivot point (rotation center) * * @param[in, out] m affine transfrom + * @param[in] pivot rotation center * @param[in] angle angle (radians) * @param[in] axis axis */ CGLM_INLINE void -glm_rotate_at(mat4 model, vec3 pivot, float angle, vec3 axis) { +glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) { vec3 pivotInv; glm_vec_inv_to(pivot, pivotInv); - glm_translate(model, pivot); - glm_rotate(model, angle, axis); - glm_translate(model, pivotInv); + glm_translate(m, pivot); + glm_rotate(m, angle, axis); + glm_translate(m, pivotInv); +} + +/*! + * @brief creates NEW rotation matrix by angle and axis at given point + * + * this creates rotation matrix, it assumes you don't have a matrix + * + * this should work faster than glm_rotate_at because it reduces + * one glm_translate. + * + * @param[out] m affine transfrom + * @param[in] pivot rotation center + * @param[in] angle angle (radians) + * @param[in] axis axis + */ +CGLM_INLINE +void +glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) { + vec3 pivotInv; + + glm_vec_inv_to(pivot, pivotInv); + + glm_mat4_identity(m); + glm_vec_copy(pivot, m[3]); + glm_rotate(m, angle, axis); + glm_translate(m, pivotInv); } /*! diff --git a/include/cglm/call/affine.h b/include/cglm/call/affine.h index 6d6b872..a9982c2 100644 --- a/include/cglm/call/affine.h +++ b/include/cglm/call/affine.h @@ -87,7 +87,11 @@ glmc_rotate(mat4 m, float angle, vec3 axis); CGLM_EXPORT void -glmc_rotate_at(mat4 model, vec3 pivot, float angle, vec3 axis); +glmc_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis); + +CGLM_EXPORT +void +glmc_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis); CGLM_EXPORT void diff --git a/include/cglm/call/quat.h b/include/cglm/call/quat.h index d250f52..ae4c9ef 100644 --- a/include/cglm/call/quat.h +++ b/include/cglm/call/quat.h @@ -137,6 +137,14 @@ CGLM_EXPORT void glmc_quat_rotate(mat4 m, versor q, mat4 dest); +CGLM_EXPORT +void +glmc_quat_rotate_at(mat4 model, versor q, vec3 pivot); + +CGLM_EXPORT +void +glmc_quat_rotate_atm(mat4 m, versor q, vec3 pivot); + #ifdef __cplusplus } #endif diff --git a/include/cglm/quat.h b/include/cglm/quat.h index fa356d4..1139c1d 100644 --- a/include/cglm/quat.h +++ b/include/cglm/quat.h @@ -60,6 +60,10 @@ # include "simd/sse2/quat.h" #endif +CGLM_INLINE +void +glm_mat4_identity(mat4 mat); + CGLM_INLINE void glm_mat4_mulv(mat4 m, vec4 v, vec4 dest); @@ -68,6 +72,10 @@ CGLM_INLINE void glm_mat4_mul(mat4 m1, mat4 m2, mat4 dest); +CGLM_INLINE +void +glm_translate(mat4 m, vec3 v); + /* * IMPORTANT: * ---------------------------------------------------------------------------- @@ -740,4 +748,48 @@ glm_quat_rotate(mat4 m, versor q, mat4 dest) { glm_mat4_mul(m, rot, dest); } +/*! + * @brief rotate existing transform matrix using quaternion at pivot point + * + * @param[in, out] m existing transform matrix + * @param[in] q quaternion + * @param[out] pivot pivot + */ +CGLM_INLINE +void +glm_quat_rotate_at(mat4 model, versor q, vec3 pivot) { + vec3 pivotInv; + + glm_vec_inv_to(pivot, pivotInv); + + glm_translate(model, pivot); + glm_quat_rotate(model, q, model); + glm_translate(model, pivotInv); +} + +/*! + * @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[out] m existing transform matrix + * @param[in] q quaternion + * @param[in] pivot pivot + */ +CGLM_INLINE +void +glm_quat_rotate_atm(mat4 m, versor q, vec3 pivot) { + vec3 pivotInv; + + glm_vec_inv_to(pivot, pivotInv); + + glm_mat4_identity(m); + glm_vec_copy(pivot, m[3]); + glm_quat_rotate(m, q, m); + glm_translate(m, pivotInv); +} + #endif /* cglm_quat_h */ diff --git a/src/affine.c b/src/affine.c index 793d8ee..1da12d6 100644 --- a/src/affine.c +++ b/src/affine.c @@ -118,8 +118,14 @@ glmc_rotate(mat4 m, float angle, vec3 axis) { CGLM_EXPORT void -glmc_rotate_at(mat4 model, vec3 pivot, float angle, vec3 axis) { - glm_rotate_at(model, pivot, angle, axis); +glmc_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis) { + glm_rotate_at(m, pivot, angle, axis); +} + +CGLM_EXPORT +void +glmc_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis) { + glm_rotate_atm(m, pivot, angle, axis); } CGLM_EXPORT diff --git a/src/quat.c b/src/quat.c index 8a9a463..c47761d 100644 --- a/src/quat.c +++ b/src/quat.c @@ -194,3 +194,15 @@ void glmc_quat_rotate(mat4 m, versor q, mat4 dest) { glm_quat_rotate(m, q, dest); } + +CGLM_EXPORT +void +glmc_quat_rotate_at(mat4 model, versor q, vec3 pivot) { + glm_quat_rotate_at(model, q, pivot); +} + +CGLM_EXPORT +void +glmc_quat_rotate_atm(mat4 m, versor q, vec3 pivot) { + glm_quat_rotate_atm(m, q, pivot); +}