~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to clutter/cogl/common/cogl-matrix.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Cogl
3
 
 *
4
 
 * An object oriented GL/GLES Abstraction/Utility Layer
5
 
 *
6
 
 * Copyright (C) 2008,2009 Intel Corporation.
7
 
 *
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.
12
 
 *
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.
17
 
 *
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.
22
 
 *
23
 
 * Authors:
24
 
 *   Robert Bragg <robert@linux.intel.com>
25
 
 */
26
 
 
27
 
#include <cogl.h>
28
 
#include <cogl-matrix.h>
29
 
 
30
 
#include <glib.h>
31
 
#include <math.h>
32
 
#include <string.h>
33
 
 
34
 
void
35
 
cogl_matrix_init_identity (CoglMatrix *matrix)
36
 
{
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;
41
 
}
42
 
 
43
 
void
44
 
cogl_matrix_multiply (CoglMatrix *result,
45
 
                      const CoglMatrix *a,
46
 
                      const CoglMatrix *b)
47
 
{
48
 
  CoglMatrix r;
49
 
 
50
 
  /* row 0 */
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;
55
 
 
56
 
  /* row 1 */
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;
61
 
 
62
 
  /* row 2 */
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;
67
 
 
68
 
  /* row 3 */
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;
73
 
 
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...
77
 
   */
78
 
 
79
 
  *result = r;
80
 
}
81
 
 
82
 
void
83
 
cogl_matrix_rotate (CoglMatrix *matrix,
84
 
                    float angle,
85
 
                    float x,
86
 
                    float y,
87
 
                    float z)
88
 
{
89
 
  CoglMatrix rotation;
90
 
  CoglMatrix result;
91
 
  float c, s;
92
 
 
93
 
  angle *= G_PI / 180.0f;
94
 
  c = cosf (angle);
95
 
  s = sinf (angle);
96
 
 
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;
100
 
  rotation.wx = 0.0f;
101
 
 
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;
105
 
  rotation.wy = 0.0f;
106
 
 
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;
110
 
  rotation.wz = 0.0f;
111
 
 
112
 
  rotation.xw = 0.0f;
113
 
  rotation.yw = 0.0f;
114
 
  rotation.zw = 0.0f;
115
 
  rotation.ww = 1.0f;
116
 
 
117
 
  cogl_matrix_multiply (&result, matrix, &rotation);
118
 
  *matrix = result;
119
 
}
120
 
 
121
 
void
122
 
cogl_matrix_translate (CoglMatrix *matrix,
123
 
                       float x,
124
 
                       float y,
125
 
                       float z)
126
 
{
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;
131
 
}
132
 
 
133
 
void
134
 
cogl_matrix_scale (CoglMatrix *matrix,
135
 
                   float sx,
136
 
                   float sy,
137
 
                   float sz)
138
 
{
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;
143
 
}
144
 
 
145
 
#if 0
146
 
gboolean
147
 
cogl_matrix_invert (CoglMatrix *matrix)
148
 
{
149
 
  /* TODO */
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.
153
 
   */
154
 
}
155
 
#endif
156
 
 
157
 
void
158
 
cogl_matrix_frustum (CoglMatrix *matrix,
159
 
                     float       left,
160
 
                     float       right,
161
 
                     float       bottom,
162
 
                     float       top,
163
 
                     float       z_near,
164
 
                     float       z_far)
165
 
{
166
 
  float x, y, a, b, c, d;
167
 
  CoglMatrix frustum;
168
 
 
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);
175
 
 
176
 
  frustum.xx = x;
177
 
  frustum.yx = 0.0f;
178
 
  frustum.zx = 0.0f;
179
 
  frustum.wx = 0.0f;
180
 
 
181
 
  frustum.xy = 0.0f;
182
 
  frustum.yy = y;
183
 
  frustum.zy = 0.0f;
184
 
  frustum.wy = 0.0f;
185
 
 
186
 
  frustum.xz = a;
187
 
  frustum.yz = b;
188
 
  frustum.zz = c;
189
 
  frustum.wz = -1.0f;
190
 
 
191
 
  frustum.xw = 0.0f;
192
 
  frustum.yw = 0.0f;
193
 
  frustum.zw = d;
194
 
  frustum.ww = 0.0f;
195
 
 
196
 
  cogl_matrix_multiply (matrix, matrix, &frustum);
197
 
}
198
 
 
199
 
void
200
 
cogl_matrix_perspective (CoglMatrix *matrix,
201
 
                         float       fov_y,
202
 
                         float       aspect,
203
 
                         float       z_near,
204
 
                         float       z_far)
205
 
{
206
 
  float ymax = z_near * tan (fov_y * G_PI / 360.0);
207
 
 
208
 
  cogl_matrix_frustum (matrix,
209
 
                       -ymax * aspect,  /* left */
210
 
                       ymax * aspect,   /* right */
211
 
                       -ymax,           /* bottom */
212
 
                       ymax,            /* top */
213
 
                       z_near,
214
 
                       z_far);
215
 
}
216
 
 
217
 
void
218
 
cogl_matrix_ortho (CoglMatrix *matrix,
219
 
                   float left,
220
 
                   float right,
221
 
                   float bottom,
222
 
                   float top,
223
 
                   float near_val,
224
 
                   float far_val)
225
 
{
226
 
  CoglMatrix ortho;
227
 
 
228
 
  /* column 0 */
229
 
  ortho.xx = 2.0 / (right - left);
230
 
  ortho.yx = 0.0;
231
 
  ortho.zx = 0.0;
232
 
  ortho.wx = 0.0;
233
 
 
234
 
  /* column 1 */
235
 
  ortho.xy = 0.0;
236
 
  ortho.yy = 2.0 / (top - bottom);
237
 
  ortho.zy = 0.0;
238
 
  ortho.wy = 0.0;
239
 
 
240
 
  /* column 2 */
241
 
  ortho.xz = 0.0;
242
 
  ortho.yz = 0.0;
243
 
  ortho.zz = -2.0 / (far_val - near_val);
244
 
  ortho.wz = 0.0;
245
 
 
246
 
  /* column 3 */
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);
250
 
  ortho.ww = 1.0;
251
 
 
252
 
  cogl_matrix_multiply (matrix, matrix, &ortho);
253
 
}
254
 
 
255
 
void
256
 
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
257
 
{
258
 
  memcpy (matrix, array, sizeof (float) * 16);
259
 
}
260
 
 
261
 
const float *
262
 
cogl_matrix_get_array (const CoglMatrix *matrix)
263
 
{
264
 
  return (float *)matrix;
265
 
}
266
 
 
267
 
void
268
 
cogl_matrix_transform_point (const CoglMatrix *matrix,
269
 
                             float *x,
270
 
                             float *y,
271
 
                             float *z,
272
 
                             float *w)
273
 
{
274
 
  float _x = *x, _y = *y, _z = *z, _w = *w;
275
 
 
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;
280
 
}
281
 
 
282