OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
matrix.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 MATRIX_H
22 #define MATRIX_H
23 #ifndef PI
24 #define PI 3.141592653f
25 #endif
26 #include <math.h>
27 
28 struct vec2
29 {
30  float x;
31  float y;
32 
33  vec2() : x(0.0f), y(0.0f) { }
34  vec2(float X, float Y) : x(X), y(Y){ }
35  explicit vec2(float S) : x(S), y(S) { }
36  vec2 operator + (const vec2 &rhs) const { return vec2(x + rhs.x, y + rhs.y); }
37  vec2 operator * (const vec2 &rhs) const { return vec2(x * rhs.x, y * rhs.y); }
38  vec2 operator - (const vec2 &rhs) const { return vec2(x - rhs.x, y - rhs.y); }
39  vec2 operator * (const float s) const { return vec2(x * s, y * s); }
40  vec2 operator / (const float s) const { return vec2(x / s, y / s); }
41 
42  vec2 &operator *= (const float s) { *this = *this * s; return *this; }
43  vec2 &operator += (const vec2 &rhs) { *this = *this + rhs; return *this; }
44  vec2 &operator *= (const vec2 &rhs) { *this = *this * rhs; return *this; }
45  vec2 &operator -= (const vec2 &rhs) { *this = *this - rhs; return *this; }
46 
47  float &operator [] (unsigned int i) { return (&x)[i]; }
48  const float &operator [] (unsigned int i) const { return (&x)[i]; }
49 };
50 
51 struct vec3
52 {
53  float x;
54  float y;
55  float z;
56 
57  vec3() : x(0.0f), y(0.0f), z(0.0f) { }
58  vec3(float X, float Y, float Z) : x(X), y(Y), z(Z) { }
59  explicit vec3(float S) : x(S), y(S), z(S) { }
60  vec3 operator - () const { return vec3(-x, -y, -z); }
61  vec3 operator + (const vec3 &rhs) const { return vec3(x + rhs.x, y + rhs.y, z + rhs.z); }
62  vec3 operator * (const vec3 &rhs) const { return vec3(x * rhs.x, y * rhs.y, z * rhs.z); }
63  vec3 operator - (const vec3 &rhs) const { return vec3(x - rhs.x, y - rhs.y, z - rhs.z); }
64  vec3 operator * (const float s) const { return vec3(x * s, y * s, z * s); }
65  vec3 operator / (const float s) const { return vec3(x / s, y / s, z / s); }
66 
67  vec3 &operator += (const vec3 &rhs) { *this = *this + rhs; return *this; }
68  vec3 &operator *= (const vec3 &rhs) { *this = *this * rhs; return *this; }
69  vec3 &operator -= (const vec3 &rhs) { *this = *this - rhs; return *this; }
70 
71  float &operator [] (unsigned int i) { return (&x)[i]; }
72  const float &operator [] (unsigned int i) const { return (&x)[i]; }
73 };
74 
75 struct vec4
76 {
77  float x;
78  float y;
79  float z;
80  float w;
81 
82  vec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
83  vec4(vec3 V, float W) : x(V.x), y(V.y), z(V.z), w(W) { }
84  vec4(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { }
85  explicit vec4(float S) : x(S), y(S), z(S), w(S) { }
86  vec4 operator - () const { return vec4(-x, -y, -z, -w); }
87  vec4 operator + (const vec4 &rhs) const { return vec4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); }
88  vec4 operator * (const vec4 &rhs) const { return vec4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w); }
89  vec4 operator - (const vec4 &rhs) const { return vec4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); }
90  vec4 operator * (const float s) const { return vec4(x * s, y * s, z * s, w * s); }
91  vec4 operator / (const float s) const { return vec4(x / s, y / s, z / s, w / s); }
92 
93  vec4 &operator *= (const float s) { *this = *this * s; return *this; }
94  vec4 &operator += (const vec4 &rhs) { *this = *this + rhs; return *this; }
95  vec4 &operator *= (const vec4 &rhs) { *this = *this * rhs; return *this; }
96  vec4 &operator -= (const vec4 &rhs) { *this = *this - rhs; return *this; }
97 
98  float &operator [] (unsigned int i) { return (&x)[i]; }
99  const float &operator [] (unsigned int i) const { return (&x)[i]; }
100 
101  vec3 xyz() const { return vec3(x, y, z); }
102 };
103 
104 struct mat4
105 {
106  vec4 x, y, z, w; // columns
107 
108  mat4() { }
109  explicit mat4(float s) : x(0.0f), y(0.0f), z(0.0f), w(0.0f)
110  {
111  x.x = s;
112  y.y = s;
113  z.z = s;
114  w.w = s;
115  }
116 
117  mat4 operator * (const mat4 &rhs)
118  {
119  mat4 m;
120  for (int lrow = 0; lrow < 4; ++lrow)
121  {
122  for (int rcol = 0; rcol < 4; ++rcol)
123  {
124  m[rcol][lrow] = 0.0f;
125  for (int k = 0; k < 4; ++k)
126  m[rcol][lrow] += (*this)[k][lrow] * rhs[rcol][k];
127 
128  }
129  }
130  return m;
131  }
132 
133  mat4 operator * (const float s)
134  {
135  mat4 m = *this;
136  m.x *= s;
137  m.y *= s;
138  m.z *= s;
139  m.w *= s;
140  return m;
141  }
142 
143  vec4 operator * (const vec4 &rhs)
144  {
145  return x * rhs.x + y * rhs.y + z * rhs.z + w * rhs.w;
146  }
147 
148  vec4 &operator [] (unsigned int i) { return (&x)[i]; }
149  const vec4 &operator [] (unsigned int i) const { return (&x)[i]; }
150  const float *value_ptr() const { return &(x[0]); }
151  float *value_ptr() { return &(x[0]); }
152 };
153 
154 static vec3 normalize(const vec3 &v)
155 {
156  return v / sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
157 }
158 
159 static mat4 perspective(float fovy, float aspect, float near, float far)
160 {
161  mat4 m(1.0f);
162  float invtf = 1.0f / tan(fovy * 0.5f);
163  m[0].x = invtf / aspect;
164  m[1].y = invtf;
165  m[2].z = -(far + near) / (far - near);
166  m[2].w = -1.0f;
167  m[3].z = (-2.0f * far * near) / (far - near);
168  m[3].w = 0.0f;
169  return m;
170 }
171 
172 static mat4 orthographic(float left, float right, float bottom, float top, float near, float far)
173 {
174  mat4 m(1.0f);
175  m[0].x = 2.0f / (right - left);
176  m[3].x = -(right + left) / (right - left);
177  m[1].y = 2.0f / (top - bottom);
178  m[3].y = -(top + bottom) / (top - bottom);
179  m[2].z = -2.0f / (far - near);
180  m[3].z = -(far + near) / (far - near);
181  return m;
182 }
183 
184 // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix
185 static mat4 inverse(const mat4 &op)
186 {
187  mat4 inv_mat(0.0f);
188  const float *m = op.value_ptr();
189  float *inv = inv_mat.value_ptr();
190 
191  inv[0] = m[5] * m[10] * m[15] -
192  m[5] * m[11] * m[14] -
193  m[9] * m[6] * m[15] +
194  m[9] * m[7] * m[14] +
195  m[13] * m[6] * m[11] -
196  m[13] * m[7] * m[10];
197 
198  inv[4] = -m[4] * m[10] * m[15] +
199  m[4] * m[11] * m[14] +
200  m[8] * m[6] * m[15] -
201  m[8] * m[7] * m[14] -
202  m[12] * m[6] * m[11] +
203  m[12] * m[7] * m[10];
204 
205  inv[8] = m[4] * m[9] * m[15] -
206  m[4] * m[11] * m[13] -
207  m[8] * m[5] * m[15] +
208  m[8] * m[7] * m[13] +
209  m[12] * m[5] * m[11] -
210  m[12] * m[7] * m[9];
211 
212  inv[12] = -m[4] * m[9] * m[14] +
213  m[4] * m[10] * m[13] +
214  m[8] * m[5] * m[14] -
215  m[8] * m[6] * m[13] -
216  m[12] * m[5] * m[10] +
217  m[12] * m[6] * m[9];
218 
219  inv[1] = -m[1] * m[10] * m[15] +
220  m[1] * m[11] * m[14] +
221  m[9] * m[2] * m[15] -
222  m[9] * m[3] * m[14] -
223  m[13] * m[2] * m[11] +
224  m[13] * m[3] * m[10];
225 
226  inv[5] = m[0] * m[10] * m[15] -
227  m[0] * m[11] * m[14] -
228  m[8] * m[2] * m[15] +
229  m[8] * m[3] * m[14] +
230  m[12] * m[2] * m[11] -
231  m[12] * m[3] * m[10];
232 
233  inv[9] = -m[0] * m[9] * m[15] +
234  m[0] * m[11] * m[13] +
235  m[8] * m[1] * m[15] -
236  m[8] * m[3] * m[13] -
237  m[12] * m[1] * m[11] +
238  m[12] * m[3] * m[9];
239 
240  inv[13] = m[0] * m[9] * m[14] -
241  m[0] * m[10] * m[13] -
242  m[8] * m[1] * m[14] +
243  m[8] * m[2] * m[13] +
244  m[12] * m[1] * m[10] -
245  m[12] * m[2] * m[9];
246 
247  inv[2] = m[1] * m[6] * m[15] -
248  m[1] * m[7] * m[14] -
249  m[5] * m[2] * m[15] +
250  m[5] * m[3] * m[14] +
251  m[13] * m[2] * m[7] -
252  m[13] * m[3] * m[6];
253 
254  inv[6] = -m[0] * m[6] * m[15] +
255  m[0] * m[7] * m[14] +
256  m[4] * m[2] * m[15] -
257  m[4] * m[3] * m[14] -
258  m[12] * m[2] * m[7] +
259  m[12] * m[3] * m[6];
260 
261  inv[10] = m[0] * m[5] * m[15] -
262  m[0] * m[7] * m[13] -
263  m[4] * m[1] * m[15] +
264  m[4] * m[3] * m[13] +
265  m[12] * m[1] * m[7] -
266  m[12] * m[3] * m[5];
267 
268  inv[14] = -m[0] * m[5] * m[14] +
269  m[0] * m[6] * m[13] +
270  m[4] * m[1] * m[14] -
271  m[4] * m[2] * m[13] -
272  m[12] * m[1] * m[6] +
273  m[12] * m[2] * m[5];
274 
275  inv[3] = -m[1] * m[6] * m[11] +
276  m[1] * m[7] * m[10] +
277  m[5] * m[2] * m[11] -
278  m[5] * m[3] * m[10] -
279  m[9] * m[2] * m[7] +
280  m[9] * m[3] * m[6];
281 
282  inv[7] = m[0] * m[6] * m[11] -
283  m[0] * m[7] * m[10] -
284  m[4] * m[2] * m[11] +
285  m[4] * m[3] * m[10] +
286  m[8] * m[2] * m[7] -
287  m[8] * m[3] * m[6];
288 
289  inv[11] = -m[0] * m[5] * m[11] +
290  m[0] * m[7] * m[9] +
291  m[4] * m[1] * m[11] -
292  m[4] * m[3] * m[9] -
293  m[8] * m[1] * m[7] +
294  m[8] * m[3] * m[5];
295 
296  inv[15] = m[0] * m[5] * m[10] -
297  m[0] * m[6] * m[9] -
298  m[4] * m[1] * m[10] +
299  m[4] * m[2] * m[9] +
300  m[8] * m[1] * m[6] -
301  m[8] * m[2] * m[5];
302 
303  float det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
304 
305  if (det == 0)
306  return mat4(1.0f);
307 
308  det = 1.0f / det;
309  return inv_mat * det;
310 }
311 
312 static mat4 rotateX(float rad)
313 {
314  float co = cosf(rad); float si = sinf(rad);
315  mat4 m(1.0f);
316  m[1][1] = co; m[1][2] = -si; m[2][1] = si; m[2][2] = co;
317  return m;
318 }
319 
320 static mat4 rotateY(float rad)
321 {
322  float co = cosf(rad); float si = sinf(rad);
323  mat4 m(1.0f);
324  m[0][0] = co; m[0][2] = si; m[2][0] = -si; m[2][2] = co;
325  return m;
326 }
327 
328 static mat4 rotateZ(float rad)
329 {
330  float co = cosf(rad); float si = sinf(rad);
331  mat4 m(1.0f);
332  m[0][0] = co; m[1][0] = -si; m[0][1] = si; m[1][1] = co;
333  return m;
334 }
335 
336 static mat4 translate(float x, float y, float z)
337 {
338  mat4 m(1.0f);
339  m[3][0] = x; m[3][1] = y; m[3][2] = z; m[3][3] = 1.0f;
340  return m;
341 }
342 
343 static mat4 translate(const vec3 &v)
344 {
345  mat4 m(1.0f);
346  m[3][0] = v.x; m[3][1] = v.y; m[3][2] = v.z;
347  return m;
348 }
349 
350 static mat4 scale(float x, float y, float z)
351 {
352  mat4 m(1.0f);
353  m[0][0] = x; m[1][1] = y; m[2][2] = z;
354  return m;
355 }
356 
357 static mat4 scale(float s)
358 {
359  return scale(s, s, s);
360 }
361 
362 #endif
const GLfloat * v
Definition: gl2ext.h:2231
vec3()
Definition: matrix.h:57
vec4 operator+(const vec4 &rhs) const
Definition: matrix.h:87
vec2()
Definition: matrix.h:33
vec2 & operator-=(const vec2 &rhs)
Definition: matrix.h:45
vec3 & operator+=(const vec3 &rhs)
Definition: matrix.h:67
vec3 xyz() const
Definition: matrix.h:101
vec4 & operator-=(const vec4 &rhs)
Definition: matrix.h:96
Definition: matrix.h:51
vec2 operator*(const vec2 &rhs) const
Definition: matrix.h:37
Definition: matrix.h:28
vec2 & operator+=(const vec2 &rhs)
Definition: matrix.h:43
vec2(float X, float Y)
Definition: matrix.h:34
float & operator[](unsigned int i)
Definition: matrix.h:47
vec4 y
Definition: matrix.h:106
vec2 & operator*=(const float s)
Definition: matrix.h:42
vec2 operator-(const vec2 &rhs) const
Definition: matrix.h:38
vec3 & operator*=(const vec3 &rhs)
Definition: matrix.h:68
vec3 operator*(const vec3 &rhs) const
Definition: matrix.h:62
float z
Definition: matrix.h:55
static mat4 scale(float x, float y, float z)
Definition: matrix.h:350
vec4 operator/(const float s) const
Definition: matrix.h:91
static mat4 rotateY(float rad)
Definition: matrix.h:320
vec4 & operator[](unsigned int i)
Definition: matrix.h:148
Definition: matrix.h:75
const float * value_ptr() const
Definition: matrix.h:150
vec4(vec3 V, float W)
Definition: matrix.h:83
vec3 & operator-=(const vec3 &rhs)
Definition: matrix.h:69
vec3(float S)
Definition: matrix.h:59
static mat4 orthographic(float left, float right, float bottom, float top, float near, float far)
Definition: matrix.h:172
static mat4 inverse(const mat4 &op)
Definition: matrix.h:185
GLfloat GLfloat GLfloat w
Definition: gl2ext.h:2701
static vec3 normalize(const vec3 &v)
Definition: matrix.h:154
static mat4 rotateZ(float rad)
Definition: matrix.h:328
float & operator[](unsigned int i)
Definition: matrix.h:98
GLfloat GLfloat f
Definition: gl2ext.h:2707
float y
Definition: matrix.h:31
float w
Definition: matrix.h:80
static mat4 rotateX(float rad)
Definition: matrix.h:312
vec4 operator-() const
Definition: matrix.h:86
float x
Definition: matrix.h:53
vec3 operator+(const vec3 &rhs) const
Definition: matrix.h:61
float y
Definition: matrix.h:54
vec4 & operator*=(const float s)
Definition: matrix.h:93
mat4()
Definition: matrix.h:108
vec4 & operator+=(const vec4 &rhs)
Definition: matrix.h:94
vec4 w
Definition: matrix.h:106
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
vec2 operator+(const vec2 &rhs) const
Definition: matrix.h:36
Definition: matrix.h:104
vec4 operator*(const vec4 &rhs) const
Definition: matrix.h:88
GLint left
Definition: gl2ext.h:2704
float z
Definition: matrix.h:79
static mat4 perspective(float fovy, float aspect, float near, float far)
Definition: matrix.h:159
vec3 operator-() const
Definition: matrix.h:60
vec4 z
Definition: matrix.h:106
float x
Definition: matrix.h:30
const GLfloat * m
Definition: gl2ext.h:2508
vec2(float S)
Definition: matrix.h:35
vec4(float S)
Definition: matrix.h:85
vec4 x
Definition: matrix.h:106
float x
Definition: matrix.h:77
float y
Definition: matrix.h:78
GLint y
Definition: gl2ext.h:179
static mat4 translate(float x, float y, float z)
Definition: matrix.h:336
vec3 operator/(const float s) const
Definition: matrix.h:65
mat4 operator*(const mat4 &rhs)
Definition: matrix.h:117
float * value_ptr()
Definition: matrix.h:151
GLint GLint bottom
Definition: gl2ext.h:2704
float & operator[](unsigned int i)
Definition: matrix.h:71
vec4()
Definition: matrix.h:82
mat4(float s)
Definition: matrix.h:109
vec3(float X, float Y, float Z)
Definition: matrix.h:58
vec4(float X, float Y, float Z, float W)
Definition: matrix.h:84
vec2 operator/(const float s) const
Definition: matrix.h:40