diff --git a/include/cglm/call/cam.h b/include/cglm/call/cam.h index 7b2c409..dc01f6f 100644 --- a/include/cglm/call/cam.h +++ b/include/cglm/call/cam.h @@ -43,10 +43,15 @@ glmc_perspective(float fovy, CGLM_EXPORT void -glmc_lookat(vec3 eye, - vec3 center, - vec3 up, - mat4 dest); +glmc_lookat(vec3 eye, vec3 center, vec3 up, mat4 dest); + +CGLM_EXPORT +void +glmc_look(vec3 eye, vec3 dir, vec3 up, mat4 dest); + +CGLM_EXPORT +void +glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest); CGLM_EXPORT void diff --git a/include/cglm/cam.h b/include/cglm/cam.h index a65847c..23504cc 100644 --- a/include/cglm/cam.h +++ b/include/cglm/cam.h @@ -303,6 +303,43 @@ glm_lookat(vec3 eye, dest[3][3] = 1.0f; } +/*! + * @brief set up view matrix + * + * convenient wrapper for lookat: if you only have direction not target self + * then this might be useful. Because you need to get target from direction. + * + * @param[in] eye eye vector + * @param[in] dir direction vector + * @param[in] up up vector + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) { + vec3 target; + glm_vec_add(eye, dir, target); + glm_lookat(eye, target, up, dest); +} + +/*! + * @brief set up view matrix + * + * convenient wrapper for look: if you only have direction and if you don't + * care what UP vector is then this might be useful to create view matrix + * + * @param[in] eye eye vector + * @param[in] dir direction vector + * @param[out] dest result matrix + */ +CGLM_INLINE +void +glm_look_anyup(vec3 eye, vec3 dir, mat4 dest) { + vec3 up; + glm_vec_ortho(dir, up); + glm_look(eye, dir, up, dest); +} + /*! * @brief decomposes frustum values of perspective projection. * diff --git a/include/cglm/vec3.h b/include/cglm/vec3.h index e6dff8f..e951ea9 100644 --- a/include/cglm/vec3.h +++ b/include/cglm/vec3.h @@ -42,6 +42,7 @@ CGLM_INLINE void glm_vec_center(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_maxv(vec3 v1, vec3 v2, vec3 dest); CGLM_INLINE void glm_vec_minv(vec3 v1, vec3 v2, vec3 dest); + CGLM_INLINE void glm_vec_ortho(vec3 v, vec3 dest); */ #ifndef cglm_vec3_h @@ -456,4 +457,18 @@ glm_vec_minv(vec3 v1, vec3 v2, vec3 dest) { dest[2] = v2[2]; } +/*! + * @brief possible orthogonal/perpendicular vector + * + * @param[in] v vector + * @param[out] dest orthogonal/perpendicular vector + */ +CGLM_INLINE +void +glm_vec_ortho(vec3 v, vec3 dest) { + dest[0] = v[1] - v[2]; + dest[1] = v[2] - v[0]; + dest[2] = v[0] - v[1]; +} + #endif /* cglm_vec3_h */ diff --git a/src/cam.c b/src/cam.c index 602b1fc..3def839 100644 --- a/src/cam.c +++ b/src/cam.c @@ -67,6 +67,18 @@ glmc_lookat(vec3 eye, glm_lookat(eye, center, up, dest); } +CGLM_EXPORT +void +glmc_look(vec3 eye, vec3 dir, vec3 up, mat4 dest) { + glm_look(eye, dir, up, dest); +} + +CGLM_EXPORT +void +glmc_look_anyup(vec3 eye, vec3 dir, mat4 dest) { + glm_look_anyup(eye, dir, dest); +} + CGLM_EXPORT void glmc_frustum_planes(mat4 m, vec4 dest[6]) { diff --git a/test/src/test_cam.c b/test/src/test_cam.c index 9df4b53..f54c984 100644 --- a/test/src/test_cam.c +++ b/test/src/test_cam.c @@ -7,6 +7,23 @@ #include "test_common.h" +void +test_camera_lookat(void **state) { + mat4 view1, view2; + vec3 center, + eye = {0.024f, 14.6f, 67.04f}, + dir = {0.0f, 0.0f, -1.0f}, + up = {0.0f, 1.0f, 0.0f} + ; + + glm_vec_add(eye, dir, center); + glm_lookat(eye, center, up, view1); + + glm_look(eye, dir, up, view2); + + test_assert_mat4_eq(view1, view2); +} + void test_camera_decomp(void **state) { mat4 proj, proj2; @@ -35,4 +52,3 @@ test_camera_decomp(void **state) { test_assert_mat4_eq(proj, proj2); } - diff --git a/test/src/test_main.c b/test/src/test_main.c index 25c7d17..5d59cfd 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -13,10 +13,9 @@ main(int argc, const char * argv[]) { cmocka_unit_test(test_mat4), /* camera */ + cmocka_unit_test(test_camera_lookat), cmocka_unit_test(test_camera_decomp) }; - return cmocka_run_group_tests(tests, - NULL, - NULL); + return cmocka_run_group_tests(tests, NULL, NULL); } diff --git a/test/src/test_tests.h b/test/src/test_tests.h index a6a8a58..a4e5adb 100644 --- a/test/src/test_tests.h +++ b/test/src/test_tests.h @@ -10,6 +10,9 @@ void test_mat4(void **state); /* camera */ +void +test_camera_lookat(void **state); + void test_camera_decomp(void **state);