summaryrefslogtreecommitdiff
path: root/libs/cglm/include/cglm/struct/project.h
blob: 00f76ff47b98f8debddf9f22a53e5903f1d491cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Copyright (c), Recep Aslantas.
 *
 * MIT License (MIT), http://opensource.org/licenses/MIT
 * Full license can be found in the LICENSE file
 */

#ifndef cglms_projects_h
#define cglms_projects_h

#include "../common.h"
#include "../types-struct.h"
#include "../project.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]
 * @returns             unprojected coordinates
 */
CGLM_INLINE
vec3s
glms_unprojecti(vec3s pos, mat4s invMat, vec4s vp) {
  vec3s r;
  glm_unprojecti(pos.raw, invMat.raw, vp.raw, r.raw);
  return r;
}

/*!
 * @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 and MVP:
 *   glm_mat4_mul(proj, view, viewProj);
 *   glm_mat4_mul(viewProj, model, MVP);
 *
 * @param[in]  pos      point/position in viewport coordinates
 * @param[in]  m        matrix (see brief)
 * @param[in]  vp       viewport as [x, y, width, height]
 * @returns             unprojected coordinates
 */
CGLM_INLINE
vec3s
glms_unproject(vec3s pos, mat4s m, vec4s vp) {
  vec3s r;
  glm_unproject(pos.raw, m.raw, vp.raw, r.raw);
  return r;
}

/*!
 * @brief map object coordinates to window coordinates
 *
 * Computing MVP:
 *   glm_mat4_mul(proj, view, viewProj);
 *   glm_mat4_mul(viewProj, model, MVP);
 *
 * @param[in]  pos      object coordinates
 * @param[in]  m        MVP matrix
 * @param[in]  vp       viewport as [x, y, width, height]
 * @returns projected coordinates
 */
CGLM_INLINE
vec3s
glms_project(vec3s pos, mat4s m, vec4s vp) {
  vec3s r;
  glm_project(pos.raw, m.raw, vp.raw, r.raw);
  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(vec2s center, vec2s size, vec4s vp) {
  mat4s res;
  glm_pickmatrix(center.raw, size.raw, vp.raw, res.raw);
  return res;
}

#endif /* cglms_projects_h */