diff --git a/include/cglm/clipspace/project_no.h b/include/cglm/clipspace/project_no.h new file mode 100644 index 0000000..4496364 --- /dev/null +++ b/include/cglm/clipspace/project_no.h @@ -0,0 +1,57 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_project_no_h +#define cglm_project_no_h + +#include "../common.h" +#include "../vec3.h" +#include "../vec4.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] pos point/position in viewport coordinates + * @param[in] invMat matrix (see brief) + * @param[in] vp viewport as [x, y, width, height] + * @param[out] dest unprojected coordinates + */ +CGLM_INLINE +void +glm_unprojecti_no(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) { + vec4 v; + + 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], v); + glm_vec3(v, dest); +} + +#endif /* cglm_project_no_h */ diff --git a/include/cglm/clipspace/project_zo.h b/include/cglm/clipspace/project_zo.h new file mode 100644 index 0000000..e23d086 --- /dev/null +++ b/include/cglm/clipspace/project_zo.h @@ -0,0 +1,57 @@ +/* + * Copyright (c), Recep Aslantas. + * + * MIT License (MIT), http://opensource.org/licenses/MIT + * Full license can be found in the LICENSE file + */ + +#ifndef cglm_project_zo_h +#define cglm_project_zo_h + +#include "../common.h" +#include "../vec3.h" +#include "../vec4.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] pos point/position in viewport coordinates + * @param[in] invMat matrix (see brief) + * @param[in] vp viewport as [x, y, width, height] + * @param[out] dest unprojected coordinates + */ +CGLM_INLINE +void +glm_unprojecti_zo(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) { + vec4 v; + + 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] = pos[2]; + v[3] = 1.0f; + + glm_mat4_mulv(invMat, v, v); + glm_vec4_scale(v, 1.0f / v[3], v); + glm_vec3(v, dest); +} + +#endif /* cglm_project_zo_h */ diff --git a/include/cglm/project.h b/include/cglm/project.h index 1336222..b39b6b6 100644 --- a/include/cglm/project.h +++ b/include/cglm/project.h @@ -13,6 +13,17 @@ #include "vec4.h" #include "mat4.h" +#ifndef CGLM_CLIPSPACE_INCLUDE_ALL +# if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT +# include "clipspace/project_zo.h" +# elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT +# include "clipspace/project_no.h" +# endif +#else +# include "clipspace/project_zo.h" +# include "clipspace/project_no.h" +#endif + /*! * @brief maps the specified viewport coordinates into specified space [1] * the matrix should contain projection matrix. @@ -42,16 +53,11 @@ CGLM_INLINE void glm_unprojecti(vec3 pos, mat4 invMat, vec4 vp, vec3 dest) { - vec4 v; - - 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], v); - glm_vec3(v, dest); +#if CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_ZO_BIT + glm_unprojecti_zo(pos, invMat, vp, dest); +#elif CGLM_CONFIG_CLIP_CONTROL & CGLM_CLIP_CONTROL_NO_BIT + glm_unprojecti_no(pos, invMat, vp, dest); +#endif } /*!