1 /*
2 * Copyright (c), Recep Aslantas.
3 *
4 * MIT License (MIT), http://opensource.org/licenses/MIT
5 * Full license can be found in the LICENSE file
6 */
7
8 /*
9 Functions:
10 CGLM_INLINE void glm_frustum_lh_no(float left, float right,
11 float bottom, float top,
12 float nearZ, float farZ,
13 mat4 dest)
14 CGLM_INLINE void glm_perspective_lh_no(float fovy,
15 float aspect,
16 float nearZ,
17 float farZ,
18 mat4 dest)
19 CGLM_INLINE void glm_perspective_default_lh_no(float aspect, mat4 dest)
20 CGLM_INLINE void glm_perspective_resize_lh_no(float aspect, mat4 proj)
21 CGLM_INLINE void glm_persp_move_far_lh_no(mat4 proj,
22 float deltaFar)
23 CGLM_INLINE void glm_persp_decomp_lh_no(mat4 proj,
24 float * __restrict nearZ,
25 float * __restrict farZ,
26 float * __restrict top,
27 float * __restrict bottom,
28 float * __restrict left,
29 float * __restrict right)
30 CGLM_INLINE void glm_persp_decompv_lh_no(mat4 proj,
31 float dest[6])
32 CGLM_INLINE void glm_persp_decomp_x_lh_no(mat4 proj,
33 float * __restrict left,
34 float * __restrict right)
35 CGLM_INLINE void glm_persp_decomp_y_lh_no(mat4 proj,
36 float * __restrict top,
37 float * __restrict bottom)
38 CGLM_INLINE void glm_persp_decomp_z_lh_no(mat4 proj,
39 float * __restrict nearZ,
40 float * __restrict farZ)
41 CGLM_INLINE void glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ)
42 CGLM_INLINE void glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ)
43 CGLM_INLINE void glm_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest)
44 */
45
46 #ifndef cglm_persp_lh_no_h
47 #define cglm_persp_lh_no_h
48
49 #include "../common.h"
50 #include "persp.h"
51
52 /*!
53 * @brief set up perspective peprojection matrix
54 * with a left-hand coordinate system and a
55 * clip-space of [-1, 1].
56 *
57 * @param[in] left viewport.left
58 * @param[in] right viewport.right
59 * @param[in] bottom viewport.bottom
60 * @param[in] top viewport.top
61 * @param[in] nearZ near clipping plane
62 * @param[in] farZ far clipping plane
63 * @param[out] dest result matrix
64 */
65 CGLM_INLINE
66 void
glm_frustum_lh_no(float left,float right,float bottom,float top,float nearZ,float farZ,mat4 dest)67 glm_frustum_lh_no(float left, float right,
68 float bottom, float top,
69 float nearZ, float farZ,
70 mat4 dest) {
71 float rl, tb, fn, nv;
72
73 glm_mat4_zero(dest);
74
75 rl = 1.0f / (right - left);
76 tb = 1.0f / (top - bottom);
77 fn =-1.0f / (farZ - nearZ);
78 nv = 2.0f * nearZ;
79
80 dest[0][0] = nv * rl;
81 dest[1][1] = nv * tb;
82 dest[2][0] = (right + left) * rl;
83 dest[2][1] = (top + bottom) * tb;
84 dest[2][2] =-(farZ + nearZ) * fn;
85 dest[2][3] = 1.0f;
86 dest[3][2] = farZ * nv * fn;
87 }
88
89 /*!
90 * @brief set up perspective projection matrix
91 * with a left-hand coordinate system and a
92 * clip-space of [-1, 1].
93 *
94 * @param[in] fovy field of view angle
95 * @param[in] aspect aspect ratio ( width / height )
96 * @param[in] nearZ near clipping plane
97 * @param[in] farZ far clipping planes
98 * @param[out] dest result matrix
99 */
100 CGLM_INLINE
101 void
glm_perspective_lh_no(float fovy,float aspect,float nearZ,float farZ,mat4 dest)102 glm_perspective_lh_no(float fovy,
103 float aspect,
104 float nearZ,
105 float farZ,
106 mat4 dest) {
107 float f, fn;
108
109 glm_mat4_zero(dest);
110
111 f = 1.0f / tanf(fovy * 0.5f);
112 fn = 1.0f / (nearZ - farZ);
113
114 dest[0][0] = f / aspect;
115 dest[1][1] = f;
116 dest[2][2] =-(nearZ + farZ) * fn;
117 dest[2][3] = 1.0f;
118 dest[3][2] = 2.0f * nearZ * farZ * fn;
119
120 }
121
122 /*!
123 * @brief set up perspective projection matrix with default near/far
124 * and angle values with a left-hand coordinate system and a
125 * clip-space of [-1, 1].
126 *
127 * @param[in] aspect aspect ratio ( width / height )
128 * @param[out] dest result matrix
129 */
130 CGLM_INLINE
131 void
glm_perspective_default_lh_no(float aspect,mat4 dest)132 glm_perspective_default_lh_no(float aspect, mat4 dest) {
133 glm_perspective_lh_no(GLM_PI_4f, aspect, 0.01f, 100.0f, dest);
134 }
135
136 /*!
137 * @brief resize perspective matrix by aspect ratio ( width / height )
138 * this makes very easy to resize proj matrix when window /viewport
139 * resized with a left-hand coordinate system and a
140 * clip-space of [-1, 1].
141 *
142 * @param[in] aspect aspect ratio ( width / height )
143 * @param[in, out] proj perspective projection matrix
144 */
145 CGLM_INLINE
146 void
glm_perspective_resize_lh_no(float aspect,mat4 proj)147 glm_perspective_resize_lh_no(float aspect, mat4 proj) {
148 if (proj[0][0] == 0.0f)
149 return;
150
151 proj[0][0] = proj[1][1] / aspect;
152 }
153
154 /*!
155 * @brief extend perspective projection matrix's far distance
156 * with a left-hand coordinate system and a
157 * clip-space of [-1, 1].
158 *
159 * this function does not guarantee far >= near, be aware of that!
160 *
161 * @param[in, out] proj projection matrix to extend
162 * @param[in] deltaFar distance from existing far (negative to shink)
163 */
164 CGLM_INLINE
165 void
glm_persp_move_far_lh_no(mat4 proj,float deltaFar)166 glm_persp_move_far_lh_no(mat4 proj, float deltaFar) {
167 float fn, farZ, nearZ, p22, p32;
168
169 p22 = -proj[2][2];
170 p32 = proj[3][2];
171
172 nearZ = p32 / (p22 - 1.0f);
173 farZ = p32 / (p22 + 1.0f) + deltaFar;
174 fn = 1.0f / (nearZ - farZ);
175
176 proj[2][2] = -(farZ + nearZ) * fn;
177 proj[3][2] = 2.0f * nearZ * farZ * fn;
178 }
179
180 /*!
181 * @brief decomposes frustum values of perspective projection
182 * with a left-hand coordinate system and a
183 * clip-space of [-1, 1].
184 *
185 * @param[in] proj perspective projection matrix
186 * @param[out] nearZ near
187 * @param[out] farZ far
188 * @param[out] top top
189 * @param[out] bottom bottom
190 * @param[out] left left
191 * @param[out] right right
192 */
193 CGLM_INLINE
194 void
glm_persp_decomp_lh_no(mat4 proj,float * __restrict nearZ,float * __restrict farZ,float * __restrict top,float * __restrict bottom,float * __restrict left,float * __restrict right)195 glm_persp_decomp_lh_no(mat4 proj,
196 float * __restrict nearZ, float * __restrict farZ,
197 float * __restrict top, float * __restrict bottom,
198 float * __restrict left, float * __restrict right) {
199 float m00, m11, m20, m21, m22, m32, n, f;
200 float n_m11, n_m00;
201
202 m00 = proj[0][0];
203 m11 = proj[1][1];
204 m20 = proj[2][0];
205 m21 = proj[2][1];
206 m22 =-proj[2][2];
207 m32 = proj[3][2];
208
209 n = m32 / (m22 - 1.0f);
210 f = m32 / (m22 + 1.0f);
211
212 n_m11 = n / m11;
213 n_m00 = n / m00;
214
215 *nearZ = n;
216 *farZ = f;
217 *bottom = n_m11 * (m21 - 1.0f);
218 *top = n_m11 * (m21 + 1.0f);
219 *left = n_m00 * (m20 - 1.0f);
220 *right = n_m00 * (m20 + 1.0f);
221 }
222
223 /*!
224 * @brief decomposes frustum values of perspective projection
225 * with a left-hand coordinate system and a
226 * clip-space of [-1, 1].
227 * this makes easy to get all values at once
228 *
229 * @param[in] proj perspective projection matrix
230 * @param[out] dest array
231 */
232 CGLM_INLINE
233 void
glm_persp_decompv_lh_no(mat4 proj,float dest[6])234 glm_persp_decompv_lh_no(mat4 proj, float dest[6]) {
235 glm_persp_decomp_lh_no(proj, &dest[0], &dest[1], &dest[2],
236 &dest[3], &dest[4], &dest[5]);
237 }
238
239 /*!
240 * @brief decomposes left and right values of perspective projection
241 * with a left-hand coordinate system and a
242 * clip-space of [-1, 1].
243 * x stands for x axis (left / right axis)
244 *
245 * @param[in] proj perspective projection matrix
246 * @param[out] left left
247 * @param[out] right right
248 */
249 CGLM_INLINE
250 void
glm_persp_decomp_x_lh_no(mat4 proj,float * __restrict left,float * __restrict right)251 glm_persp_decomp_x_lh_no(mat4 proj,
252 float * __restrict left,
253 float * __restrict right) {
254 float nearZ, m20, m00, m22;
255
256 m00 = proj[0][0];
257 m20 = proj[2][0];
258 m22 =-proj[2][2];
259
260 nearZ = proj[3][2] / (m22 - 1.0f);
261 *left = nearZ * (m20 - 1.0f) / m00;
262 *right = nearZ * (m20 + 1.0f) / m00;
263 }
264
265 /*!
266 * @brief decomposes top and bottom values of perspective projection
267 * with a left-hand coordinate system and a
268 * clip-space of [-1, 1].
269 * y stands for y axis (top / botom axis)
270 *
271 * @param[in] proj perspective projection matrix
272 * @param[out] top top
273 * @param[out] bottom bottom
274 */
275 CGLM_INLINE
276 void
glm_persp_decomp_y_lh_no(mat4 proj,float * __restrict top,float * __restrict bottom)277 glm_persp_decomp_y_lh_no(mat4 proj,
278 float * __restrict top,
279 float * __restrict bottom) {
280 float nearZ, m21, m11, m22;
281
282 m21 = proj[2][1];
283 m11 = proj[1][1];
284 m22 =-proj[2][2];
285
286 nearZ = proj[3][2] / (m22 - 1.0f);
287 *bottom = nearZ * (m21 - 1.0f) / m11;
288 *top = nearZ * (m21 + 1.0f) / m11;
289 }
290
291 /*!
292 * @brief decomposes near and far values of perspective projection
293 * with a left-hand coordinate system and a
294 * clip-space of [-1, 1].
295 * z stands for z axis (near / far axis)
296 *
297 * @param[in] proj perspective projection matrix
298 * @param[out] nearZ near
299 * @param[out] farZ far
300 */
301 CGLM_INLINE
302 void
glm_persp_decomp_z_lh_no(mat4 proj,float * __restrict nearZ,float * __restrict farZ)303 glm_persp_decomp_z_lh_no(mat4 proj,
304 float * __restrict nearZ,
305 float * __restrict farZ) {
306 float m32, m22;
307
308 m32 = proj[3][2];
309 m22 =-proj[2][2];
310
311 *nearZ = m32 / (m22 - 1.0f);
312 *farZ = m32 / (m22 + 1.0f);
313 }
314
315 /*!
316 * @brief decomposes far value of perspective projection
317 * with a left-hand coordinate system and a
318 * clip-space of [-1, 1].
319 *
320 * @param[in] proj perspective projection matrix
321 * @param[out] farZ far
322 */
323 CGLM_INLINE
324 void
glm_persp_decomp_far_lh_no(mat4 proj,float * __restrict farZ)325 glm_persp_decomp_far_lh_no(mat4 proj, float * __restrict farZ) {
326 *farZ = proj[3][2] / (-proj[2][2] + 1.0f);
327 }
328
329 /*!
330 * @brief decomposes near value of perspective projection
331 * with a left-hand coordinate system and a
332 * clip-space of [-1, 1].
333 *
334 * @param[in] proj perspective projection matrix
335 * @param[out] nearZ near
336 */
337 CGLM_INLINE
338 void
glm_persp_decomp_near_lh_no(mat4 proj,float * __restrict nearZ)339 glm_persp_decomp_near_lh_no(mat4 proj, float * __restrict nearZ) {
340 *nearZ = proj[3][2] / (-proj[2][2] - 1.0f);
341 }
342
343 /*!
344 * @brief returns sizes of near and far planes of perspective projection
345 * with a left-hand coordinate system and a
346 * clip-space of [-1, 1].
347 *
348 * @param[in] proj perspective projection matrix
349 * @param[in] fovy fovy (see brief)
350 * @param[out] dest sizes order: [Wnear, Hnear, Wfar, Hfar]
351 */
352 CGLM_INLINE
353 void
glm_persp_sizes_lh_no(mat4 proj,float fovy,vec4 dest)354 glm_persp_sizes_lh_no(mat4 proj, float fovy, vec4 dest) {
355 float t, a, nearZ, farZ;
356
357 t = 2.0f * tanf(fovy * 0.5f);
358 a = glm_persp_aspect(proj);
359
360 glm_persp_decomp_z_lh_no(proj, &nearZ, &farZ);
361
362 dest[1] = t * nearZ;
363 dest[3] = t * farZ;
364 dest[0] = a * dest[1];
365 dest[2] = a * dest[3];
366 }
367
368 /*!
369 * @brief returns field of view angle along the Y-axis (in radians)
370 * with a left-hand coordinate system and a clip-space of [-1, 1].
371 *
372 * if you need to degrees, use glm_deg to convert it or use this:
373 * fovy_deg = glm_deg(glm_persp_fovy(projMatrix))
374 *
375 * @param[in] proj perspective projection matrix
376 */
377 CGLM_INLINE
378 float
glm_persp_fovy_lh_no(mat4 proj)379 glm_persp_fovy_lh_no(mat4 proj) {
380 return glm_persp_fovy(proj);
381 }
382
383 /*!
384 * @brief returns aspect ratio of perspective projection
385 * with a left-hand coordinate system and a clip-space of [-1, 1].
386 *
387 * @param[in] proj perspective projection matrix
388 */
389 CGLM_INLINE
390 float
glm_persp_aspect_lh_no(mat4 proj)391 glm_persp_aspect_lh_no(mat4 proj) {
392 return glm_persp_aspect(proj);
393 }
394
395 #endif /*cglm_cam_lh_no_h*/
396