From 8427d02a9b0192c216e990a0147cb2daa55730fd Mon Sep 17 00:00:00 2001 From: Recep Aslantas Date: Mon, 16 Aug 2021 16:53:46 +0300 Subject: [PATCH] pick matrix helper (aka gluPickMatrix) --- CREDITS | 4 ++++ include/cglm/call/project.h | 4 ++++ include/cglm/project.h | 33 +++++++++++++++++++++++++++++++++ include/cglm/struct/project.h | 16 ++++++++++++++++ src/project.c | 6 ++++++ 5 files changed, 63 insertions(+) diff --git a/CREDITS b/CREDITS index c388348..00cc832 100644 --- a/CREDITS +++ b/CREDITS @@ -78,3 +78,7 @@ https://stackoverflow.com/a/57793352/2676533 16. ARM NEON Div http://github.com/microsoft/DirectXMath + +17. Pick Matrix + +glu project -> project.c diff --git a/include/cglm/call/project.h b/include/cglm/call/project.h index 35ac087..991ba1d 100644 --- a/include/cglm/call/project.h +++ b/include/cglm/call/project.h @@ -25,6 +25,10 @@ CGLM_EXPORT void glmc_project(vec3 pos, mat4 m, vec4 vp, vec3 dest); +CGLM_EXPORT +void +glmc_pickmatrix(vec2 center, vec2 size, vec4 vp, mat4 dest); + #ifdef __cplusplus } #endif diff --git a/include/cglm/project.h b/include/cglm/project.h index ceeb528..45f38a7 100644 --- a/include/cglm/project.h +++ b/include/cglm/project.h @@ -114,4 +114,37 @@ glm_project(vec3 pos, mat4 m, vec4 vp, vec3 dest) { #endif } +/*! + * @brief define a picking region + * + * @param[in] center center [x, y] of a picking region in window coordinates + * @param[in] size size [width, height] of the picking region in window coordinates + * @param[in] vp viewport as [x, y, width, height] + * @param[out] dest projected coordinates + */ +CGLM_INLINE +void +glm_pickmatrix(vec3 center, vec2 size, vec4 vp, mat4 dest) { + mat4 res; + vec3 v; + + if (size[0] <= 0.0f || size[1] <= 0.0f) + return; + + /* Translate and scale the picked region to the entire window */ + v[0] = (vp[2] - 2.0f * (center[0] - vp[0])) / size[0]; + v[1] = (vp[3] - 2.0f * (center[1] - vp[1])) / size[1]; + v[2] = 0.0f; + + glm_translate_make(res, v); + + v[0] = vp[2] / size[0]; + v[1] = vp[3] / size[1]; + v[2] = 1.0f; + + glm_scale(res, v); + + glm_mat4_copy(res, dest); +} + #endif /* cglm_project_h */ diff --git a/include/cglm/struct/project.h b/include/cglm/struct/project.h index 8a2635f..130ff99 100644 --- a/include/cglm/struct/project.h +++ b/include/cglm/struct/project.h @@ -101,4 +101,20 @@ glms_project(vec3s pos, mat4s m, vec4s vp) { return r; } +/*! + * @brief define a picking region + * + * @param[in] center center [x, y] of a picking region in window coordinates + * @param[in] size size [width, height] of the picking region in window coordinates + * @param[in] vp viewport as [x, y, width, height] + * @returns projected coordinates + */ +CGLM_INLINE +mat4s +glms_pickmatrix(vec3s center, vec2s size, vec4s vp) { + mat4s res; + glm_pickmatrix(center.raw, size.raw, vp.raw, res.raw); + return res; +} + #endif /* cglms_projects_h */ diff --git a/src/project.c b/src/project.c index 91c7128..3e09ac6 100644 --- a/src/project.c +++ b/src/project.c @@ -25,3 +25,9 @@ void glmc_project(vec3 pos, mat4 m, vec4 vp, vec3 dest) { glm_project(pos, m, vp, dest); } + +CGLM_EXPORT +void +glmc_pickmatrix(vec2 center, vec2 size, vec4 vp, mat4 dest) { + glm_pickmatrix(center, size, vp, dest); +}