diff --git a/include/cglm/call/cam.h b/include/cglm/call/cam.h index 7b2c409..f8d0b07 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_any(vec3 eye, vec3 dir, mat4 dest); CGLM_EXPORT void diff --git a/include/cglm/cam.h b/include/cglm/cam.h index a65847c..1ca4360 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_any(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/test/src/test_cam.c b/test/src/test_cam.c index 9df4b53..d368ad2 100644 --- a/test/src/test_cam.c +++ b/test/src/test_cam.c @@ -7,6 +7,22 @@ #include "test_common.h" +void +test_camera_lookat(void **state) { + mat4 view1, view2; + vec3 eye = {0.024f, 14.6f, 67.04f}, + dir = {0.0f, 0.0f, -1.0f}, + up = GLM_YUP, + center; + + 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 +51,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);