mirror of
https://github.com/recp/cglm.git
synced 2025-10-04 01:00:46 +00:00
vec: optimize rotate vector using matrix
* add mat3 version
This commit is contained in:
@@ -60,6 +60,7 @@ Functions:
|
||||
#. :c:func:`glm_vec_angle`
|
||||
#. :c:func:`glm_vec_rotate`
|
||||
#. :c:func:`glm_vec_rotate_m4`
|
||||
#. :c:func:`glm_vec_rotate_m3`
|
||||
#. :c:func:`glm_vec_proj`
|
||||
#. :c:func:`glm_vec_center`
|
||||
#. :c:func:`glm_vec_maxv`
|
||||
@@ -338,6 +339,15 @@ Functions documentation
|
||||
| *[in]* **v** vector
|
||||
| *[out]* **dest** rotated vector
|
||||
|
||||
.. c:function:: void glm_vec_rotate_m3(mat3 m, vec3 v, vec3 dest)
|
||||
|
||||
apply rotation matrix to vector
|
||||
|
||||
Parameters:
|
||||
| *[in]* **m** affine matrix or rot matrix
|
||||
| *[in]* **v** vector
|
||||
| *[out]* **dest** rotated vector
|
||||
|
||||
.. c:function:: void glm_vec_proj(vec3 a, vec3 b, vec3 dest)
|
||||
|
||||
project a vector onto b vector
|
||||
|
@@ -67,6 +67,7 @@
|
||||
#define cglm_vec3_h
|
||||
|
||||
#include "common.h"
|
||||
#include "vec4.h"
|
||||
#include "vec3-ext.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -551,6 +552,12 @@ glm_vec_rotate(vec3 v, float angle, vec3 axis) {
|
||||
/*!
|
||||
* @brief apply rotation matrix to vector
|
||||
*
|
||||
* matrix format should be (no perspective):
|
||||
* a b c x
|
||||
* e f g y
|
||||
* i j k z
|
||||
* 0 0 0 w
|
||||
*
|
||||
* @param[in] m affine matrix or rot matrix
|
||||
* @param[in] v vector
|
||||
* @param[out] dest rotated vector
|
||||
@@ -558,17 +565,44 @@ glm_vec_rotate(vec3 v, float angle, vec3 axis) {
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_rotate_m4(mat4 m, vec3 v, vec3 dest) {
|
||||
vec3 res, x, y, z;
|
||||
vec4 x, y, z, res;
|
||||
|
||||
glm_vec_normalize_to(m[0], x);
|
||||
glm_vec_normalize_to(m[1], y);
|
||||
glm_vec_normalize_to(m[2], z);
|
||||
glm_vec4_normalize_to(m[0], x);
|
||||
glm_vec4_normalize_to(m[1], y);
|
||||
glm_vec4_normalize_to(m[2], z);
|
||||
|
||||
res[0] = x[0] * v[0] + y[0] * v[1] + z[0] * v[2];
|
||||
res[1] = x[1] * v[0] + y[1] * v[1] + z[1] * v[2];
|
||||
res[2] = x[2] * v[0] + y[2] * v[1] + z[2] * v[2];
|
||||
glm_vec4_scale(x, v[0], res);
|
||||
glm_vec4_muladds(y, v[1], res);
|
||||
glm_vec4_muladds(y, v[2], res);
|
||||
|
||||
glm_vec_copy(res, dest);
|
||||
glm_vec3(res, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief apply rotation matrix to vector
|
||||
*
|
||||
* @param[in] m affine matrix or rot matrix
|
||||
* @param[in] v vector
|
||||
* @param[out] dest rotated vector
|
||||
*/
|
||||
CGLM_INLINE
|
||||
void
|
||||
glm_vec_rotate_m3(mat3 m, vec3 v, vec3 dest) {
|
||||
vec4 res, x, y, z;
|
||||
|
||||
glm_vec4(m[0], 0.0f, x);
|
||||
glm_vec4(m[1], 0.0f, y);
|
||||
glm_vec4(m[2], 0.0f, z);
|
||||
|
||||
glm_vec4_normalize(x);
|
||||
glm_vec4_normalize(y);
|
||||
glm_vec4_normalize(z);
|
||||
|
||||
glm_vec4_scale(x, v[0], res);
|
||||
glm_vec4_muladds(y, v[1], res);
|
||||
glm_vec4_muladds(y, v[2], res);
|
||||
|
||||
glm_vec3(res, dest);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@@ -9,6 +9,8 @@
|
||||
|
||||
void
|
||||
test_vec3(void **state) {
|
||||
mat3 rot1m3;
|
||||
mat4 rot1;
|
||||
vec3 v, v1, v2;
|
||||
|
||||
/* test zero */
|
||||
@@ -63,4 +65,14 @@ test_vec3(void **state) {
|
||||
glm_vec_broadcast(3, v2);
|
||||
glm_vec_muladd(v1, v2, v);
|
||||
assert_true(glmc_vec_eq_eps(v, 10));
|
||||
|
||||
/* rotate */
|
||||
glm_vec_copy(GLM_YUP, v);
|
||||
glm_rotate_make(rot1, glm_rad(90), GLM_XUP);
|
||||
glm_vec_rotate_m4(rot1, v, v1);
|
||||
glm_mat4_pick3(rot1, rot1m3);
|
||||
glm_vec_rotate_m3(rot1m3, v, v2);
|
||||
|
||||
test_assert_vec3_eq(v1, v2);
|
||||
test_assert_vec3_eq(v1, GLM_ZUP);
|
||||
}
|
||||
|
Reference in New Issue
Block a user