4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 2008,2009 Intel Corporation.
8
* This library is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2 of the License, or (at your option) any later version.
13
* This library is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with this library; if not, write to the
20
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21
* Boston, MA 02111-1307, USA.
24
* Robert Bragg <robert@linux.intel.com>
28
#include <cogl-matrix.h>
35
cogl_matrix_init_identity (CoglMatrix *matrix)
37
matrix->xx = 1; matrix->xy = 0; matrix->xz = 0; matrix->xw = 0;
38
matrix->yx = 0; matrix->yy = 1; matrix->yz = 0; matrix->yw = 0;
39
matrix->zx = 0; matrix->zy = 0; matrix->zz = 1; matrix->zw = 0;
40
matrix->wx = 0; matrix->wy = 0; matrix->wz = 0; matrix->ww = 1;
44
cogl_matrix_multiply (CoglMatrix *result,
51
r.xx = a->xx * b->xx + a->xy * b->yx + a->xz * b->zx + a->xw * b->wx;
52
r.xy = a->xx * b->xy + a->xy * b->yy + a->xz * b->zy + a->xw * b->wy;
53
r.xz = a->xx * b->xz + a->xy * b->yz + a->xz * b->zz + a->xw * b->wz;
54
r.xw = a->xx * b->xw + a->xy * b->yw + a->xz * b->zw + a->xw * b->ww;
57
r.yx = a->yx * b->xx + a->yy * b->yx + a->yz * b->zx + a->yw * b->wx;
58
r.yy = a->yx * b->xy + a->yy * b->yy + a->yz * b->zy + a->yw * b->wy;
59
r.yz = a->yx * b->xz + a->yy * b->yz + a->yz * b->zz + a->yw * b->wz;
60
r.yw = a->yx * b->xw + a->yy * b->yw + a->yz * b->zw + a->yw * b->ww;
63
r.zx = a->zx * b->xx + a->zy * b->yx + a->zz * b->zx + a->zw * b->wx;
64
r.zy = a->zx * b->xy + a->zy * b->yy + a->zz * b->zy + a->zw * b->wy;
65
r.zz = a->zx * b->xz + a->zy * b->yz + a->zz * b->zz + a->zw * b->wz;
66
r.zw = a->zx * b->xw + a->zy * b->yw + a->zz * b->zw + a->zw * b->ww;
69
r.wx = a->wx * b->xx + a->wy * b->yx + a->wz * b->zx + a->ww * b->wx;
70
r.wy = a->wx * b->xy + a->wy * b->yy + a->wz * b->zy + a->ww * b->wy;
71
r.wz = a->wx * b->xz + a->wy * b->yz + a->wz * b->zz + a->ww * b->wz;
72
r.ww = a->wx * b->xw + a->wy * b->yw + a->wz * b->zw + a->ww * b->ww;
74
/* The idea was that having this unrolled; it might be easier for the
75
* compiler to vectorize, but that's probably not true. Mesa does it
76
* using a single for (i=0; i<4; i++) approach, may that's better...
83
cogl_matrix_rotate (CoglMatrix *matrix,
93
angle *= G_PI / 180.0f;
97
rotation.xx = x * x * (1.0f - c) + c;
98
rotation.yx = y * x * (1.0f - c) + z * s;
99
rotation.zx = x * z * (1.0f - c) - y * s;
102
rotation.xy = x * y * (1.0f - c) - z * s;
103
rotation.yy = y * y * (1.0f - c) + c;
104
rotation.zy = y * z * (1.0f - c) + x * s;
107
rotation.xz = x * z * (1.0f - c) + y * s;
108
rotation.yz = y * z * (1.0f - c) - x * s;
109
rotation.zz = z * z * (1.0f - c) + c;
117
cogl_matrix_multiply (&result, matrix, &rotation);
122
cogl_matrix_translate (CoglMatrix *matrix,
127
matrix->xw = matrix->xx * x + matrix->xy * y + matrix->xz * z + matrix->xw;
128
matrix->yw = matrix->yx * x + matrix->yy * y + matrix->yz * z + matrix->yw;
129
matrix->zw = matrix->zx * x + matrix->zy * y + matrix->zz * z + matrix->zw;
130
matrix->ww = matrix->wx * x + matrix->wy * y + matrix->wz * z + matrix->ww;
134
cogl_matrix_scale (CoglMatrix *matrix,
139
matrix->xx *= sx; matrix->xy *= sy; matrix->xz *= sz;
140
matrix->yx *= sx; matrix->yy *= sy; matrix->yz *= sz;
141
matrix->zx *= sx; matrix->zy *= sy; matrix->zz *= sz;
142
matrix->wx *= sx; matrix->wy *= sy; matrix->wz *= sz;
147
cogl_matrix_invert (CoglMatrix *matrix)
150
/* Note: It might be nice to also use the flag based tricks that mesa does
151
* to alow it to track the type of transformations a matrix represents
152
* so it can use various assumptions to optimise the inversion.
158
cogl_matrix_frustum (CoglMatrix *matrix,
166
float x, y, a, b, c, d;
169
x = (2.0f * z_near) / (right - left);
170
y = (2.0f * z_near) / (top - bottom);
171
a = (right + left) / (right - left);
172
b = (top + bottom) / (top - bottom);
173
c = -(z_far + z_near) / ( z_far - z_near);
174
d = -(2.0f * z_far* z_near) / (z_far - z_near);
196
cogl_matrix_multiply (matrix, matrix, &frustum);
200
cogl_matrix_perspective (CoglMatrix *matrix,
206
float ymax = z_near * tan (fov_y * G_PI / 360.0);
208
cogl_matrix_frustum (matrix,
209
-ymax * aspect, /* left */
210
ymax * aspect, /* right */
218
cogl_matrix_ortho (CoglMatrix *matrix,
229
ortho.xx = 2.0 / (right - left);
236
ortho.yy = 2.0 / (top - bottom);
243
ortho.zz = -2.0 / (far_val - near_val);
247
ortho.xw = -(right + left) / (right - left);
248
ortho.yw = -(top + bottom) / (top - bottom);
249
ortho.zw = -(far_val + near_val) / (far_val - near_val);
252
cogl_matrix_multiply (matrix, matrix, &ortho);
256
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
258
memcpy (matrix, array, sizeof (float) * 16);
262
cogl_matrix_get_array (const CoglMatrix *matrix)
264
return (float *)matrix;
268
cogl_matrix_transform_point (const CoglMatrix *matrix,
274
float _x = *x, _y = *y, _z = *z, _w = *w;
276
*x = matrix->xx * _x + matrix->xy * _y + matrix->xz * _z + matrix->xw * _w;
277
*y = matrix->yx * _x + matrix->yy * _y + matrix->yz * _z + matrix->yw * _w;
278
*z = matrix->zx * _x + matrix->zy * _y + matrix->zz * _z + matrix->zw * _w;
279
*w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w;