diff --git a/include/cglm/call/project.h b/include/cglm/call/project.h index c60b9b3..35ac087 100644 --- a/include/cglm/call/project.h +++ b/include/cglm/call/project.h @@ -15,11 +15,15 @@ extern "C" { CGLM_EXPORT void -glmc_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec3 dest); +glmc_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest); CGLM_EXPORT void -glmc_unproject(mat4 m, vec4 vp, vec3 coord, vec3 dest); +glmc_unproject(vec3 pos, mat4 m, vec4 vp, vec3 dest); + +CGLM_EXPORT +void +glmc_project(vec3 pos, mat4 m, vec4 vp, vec3 dest); #ifdef __cplusplus } diff --git a/include/cglm/project.h b/include/cglm/project.h index fdb0cf9..a0b306b 100644 --- a/include/cglm/project.h +++ b/include/cglm/project.h @@ -33,23 +33,24 @@ * glm_mat4_mul(viewProj, model, MVP); * glm_mat4_inv(viewProj, invMVP); * + * @param[in] pos viewport coordinates * @param[in] invMat matrix (see brief) * @param[in] vp viewport as [x, y, width, height] - * @param[in] coord viewport coordinates * @param[out] dest unprojected coordinates */ CGLM_INLINE void -glm_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec4 dest) { +glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) { vec4 v; - v[0] = 2.0f * (coord[0] - vp[0]) / vp[2] - 1.0f; - v[1] = 2.0f * (coord[1] - vp[1]) / vp[3] - 1.0f; - v[2] = 2.0f * coord[2] - 1.0f; + v[0] = 2.0f * (pos[0] - vp[0]) / vp[2] - 1.0f; + v[1] = 2.0f * (pos[1] - vp[1]) / vp[3] - 1.0f; + v[2] = 2.0f * pos[2] - 1.0f; v[3] = 1.0f; glm_mat4_mulv(invMat, v, v); - glm_vec4_scale(v, 1.0f / v[3], dest); + glm_vec4_scale(v, 1.0f / v[3], v); + glm_vec3(v, dest); } /*! @@ -71,17 +72,17 @@ glm_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec4 dest) { * glm_mat4_mul(proj, view, viewProj); * glm_mat4_mul(viewProj, model, MVP); * + * @param[in] pos viewport coordinates * @param[in] m matrix (see brief) * @param[in] vp viewport as [x, y, width, height] - * @param[in] coord viewport coordinates * @param[out] dest unprojected coordinates */ CGLM_INLINE void -glm_unproject(mat4 m, vec4 vp, vec3 coord, vec4 dest) { +glm_unproject(vec3 pos, mat4 m, vec4 vp, vec3 dest) { mat4 inv; glm_mat4_inv(m, inv); - glm_unprojecti(inv, vp, coord, dest); + glm_unprojecti(pos, inv, vp, dest); } /*! diff --git a/src/project.c b/src/project.c index 16209e7..91c7128 100644 --- a/src/project.c +++ b/src/project.c @@ -10,12 +10,18 @@ CGLM_EXPORT void -glmc_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec3 dest) { - glm_unprojecti(invMat, vp, coord, dest); +glmc_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) { + glm_unprojecti(pos, invMat, vp, dest); } CGLM_EXPORT void -glmc_unproject(mat4 m, vec4 vp, vec3 coord, vec3 dest) { - glm_unproject(m, vp, coord, dest); +glmc_unproject(vec3 pos, mat4 m, vec4 vp, vec3 dest) { + glm_unproject(pos, m, vp, dest); +} + +CGLM_EXPORT +void +glmc_project(vec3 pos, mat4 m, vec4 vp, vec3 dest) { + glm_project(pos, m, vp, dest); } diff --git a/test/src/test_main.c b/test/src/test_main.c index 5d59cfd..61fa7d5 100644 --- a/test/src/test_main.c +++ b/test/src/test_main.c @@ -15,6 +15,9 @@ main(int argc, const char * argv[]) { /* camera */ cmocka_unit_test(test_camera_lookat), cmocka_unit_test(test_camera_decomp) + + /* project */ + cmocka_unit_test(test_project) }; return cmocka_run_group_tests(tests, NULL, NULL); diff --git a/test/src/test_project.c b/test/src/test_project.c new file mode 100644 index 0000000..4cdac9e --- /dev/null +++ b/test/src/test_project.c @@ -0,0 +1,31 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "test_common.h" + +void +test_project(void **state) { + mat4 model, view, proj, mvp; + vec4 viewport = {0.0f, 0.0f, 800.0f, 600.0f}; + vec3 pos = {13.0f, 45.0f, 0.74f}; + vec3 projected, unprojected; + + glm_translate_make(model, (vec3){0.0f, 0.0f, -10.0f}); + glm_lookat((vec3){0.0f, 0.0f, 0.0f}, pos, GLM_YUP, view); + + glm_perspective_default(0.5f, proj); + glm_mat4_mulN((mat4 *[]){&proj, &view, &model}, 3, mvp); + + glmc_project(pos, mvp, viewport, projected); + glmc_unproject(projected, mvp, viewport, unprojected); + + /* unprojected of projected vector must be same as original one */ + /* we used 0.01 because of projection floating point errors */ + assert_true(fabsf(pos[0] - unprojected[0]) < 0.01); + assert_true(fabsf(pos[1] - unprojected[1]) < 0.01); + assert_true(fabsf(pos[2] - unprojected[2]) < 0.01); +} diff --git a/test/src/test_tests.h b/test/src/test_tests.h index a4e5adb..26eb91d 100644 --- a/test/src/test_tests.h +++ b/test/src/test_tests.h @@ -16,4 +16,7 @@ test_camera_lookat(void **state); void test_camera_decomp(void **state); +void +test_project(void **state); + #endif /* test_tests_h */