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 
27 #ifndef PI
28 #define PI 3.141592653f
29 #endif
30 
31 // Basic vector math.
32 
33 struct vec2
34 {
35  union
36  {
37  struct
38  {
39  float x, y;
40  } c;
41  // Allow us to use vec2, vec3 and vec4 directly in uniform buffers.
42  // GLSL using std140 packing demands that packing of vectors is four floats.
43  // The rules on packing with arrays can be slightly complicated howewer.
44  float data[2];
45  };
46  enum { vector_size = 2 };
47  vec2() {}
48  vec2(float s) { c.x = c.y = s; }
49  vec2(float x, float y) { c.x = x; c.y = y; }
50  vec2(const float *vec) { memcpy(data, vec, 2 * sizeof(float)); }
51 };
52 
53 struct vec3
54 {
55  union
56  {
57  struct
58  {
59  float x, y, z;
60  } c;
61  float data[4];
62  };
63  enum { vector_size = 3 };
64  vec3() {}
65  vec3(float s) { c.x = c.y = c.z = s; }
66  vec3(float x, float y, float z) { c.x = x; c.y = y; c.z = z; }
67  vec3(const float *vec) { memcpy(data, vec, 3 * sizeof(float)); }
68 };
69 
70 struct vec4
71 {
72  union
73  {
74  struct
75  {
76  float x, y, z, w;
77  } c;
78  float data[4];
79  };
80  enum { vector_size = 4 };
81  vec4() {}
82  vec4(float s) { c.x = c.y = c.z = c.w = s; }
83  vec4(float x, float y, float z, float w) { c.x = x; c.y = y; c.z = z; c.w = w; }
84  vec4(const float *vec) { memcpy(data, vec, 4 * sizeof(float)); }
85 
86  vec4(const vec3& vec, float v)
87  {
88  *this = vec4(vec.c.x, vec.c.y, vec.c.z, v);
89  }
90 
91  vec4(const vec2& a, const vec2& b)
92  {
93  *this = vec4(a.c.x, a.c.y, b.c.x, b.c.y);
94  }
95 };
96 
97 struct mat4
98 {
99  float data[16];
100 
101  mat4() {}
102  mat4(float s) { for (unsigned int i = 0; i < 16; i++) data[i] = s; }
103  mat4(float c00, float c01, float c02, float c03,
104  float c10, float c11, float c12, float c13,
105  float c20, float c21, float c22, float c23,
106  float c30, float c31, float c32, float c33)
107  {
108  data[ 0] = c00; data[ 1] = c01; data[ 2] = c02; data[ 3] = c03;
109  data[ 4] = c10; data[ 5] = c11; data[ 6] = c12; data[ 7] = c13;
110  data[ 8] = c20; data[ 9] = c21; data[10] = c22; data[11] = c23;
111  data[12] = c30; data[13] = c31; data[14] = c32; data[15] = c33;
112  }
113  mat4(const float *mat) { memcpy(data, mat, 16 * sizeof(float)); }
114 };
115 
116 template<typename T>
117 inline T operator-(const T& a)
118 {
119  T res;
120  for (unsigned int i = 0; i < T::vector_size; i++)
121  res.data[i] = -a.data[i];
122  return res;
123 }
124 
125 template<typename T>
126 inline T operator*(const T& a, const T& b)
127 {
128  T res;
129  for (unsigned int i = 0; i < T::vector_size; i++)
130  res.data[i] = a.data[i] * b.data[i];
131  return res;
132 }
133 
134 template<typename T>
135 inline T operator/(const T& a, const T& b)
136 {
137  T res;
138  for (unsigned int i = 0; i < T::vector_size; i++)
139  res.data[i] = a.data[i] / b.data[i];
140  return res;
141 }
142 
143 template<typename T>
144 inline T operator+(const T& a, const T& b)
145 {
146  T res;
147  for (unsigned int i = 0; i < T::vector_size; i++)
148  res.data[i] = a.data[i] + b.data[i];
149  return res;
150 }
151 
152 template<typename T>
153 inline T operator-(const T& a, const T& b)
154 {
155  T res;
156  for (unsigned int i = 0; i < T::vector_size; i++)
157  res.data[i] = a.data[i] - b.data[i];
158  return res;
159 }
160 
161 template<typename T>
162 inline T& operator*=(T& a, const T& b)
163 {
164  for (unsigned int i = 0; i < T::vector_size; i++)
165  a.data[i] *= b.data[i];
166  return a;
167 }
168 
169 template<typename T>
170 inline T& operator/=(T& a, const T& b)
171 {
172  for (unsigned int i = 0; i < T::vector_size; i++)
173  a.data[i] /= b.data[i];
174  return a;
175 }
176 
177 template<typename T>
178 inline T& operator+=(T& a, const T& b)
179 {
180  for (unsigned int i = 0; i < T::vector_size; i++)
181  a.data[i] += b.data[i];
182  return a;
183 }
184 
185 template<typename T>
186 inline T& operator-=(T& a, const T& b)
187 {
188  for (unsigned int i = 0; i < T::vector_size; i++)
189  a.data[i] -= b.data[i];
190  return a;
191 }
192 
193 inline mat4 operator*(const mat4& a, const mat4& b)
194 {
195  mat4 res;
196  for (unsigned int r = 0; r < 4; r++)
197  {
198  for (unsigned int c = 0; c < 4; c++)
199  {
200  float sum = 0.0f;
201  for (unsigned int k = 0; k < 4; k++)
202  sum += a.data[r + 4 * k] * b.data[4 * c + k];
203  res.data[r + 4 * c] = sum;
204  }
205  }
206 
207  return res;
208 }
209 
210 inline vec4 operator*(const mat4& mat, const vec4& vec)
211 {
212  vec4 res(0.0f);
213  for (unsigned int i = 0; i < 4; i++)
214  res += vec4(mat.data + 4 * i) * vec4(vec.data[i]);
215  return res;
216 }
217 
218 inline mat4& operator*=(mat4& mat, float v)
219 {
220  for (unsigned int i = 0; i < 16; i++)
221  mat.data[i] *= v;
222  return mat;
223 }
224 
225 inline vec3 vec_cross(const vec3& a, const vec3& b)
226 {
227  return vec3(
228  a.c.y * b.c.z - b.c.y * a.c.z,
229  a.c.z * b.c.x - b.c.z * a.c.x,
230  a.c.x * b.c.y - b.c.x * a.c.y);
231 }
232 
233 template<typename T>
234 inline float vec_dot(const T& a, const T& b)
235 {
236  float sum = 0.0f;
237  for (unsigned int i = 0; i < T::vector_size; i++)
238  sum += a.data[i] * b.data[i];
239  return sum;
240 }
241 
242 template<typename T>
243 inline float vec_length(const T& vec)
244 {
245  return sqrt(vec_dot(vec, vec));
246 }
247 
248 template<typename T>
249 inline T vec_normalize(const T& vec)
250 {
251  return vec / T(vec_length(vec));
252 }
253 
254 template<typename T>
255 inline T vec_floor(const T& vec)
256 {
257  T res;
258  for (unsigned int i = 0; i < T::vector_size; i++)
259  res.data[i] = floor(vec.data[i]);
260  return res;
261 }
262 
263 template<typename T>
264 inline T vec_fract(const T& vec)
265 {
266  return vec - vec_floor(vec);
267 }
268 
269 inline vec3 vec_project(const vec4& vec)
270 {
271  return vec3(vec.data) / vec3(vec.c.w);
272 }
273 
274 inline mat4 mat_look_at(const vec3& eye, const vec3& center,
275  const vec3& up)
276 {
277  vec3 zaxis = vec_normalize(center - eye);
278  vec3 xaxis = vec_normalize(vec_cross(zaxis, up));
279  vec3 yaxis = vec_cross(xaxis, zaxis);
280  return mat4(
281  xaxis.c.x, yaxis.c.x, -zaxis.c.x, 0.0f,
282  xaxis.c.y, yaxis.c.y, -zaxis.c.y, 0.0f,
283  xaxis.c.z, yaxis.c.z, -zaxis.c.z, 0.0f,
284  -vec_dot(xaxis, eye), -vec_dot(yaxis, eye), -vec_dot(-zaxis, eye), 1.0f);
285 }
286 
287 inline mat4 mat_perspective_fov(float fovy, float aspect,
288  float zn, float zf)
289 {
290  float yFac = tanf(fovy * PI / 360.0f);
291  float xFac = yFac * aspect;
292  return mat4(1.0f / xFac, 0.0f, 0.0f, 0.0f,
293  0.0f, 1.0f / yFac, 0.0f, 0.0f,
294  0.0f, 0.0f, -(zf + zn) / (zf - zn), -1.0f,
295  0.0f, 0.0f, -(2.0f * zf * zn) / (zf - zn), 0.0f);
296 }
297 
298 inline mat4 mat_inverse(const mat4& a)
299 {
300  float a0 = a.data[ 0] * a.data[ 5] - a.data[ 4] * a.data[ 1];
301  float a1 = a.data[ 0] * a.data[ 9] - a.data[ 8] * a.data[ 1];
302  float a2 = a.data[ 0] * a.data[13] - a.data[12] * a.data[ 1];
303  float a3 = a.data[ 4] * a.data[ 9] - a.data[ 8] * a.data[ 5];
304  float a4 = a.data[ 4] * a.data[13] - a.data[12] * a.data[ 5];
305  float a5 = a.data[ 8] * a.data[13] - a.data[12] * a.data[ 9];
306  float b0 = a.data[ 2] * a.data[ 7] - a.data[ 6] * a.data[ 3];
307  float b1 = a.data[ 2] * a.data[11] - a.data[10] * a.data[ 3];
308  float b2 = a.data[ 2] * a.data[15] - a.data[14] * a.data[ 3];
309  float b3 = a.data[ 6] * a.data[11] - a.data[10] * a.data[ 7];
310  float b4 = a.data[ 6] * a.data[15] - a.data[14] * a.data[ 7];
311  float b5 = a.data[10] * a.data[15] - a.data[14] * a.data[11];
312 
313  float det = a0 * b5 - a1 * b4 + a2 * b3 + a3 * b2 - a4 * b1 + a5 * b0;
314  float inv_det = 1.0f / det;
315 
316  mat4 inv;
317  inv.data[ 0] = + a.data[5] * b5 - a.data[ 9] * b4 + a.data[13] * b3;
318  inv.data[ 1] = - a.data[1] * b5 + a.data[ 9] * b2 - a.data[13] * b1;
319  inv.data[ 2] = + a.data[1] * b4 - a.data[ 5] * b2 + a.data[13] * b0;
320  inv.data[ 3] = - a.data[1] * b3 + a.data[ 5] * b1 - a.data[ 9] * b0;
321  inv.data[ 4] = - a.data[4] * b5 + a.data[ 8] * b4 - a.data[12] * b3;
322  inv.data[ 5] = + a.data[0] * b5 - a.data[ 8] * b2 + a.data[12] * b1;
323  inv.data[ 6] = - a.data[0] * b4 + a.data[ 4] * b2 - a.data[12] * b0;
324  inv.data[ 7] = + a.data[0] * b3 - a.data[ 4] * b1 + a.data[ 8] * b0;
325  inv.data[ 8] = + a.data[7] * a5 - a.data[11] * a4 + a.data[15] * a3;
326  inv.data[ 9] = - a.data[3] * a5 + a.data[11] * a2 - a.data[15] * a1;
327  inv.data[10] = + a.data[3] * a4 - a.data[ 7] * a2 + a.data[15] * a0;
328  inv.data[11] = - a.data[3] * a3 + a.data[ 7] * a1 - a.data[11] * a0;
329  inv.data[12] = - a.data[6] * a5 + a.data[10] * a4 - a.data[14] * a3;
330  inv.data[13] = + a.data[2] * a5 - a.data[10] * a2 + a.data[14] * a1;
331  inv.data[14] = - a.data[2] * a4 + a.data[ 6] * a2 - a.data[14] * a0;
332  inv.data[15] = + a.data[2] * a3 - a.data[ 6] * a1 + a.data[10] * a0;
333 
334  inv *= inv_det;
335  return inv;
336 }
337 
338 #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:50
const GLfloat * v
Definition: gl2ext.h:2231
vec3()
Definition: vector_math.h:64
float data[4]
Definition: vector_math.h:121
vec2()
Definition: vector_math.h:47
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:91
vec3(const float *vec)
Definition: vector_math.h:67
GLboolean GLboolean GLboolean GLboolean a
Definition: gl2ext.h:306
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
Definition: matrix.h:28
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:49
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
float z
Definition: matrix.h:55
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
Definition: gl2ext.h:179
mat4(const float *mat)
Definition: vector_math.h:113
Definition: matrix.h:75
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:103
vec4(float x, float y, float z, float w)
Definition: vector_math.h:83
float vec_length(const T &vec)
Definition: vector_math.h:298
vec2(float s)
Definition: vector_math.h:48
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
GLfloat GLfloat f
Definition: gl2ext.h:2707
#define PI
Definition: vector_math.h:28
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:65
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_perspective_fov(float fovy, float aspect, float zn, float zf)
Definition: vector_math.h:419
mat4()
Definition: vector_math.h:101
float data[16]
Definition: vector_math.h:151
vec4(const vec3 &vec, float v)
Definition: vector_math.h:86
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
Definition: matrix.h:104
T::vector_type & operator*=(T &a, const T &b)
Definition: vector_math.h:217
mat4 mat_inverse(const mat4 &a)
Definition: vector_math.h:430
vec4(float s)
Definition: vector_math.h:82
float z
Definition: matrix.h:79
T::vector_type & operator-=(T &a, const T &b)
Definition: vector_math.h:241
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:84
float x
Definition: matrix.h:77
vec3 vec_project(const vec4 &vec)
Definition: vector_math.h:333
float y
Definition: matrix.h:78
GLint y
Definition: gl2ext.h:179
vec3(float x, float y, float z)
Definition: vector_math.h:66
vec4()
Definition: vector_math.h:81
mat4(float s)
Definition: vector_math.h:102