OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector_math.h
Go to the documentation of this file.
1 /* Copyright (c) 2014-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #ifndef VECTOR_MATH_H__
22 #define VECTOR_MATH_H__
23 
24 #include <string.h>
25 #include <math.h>
26 #include <stdint.h>
27 
28 #ifndef PI
29 #define PI 3.141592653f
30 #endif
31 
32 // Basic vector math.
33 
34 template<typename T>
35 const typename T::data_type *value_ptr(const T& vec)
36 {
37  return vec.data;
38 }
39 
40 struct vec2
41 {
42  union
43  {
44  struct
45  {
46  float x, y;
47  } c;
48  // Allow us to use vec2, vec3 and vec4 directly in uniform buffers.
49  // GLSL using std140 packing demands that packing of vectors is four floats.
50  // The rules on packing with arrays can be slightly complicated howewer.
51  float data[2];
52  };
53  enum { vector_size = 2 };
54  typedef float data_type;
55  typedef vec2 vector_type;
56  vec2() {}
57  vec2(float s) { c.x = c.y = s; }
58  vec2(float x, float y) { c.x = x; c.y = y; }
59  vec2(const float *vec) { memcpy(data, vec, 2 * sizeof(float)); }
60 };
61 
62 struct uvec2
63 {
64  union
65  {
66  struct
67  {
68  uint32_t x, y;
69  } c;
70  // Allow us to use vec2, vec3 and vec4 directly in uniform buffers.
71  // GLSL using std140 packing demands that packing of vectors is four floats.
72  // The rules on packing with arrays can be slightly complicated howewer.
73  uint32_t data[2];
74  };
75  enum { vector_size = 2 };
76  typedef uint32_t data_type;
77  typedef uvec2 vector_type;
78  uvec2() {}
79  uvec2(uint32_t s) { c.x = c.y = s; }
80  uvec2(uint32_t x, uint32_t y) { c.x = x; c.y = y; }
81  uvec2(const uint32_t *vec) { memcpy(data, vec, 2 * sizeof(uint32_t)); }
82  operator vec2() const { return vec2(c.x, c.y); }
83 };
84 
85 struct vec3
86 {
87  union
88  {
89  struct
90  {
91  float x, y, z;
92  } c;
93  float data[4];
94  };
95  enum { vector_size = 3 };
96  typedef float data_type;
97  typedef vec3 vector_type;
98  vec3() {}
99  vec3(float s) { c.x = c.y = c.z = s; }
100  vec3(float x, float y, float z) { c.x = x; c.y = y; c.z = z; }
101  vec3(const float *vec) { memcpy(data, vec, 3 * sizeof(float)); }
102 };
103 
104 struct vec4
105 {
106  union
107  {
108  struct
109  {
110  float x, y, z, w;
111  } c;
112  float data[4];
113  };
114  enum { vector_size = 4 };
115  typedef float data_type;
116  typedef vec4 vector_type;
117  vec4() {}
118  vec4(float s) { c.x = c.y = c.z = c.w = s; }
119  vec4(float x, float y, float z, float w) { c.x = x; c.y = y; c.z = z; c.w = w; }
120  vec4(const float *vec) { memcpy(data, vec, 4 * sizeof(float)); }
121 
122  vec4(const vec3& vec, float v)
123  {
124  *this = vec4(vec.c.x, vec.c.y, vec.c.z, v);
125  }
126 
127  vec4(const vec2& a, const vec2& b)
128  {
129  *this = vec4(a.c.x, a.c.y, b.c.x, b.c.y);
130  }
131 
132  operator vec3() const { return vec3(data); }
133 };
134 
135 struct mat4
136 {
137  float data[16];
138 
139  mat4() {}
140  mat4(float s) { for (unsigned int i = 0; i < 16; i++) data[i] = s; }
141  mat4(float c00, float c01, float c02, float c03,
142  float c10, float c11, float c12, float c13,
143  float c20, float c21, float c22, float c23,
144  float c30, float c31, float c32, float c33)
145  {
146  data[ 0] = c00; data[ 1] = c01; data[ 2] = c02; data[ 3] = c03;
147  data[ 4] = c10; data[ 5] = c11; data[ 6] = c12; data[ 7] = c13;
148  data[ 8] = c20; data[ 9] = c21; data[10] = c22; data[11] = c23;
149  data[12] = c30; data[13] = c31; data[14] = c32; data[15] = c33;
150  }
151  mat4(const float *mat) { memcpy(data, mat, 16 * sizeof(float)); }
152  typedef float data_type;
153 };
154 
155 // Use SFINAE to avoid dubious overloads.
156 
157 template<typename T>
158 inline typename T::vector_type operator-(const T& a)
159 {
160  T res;
161  for (unsigned int i = 0; i < T::vector_size; i++)
162  res.data[i] = -a.data[i];
163  return res;
164 }
165 
166 template<typename T>
167 inline typename T::vector_type operator*(const T& a, const T& b)
168 {
169  T res;
170  for (unsigned int i = 0; i < T::vector_size; i++)
171  res.data[i] = a.data[i] * b.data[i];
172  return res;
173 }
174 
175 template<typename T>
176 inline typename T::vector_type operator/(const T& a, const T& b)
177 {
178  T res;
179  for (unsigned int i = 0; i < T::vector_size; i++)
180  res.data[i] = a.data[i] / b.data[i];
181  return res;
182 }
183 
184 template<typename T>
185 inline typename T::vector_type operator+(const T& a, const T& b)
186 {
187  T res;
188  for (unsigned int i = 0; i < T::vector_size; i++)
189  res.data[i] = a.data[i] + b.data[i];
190  return res;
191 }
192 
193 template<typename T>
194 inline typename T::vector_type operator-(const T& a, const T& b)
195 {
196  T res;
197  for (unsigned int i = 0; i < T::vector_size; i++)
198  res.data[i] = a.data[i] - b.data[i];
199  return res;
200 }
201 
202 template<typename T>
203 inline typename T::vector_type& operator*=(T& a, const T& b)
204 {
205  for (unsigned int i = 0; i < T::vector_size; i++)
206  a.data[i] *= b.data[i];
207  return a;
208 }
209 
210 template<typename T>
211 inline typename T::vector_type& operator/=(T& a, const T& b)
212 {
213  for (unsigned int i = 0; i < T::vector_size; i++)
214  a.data[i] /= b.data[i];
215  return a;
216 }
217 
218 template<typename T>
219 inline typename T::vector_type& operator+=(T& a, const T& b)
220 {
221  for (unsigned int i = 0; i < T::vector_size; i++)
222  a.data[i] += b.data[i];
223  return a;
224 }
225 
226 template<typename T>
227 inline typename T::vector_type& operator-=(T& a, const T& b)
228 {
229  for (unsigned int i = 0; i < T::vector_size; i++)
230  a.data[i] -= b.data[i];
231  return a;
232 }
233 
234 inline mat4 operator*(const mat4& a, const mat4& b)
235 {
236  mat4 res;
237  for (unsigned int r = 0; r < 4; r++)
238  {
239  for (unsigned int c = 0; c < 4; c++)
240  {
241  float sum = 0.0f;
242  for (unsigned int k = 0; k < 4; k++)
243  sum += a.data[r + 4 * k] * b.data[4 * c + k];
244  res.data[r + 4 * c] = sum;
245  }
246  }
247 
248  return res;
249 }
250 
251 inline vec4 operator*(const mat4& mat, const vec4& vec)
252 {
253  vec4 res(0.0f);
254  for (unsigned int i = 0; i < 4; i++)
255  res += vec4(mat.data + 4 * i) * vec4(vec.data[i]);
256  return res;
257 }
258 
259 inline mat4& operator*=(mat4& mat, float v)
260 {
261  for (unsigned int i = 0; i < 16; i++)
262  mat.data[i] *= v;
263  return mat;
264 }
265 
266 inline vec3 vec_cross(const vec3& a, const vec3& b)
267 {
268  return vec3(
269  a.c.y * b.c.z - b.c.y * a.c.z,
270  a.c.z * b.c.x - b.c.z * a.c.x,
271  a.c.x * b.c.y - b.c.x * a.c.y);
272 }
273 
274 template<typename T>
275 inline float vec_dot(const T& a, const T& b)
276 {
277  float sum = 0.0f;
278  for (unsigned int i = 0; i < T::vector_size; i++)
279  sum += a.data[i] * b.data[i];
280  return sum;
281 }
282 
283 template<typename T>
284 inline float vec_length(const T& vec)
285 {
286  return sqrt(vec_dot(vec, vec));
287 }
288 
289 template<typename T>
290 inline T vec_normalize(const T& vec)
291 {
292  return vec / T(vec_length(vec));
293 }
294 
295 template<typename T>
296 inline T vec_floor(const T& vec)
297 {
298  T res;
299  for (unsigned int i = 0; i < T::vector_size; i++)
300  res.data[i] = floor(vec.data[i]);
301  return res;
302 }
303 
304 template<typename T>
305 inline T vec_fract(const T& vec)
306 {
307  return vec - vec_floor(vec);
308 }
309 
310 inline vec3 vec_project(const vec4& vec)
311 {
312  return vec3(vec.data) / vec3(vec.c.w);
313 }
314 
315 template<typename T>
316 inline T clamp(T value, T lo, T hi)
317 {
318  if (value < lo)
319  return lo;
320  else if (value > hi)
321  return hi;
322  else
323  return value;
324 }
325 
326 template<typename T>
327 inline T vec_clamp(const T& vec, const T& lo, const T& hi)
328 {
329  T res;
330  for (unsigned int i = 0; i < T::vector_size; i++)
331  res.data[i] = clamp(vec.data[i], lo.data[i], hi.data[i]);
332  return res;
333 }
334 
335 inline mat4 mat_look_at(const vec3& eye, const vec3& center,
336  const vec3& up)
337 {
338  vec3 zaxis = vec_normalize(center - eye);
339  vec3 xaxis = vec_normalize(vec_cross(zaxis, up));
340  vec3 yaxis = vec_cross(xaxis, zaxis);
341  return mat4(
342  xaxis.c.x, yaxis.c.x, -zaxis.c.x, 0.0f,
343  xaxis.c.y, yaxis.c.y, -zaxis.c.y, 0.0f,
344  xaxis.c.z, yaxis.c.z, -zaxis.c.z, 0.0f,
345  -vec_dot(xaxis, eye), -vec_dot(yaxis, eye), -vec_dot(-zaxis, eye), 1.0f);
346 }
347 
348 inline mat4 mat_rotate_x(float radians)
349 {
350  float cos_r = cos(radians);
351  float sin_r = sin(radians);
352 
353  return mat4(1.0f, 0.0f, 0.0f, 0.0f,
354  0.0f, cos_r, sin_r, 0.0f,
355  0.0f, -sin_r, cos_r, 0.0f,
356  0.0f, 0.0f, 0.0f, 1.0f);
357 }
358 
359 inline mat4 mat_rotate_y(float radians)
360 {
361  float cos_r = cos(radians);
362  float sin_r = sin(radians);
363 
364  return mat4(cos_r, 0.0f, sin_r, 0.0f,
365  0.0f, 1.0f, 0.0f, 0.0f,
366  -sin_r, 0.0f, cos_r, 0.0f,
367  0.0f, 0.0f, 0.0f, 1.0f);
368 }
369 
370 inline mat4 mat_rotate_z(float radians)
371 {
372  float cos_r = cos(radians);
373  float sin_r = sin(radians);
374 
375  return mat4(cos_r, sin_r, 0.0f, 0.0f,
376  -sin_r, cos_r, 0.0f, 0.0f,
377  0.0f, 0.0f, 1.0f, 0.0f,
378  0.0f, 0.0f, 0.0f, 1.0f);
379 }
380 
381 inline mat4 mat_perspective_fov(float fovy, float aspect,
382  float zn, float zf)
383 {
384  float yFac = tanf(fovy * PI / 360.0f);
385  float xFac = yFac * aspect;
386  return mat4(1.0f / xFac, 0.0f, 0.0f, 0.0f,
387  0.0f, 1.0f / yFac, 0.0f, 0.0f,
388  0.0f, 0.0f, -(zf + zn) / (zf - zn), -1.0f,
389  0.0f, 0.0f, -(2.0f * zf * zn) / (zf - zn), 0.0f);
390 }
391 
392 inline mat4 mat_inverse(const mat4& a)
393 {
394  float a0 = a.data[ 0] * a.data[ 5] - a.data[ 4] * a.data[ 1];
395  float a1 = a.data[ 0] * a.data[ 9] - a.data[ 8] * a.data[ 1];
396  float a2 = a.data[ 0] * a.data[13] - a.data[12] * a.data[ 1];
397  float a3 = a.data[ 4] * a.data[ 9] - a.data[ 8] * a.data[ 5];
398  float a4 = a.data[ 4] * a.data[13] - a.data[12] * a.data[ 5];
399  float a5 = a.data[ 8] * a.data[13] - a.data[12] * a.data[ 9];
400  float b0 = a.data[ 2] * a.data[ 7] - a.data[ 6] * a.data[ 3];
401  float b1 = a.data[ 2] * a.data[11] - a.data[10] * a.data[ 3];
402  float b2 = a.data[ 2] * a.data[15] - a.data[14] * a.data[ 3];
403  float b3 = a.data[ 6] * a.data[11] - a.data[10] * a.data[ 7];
404  float b4 = a.data[ 6] * a.data[15] - a.data[14] * a.data[ 7];
405  float b5 = a.data[10] * a.data[15] - a.data[14] * a.data[11];
406 
407  float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
408  float inv_det = 1.0f / det;
409 
410  mat4 inv;
411  inv.data[ 0] = + a.data[5] * b5 - a.data[ 9] * b4 + a.data[13] * b3;
412  inv.data[ 1] = - a.data[1] * b5 + a.data[ 9] * b2 - a.data[13] * b1;
413  inv.data[ 2] = + a.data[1] * b4 - a.data[ 5] * b2 + a.data[13] * b0;
414  inv.data[ 3] = - a.data[1] * b3 + a.data[ 5] * b1 - a.data[ 9] * b0;
415  inv.data[ 4] = - a.data[4] * b5 + a.data[ 8] * b4 - a.data[12] * b3;
416  inv.data[ 5] = + a.data[0] * b5 - a.data[ 8] * b2 + a.data[12] * b1;
417  inv.data[ 6] = - a.data[0] * b4 + a.data[ 4] * b2 - a.data[12] * b0;
418  inv.data[ 7] = + a.data[0] * b3 - a.data[ 4] * b1 + a.data[ 8] * b0;
419  inv.data[ 8] = + a.data[7] * a5 - a.data[11] * a4 + a.data[15] * a3;
420  inv.data[ 9] = - a.data[3] * a5 + a.data[11] * a2 - a.data[15] * a1;
421  inv.data[10] = + a.data[3] * a4 - a.data[ 7] * a2 + a.data[15] * a0;
422  inv.data[11] = - a.data[3] * a3 + a.data[ 7] * a1 - a.data[11] * a0;
423  inv.data[12] = - a.data[6] * a5 + a.data[10] * a4 - a.data[14] * a3;
424  inv.data[13] = + a.data[2] * a5 - a.data[10] * a2 + a.data[14] * a1;
425  inv.data[14] = - a.data[2] * a4 + a.data[ 6] * a2 - a.data[14] * a0;
426  inv.data[15] = + a.data[2] * a3 - a.data[ 6] * a1 + a.data[10] * a0;
427 
428  inv *= inv_det;
429  return inv;
430 }
431 
432 #endif
struct vec3::@35::@38 c
T vec_fract(const T &vec)
Definition: vector_math.h:328
T vec_floor(const T &vec)
Definition: vector_math.h:310
vec2(const float *vec)
Definition: vector_math.h:59
const GLfloat * v
Definition: gl2ext.h:2231
vec3()
Definition: vector_math.h:98
float data[4]
Definition: vector_math.h:121
float data_type
Definition: vector_math.h:152
vec2()
Definition: vector_math.h:56
float data_type
Definition: vector_math.h:54
T::vector_type & operator/=(T &a, const T &b)
Definition: vector_math.h:225
vec4(const vec2 &a, const vec2 &b)
Definition: vector_math.h:127
vec3(const float *vec)
Definition: vector_math.h:101
GLboolean GLboolean GLboolean GLboolean a
Definition: gl2ext.h:306
uint32_t y
Definition: vector_math.h:68
Definition: matrix.h:51
float vec_dot(const T &a, const T &b)
Definition: vector_math.h:289
GLboolean r
Definition: gl2ext.h:306
mat4 mat_look_at(const vec3 &eye, const vec3 &center, const vec3 &up)
Definition: vector_math.h:358
vec2 vector_type
Definition: vector_math.h:55
Definition: matrix.h:28
uint32_t x
Definition: vector_math.h:68
vec3 vec_cross(const vec3 &a, const vec3 &b)
Definition: vector_math.h:280
T::vector_type operator/(const T &a, const T &b)
Definition: vector_math.h:190
vec2(float x, float y)
Definition: vector_math.h:58
T::vector_type operator*(const T &a, const T &b)
Definition: vector_math.h:181
T::vector_type operator+(const T &a, const T &b)
Definition: vector_math.h:199
const T::data_type * value_ptr(const T &vec)
Definition: vector_math.h:35
mat4 mat_rotate_y(float radians)
Definition: vector_math.h:382
struct uvec2::@31::@34 c
GLint value
Definition: gl2ext.h:558
float z
Definition: matrix.h:55
#define PI
Definition: vector_math.h:29
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
Definition: gl2ext.h:179
mat4(const float *mat)
Definition: vector_math.h:151
Definition: matrix.h:75
uvec2 vector_type
Definition: vector_math.h:77
mat4(float c00, float c01, float c02, float c03, float c10, float c11, float c12, float c13, float c20, float c21, float c22, float c23, float c30, float c31, float c32, float c33)
Definition: vector_math.h:141
float data_type
Definition: vector_math.h:96
vec4(float x, float y, float z, float w)
Definition: vector_math.h:119
float vec_length(const T &vec)
Definition: vector_math.h:298
uvec2(const uint32_t *vec)
Definition: vector_math.h:81
float data_type
Definition: vector_math.h:115
vec4 vector_type
Definition: vector_math.h:116
vec2(float s)
Definition: vector_math.h:57
struct vec4::@39::@42 c
T::vector_type operator-(const T &a)
Definition: vector_math.h:172
GLfloat GLfloat GLfloat w
Definition: gl2ext.h:2701
uint32_t data_type
Definition: vector_math.h:76
GLfloat GLfloat f
Definition: gl2ext.h:2707
T::vector_type & operator+=(T &a, const T &b)
Definition: vector_math.h:233
float y
Definition: matrix.h:31
vec3(float s)
Definition: vector_math.h:99
mat4 mat_rotate_z(float radians)
Definition: vector_math.h:393
float w
Definition: matrix.h:80
float x
Definition: matrix.h:53
struct vec2::@27::@30 c
float y
Definition: matrix.h:54
mat4 mat_rotate_x(float radians)
Definition: vector_math.h:371
mat4 mat_perspective_fov(float fovy, float aspect, float zn, float zf)
Definition: vector_math.h:419
uvec2(uint32_t s)
Definition: vector_math.h:79
mat4()
Definition: vector_math.h:139
float data[16]
Definition: vector_math.h:151
vec4(const vec3 &vec, float v)
Definition: vector_math.h:122
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
vec3 vector_type
Definition: vector_math.h:97
Definition: matrix.h:104
T::vector_type & operator*=(T &a, const T &b)
Definition: vector_math.h:217
T vec_clamp(const T &vec, const T &lo, const T &hi)
Definition: vector_math.h:350
mat4 mat_inverse(const mat4 &a)
Definition: vector_math.h:430
vec4(float s)
Definition: vector_math.h:118
float z
Definition: matrix.h:79
T::vector_type & operator-=(T &a, const T &b)
Definition: vector_math.h:241
T clamp(T value, T lo, T hi)
Definition: vector_math.h:339
T vec_normalize(const T &vec)
Definition: vector_math.h:304
GLboolean GLboolean GLboolean b
Definition: gl2ext.h:306
float x
Definition: matrix.h:30
vec4(const float *vec)
Definition: vector_math.h:120
uvec2(uint32_t x, uint32_t y)
Definition: vector_math.h:80
float x
Definition: matrix.h:77
vec3 vec_project(const vec4 &vec)
Definition: vector_math.h:333
float y
Definition: matrix.h:78
uvec2()
Definition: vector_math.h:78
GLint y
Definition: gl2ext.h:179
vec3(float x, float y, float z)
Definition: vector_math.h:100
vec4()
Definition: vector_math.h:117
mat4(float s)
Definition: vector_math.h:140