From 29996d0bddea84c6ba80b5e5e0ce9f6b2e75af02 Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Thu, 8 Mar 2018 13:02:33 +0300 Subject: [PATCH] add unproject function --- include/cglm/call.h | 1 + include/cglm/call/project.h | 29 +++++++++++++ include/cglm/cglm.h | 1 + include/cglm/project.h | 84 +++++++++++++++++++++++++++++++++++++ src/project.c | 21 ++++++++++ win/cglm.vcxproj | 3 ++ win/cglm.vcxproj.filters | 9 ++++ 7 files changed, 148 insertions(+) create mode 100644 include/cglm/call/project.h create mode 100644 include/cglm/project.h create mode 100644 src/project.c diff --git a/include/cglm/call.h b/include/cglm/call.h index 3f7bf14..ce08b78 100644 --- a/include/cglm/call.h +++ b/include/cglm/call.h @@ -24,6 +24,7 @@ extern "C" { #include "call/frustum.h" #include "call/box.h" #include "call/io.h" +#include "call/project.h" #ifdef __cplusplus } diff --git a/include/cglm/call/project.h b/include/cglm/call/project.h new file mode 100644 index 0000000..1120b21 --- /dev/null +++ b/include/cglm/call/project.h @@ -0,0 +1,29 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglmc_project_h +#define cglmc_project_h +#ifdef __cplusplus +extern "C" { +#endif + +#include "../cglm.h" + +CGLM_EXPORT +void +glmc_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec3 dest); + +CGLM_EXPORT +void +glmc_unproject(mat4 m, vec2 vp, vec3 coord, vec3 dest); + +#ifdef __cplusplus +} +#endif +#endif /* cglmc_project_h */ + + diff --git a/include/cglm/cglm.h b/include/cglm/cglm.h index e99bb09..52c7e97 100644 --- a/include/cglm/cglm.h +++ b/include/cglm/cglm.h @@ -23,5 +23,6 @@ #include "color.h" #include "util.h" #include "io.h" +#include "project.h" #endif /* cglm_h */ diff --git a/include/cglm/project.h b/include/cglm/project.h new file mode 100644 index 0000000..27cb42a --- /dev/null +++ b/include/cglm/project.h @@ -0,0 +1,84 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_project_h +#define cglm_project_h + +#include "mat4.h" + +/*! + * @brief maps the specified viewport coordinates into specified space [1] + * the matrix should contain projection matrix. + * + * if you don't have ( and don't want to have ) an inverse matrix then use + * glm_unproject version. You may use existing inverse of matrix in somewhere + * else, this is why glm_unprojecti exists to save save inversion cost + * + * [1] space: + * 1- if m = invProj: View Space + * 2- if m = invViewProj: World Space + * 3- if m = invMVP: Object Space + * + * You probably want to map the coordinates into object space + * so use invMVP as m + * + * Computing viewProj: + * glm_mat4_mul(proj, view, viewProj); + * glm_mat4_mul(viewProj, model, MVP); + * glm_mat4_inv(viewProj, invMVP); + * + * @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) { + 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[3] = 1.0f; + + glm_mat4_mulv(invMat, v, dest); +} + +/*! + * @brief maps the specified viewport coordinates into specified space [1] + * the matrix should contain projection matrix. + * + * this is same as glm_unprojecti except this function get inverse matrix for + * you. + * + * [1] space: + * 1- if m = proj: View Space + * 2- if m = viewProj: World Space + * 3- if m = MVP: Object Space + * + * You probably want to map the coordinates into object space + * so use MVP as m + * + * Computing viewProj: + * glm_mat4_mul(proj, view, viewProj); + * glm_mat4_mul(viewProj, model, MVP); + * + * @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, vec2 vp, vec3 coord, vec3 dest) { + mat4 inv; + glm_mat4_inv(m, inv); + glm_unprojecti(inv, vp, coord, dest); +} + +#endif /* cglm_project_h */ diff --git a/src/project.c b/src/project.c new file mode 100644 index 0000000..80e0b44 --- /dev/null +++ b/src/project.c @@ -0,0 +1,21 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#include "../include/cglm/cglm.h" +#include "../include/cglm/call.h" + +CGLM_EXPORT +void +glmc_unprojecti(mat4 invMat, vec4 vp, vec3 coord, vec3 dest) { + glm_unprojecti(invMat, vp, coord, dest); +} + +CGLM_EXPORT +void +glmc_unproject(mat4 m, vec2 vp, vec3 coord, vec3 dest) { + glm_unproject(m, vp, coord, dest); +} diff --git a/win/cglm.vcxproj b/win/cglm.vcxproj index 4a0463d..415a87d 100644 --- a/win/cglm.vcxproj +++ b/win/cglm.vcxproj @@ -29,6 +29,7 @@ + @@ -47,6 +48,7 @@ + @@ -60,6 +62,7 @@ + diff --git a/win/cglm.vcxproj.filters b/win/cglm.vcxproj.filters index 506f3d8..3090d72 100644 --- a/win/cglm.vcxproj.filters +++ b/win/cglm.vcxproj.filters @@ -75,6 +75,9 @@ src + + src + @@ -206,5 +209,11 @@ include\cglm + + include\cglm + + + include\cglm\call + \ No newline at end of file