gKit2 light
Loading...
Searching...
No Matches
mat.cpp
1
2#include <cassert>
3#include <cstdio>
4#include <cmath>
5#include <algorithm>
6
7#include "mat.h"
8
9
10float radians( const float angle )
11{
12 return float(M_PI / 180) * angle;
13}
14
15float degrees( const float angle )
16{
17 return float(180 / M_PI) * angle;
18}
19
21 const float t00, const float t01, const float t02, const float t03,
22 const float t10, const float t11, const float t12, const float t13,
23 const float t20, const float t21, const float t22, const float t23,
24 const float t30, const float t31, const float t32, const float t33 )
25{
26 m[0][0]= t00; m[0][1]= t01; m[0][2]= t02; m[0][3]= t03;
27 m[1][0]= t10; m[1][1]= t11; m[1][2]= t12; m[1][3]= t13;
28 m[2][0]= t20; m[2][1]= t21; m[2][2]= t22; m[2][3]= t23;
29 m[3][0]= t30; m[3][1]= t31; m[3][2]= t32; m[3][3]= t33;
30}
31
32Transform& Transform::column_major( const float matrix[16] )
33{
34 for(int i= 0; i < 4; i++)
35 column(i, matrix[4*i], matrix[4*i+1], matrix[4*i+2], matrix[4*i+3]);
36 return *this;
37}
38
39Transform& Transform::row_major( const float matrix[16] )
40{
41 for(int i= 0; i < 4; i++)
42 row(i, matrix[4*i], matrix[4*i+1], matrix[4*i+2], matrix[4*i+3]);
43 return *this;
44}
45
46Transform& Transform::column( const unsigned id, const float t0, const float t1, const float t2, const float t3 )
47{
48 m[0][id]= t0;
49 m[1][id]= t1;
50 m[2][id]= t2;
51 m[3][id]= t3;
52 return *this;
53}
54
55vec4 Transform::column( const unsigned id ) const
56{
57 assert(id < 4);
58 return vec4(m[0][id], m[1][id], m[2][id], m[3][id]);
59}
60
61vec4 Transform::column( const unsigned id )
62{
63 assert(id < 4);
64 return vec4(m[0][id], m[1][id], m[2][id], m[3][id]);
65}
66
67
68Transform& Transform::row( const unsigned id, const float t0, const float t1, const float t2, const float t3 )
69{
70 m[id][0]= t0;
71 m[id][1]= t1;
72 m[id][2]= t2;
73 m[id][3]= t3;
74 return *this;
75}
76
77vec4 Transform::row( const unsigned id ) const
78{
79 assert(id < 4);
80 return vec4(m[id][0], m[id][1], m[id][2], m[id][3]);
81}
82
83vec4 Transform::row( const unsigned id )
84{
85 assert(id < 4);
86 return vec4(m[id][0], m[id][1], m[id][2], m[id][3]);
87}
88
89
90Transform::Transform( const Vector& x, const Vector& y, const Vector& z, const Vector& w )
91{
92 m[0][0] = x.x; m[0][1] = y.x; m[0][2] = z.x; m[0][3] = w.x;
93 m[1][0] = x.y; m[1][1] = y.y; m[1][2] = z.y; m[1][3] = w.y;
94 m[2][0] = x.z; m[2][1] = y.z; m[2][2] = z.z; m[2][3] = w.z;
95 m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 1;
96}
97
98Transform::Transform( const vec4& x, const vec4& y, const vec4& z, const vec4& w )
99{
100 m[0][0] = x.x; m[0][1] = y.x; m[0][2] = z.x; m[0][3] = w.x;
101 m[1][0] = x.y; m[1][1] = y.y; m[1][2] = z.y; m[1][3] = w.y;
102 m[2][0] = x.z; m[2][1] = y.z; m[2][2] = z.z; m[2][3] = w.z;
103 m[3][0] = x.w; m[3][1] = y.w; m[3][2] = z.w; m[3][3] = w.w;
104}
105
106Vector Transform::operator[] ( const unsigned c ) const
107{
108 assert(c < 4);
109 return Vector(m[0][c], m[1][c], m[2][c]);
110}
111
112
115{
116 float x= p.x;
117 float y= p.y;
118 float z= p.z;
119
120 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3]; // dot(vec4(m[0]), vec4(p, 1))
121 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3]; // dot(vec4(m[1]), vec4(p, 1))
122 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3]; // dot(vec4(m[2]), vec4(p, 1))
123 float wt= m[3][0] * x + m[3][1] * y + m[3][2] * z + m[3][3]; // dot(vec4(m[3]), vec4(p, 1))
124
125 assert(wt != 0);
126 float w= 1.f / wt;
127 if(wt == 1.f)
128 return Point(xt, yt, zt);
129 else
130 return Point(xt*w, yt*w, zt*w);
131}
132
135{
136 float x= v.x;
137 float y= v.y;
138 float z= v.z;
139
140 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z; // dot(vec4(m[0]), vec4(v, 0))
141 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z; // dot(vec4(m[1]), vec4(v, 0))
142 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z; // dot(vec4(m[2]), vec4(v, 0))
143 // dot(vec4(m[3]), vec4(v, 0)) == dot(vec4(0, 0, 0, 1), vec4(v, 0)) == 0 par definition
144
145 return Vector(xt, yt, zt);
146}
147
150{
151 float x= v.x;
152 float y= v.y;
153 float z= v.z;
154 float w= v.w;
155
156 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3] * w; // dot(vec4(m[0]), v)
157 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3] * w; // dot(vec4(m[1]), v)
158 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3] * w; // dot(vec4(m[2]), v)
159 float wt= m[3][0] * x + m[3][1] * y + m[3][2] * z + m[3][3] * w; // dot(vec4(m[3]), v)
160
161 return vec4(xt, yt, zt, wt);
162}
163
166{
167 return Transform(
168 m[0][0], m[1][0], m[2][0], m[3][0],
169 m[0][1], m[1][1], m[2][1], m[3][1],
170 m[0][2], m[1][2], m[2][2], m[3][2],
171 m[0][3], m[1][3], m[2][3], m[3][3]);
172}
173
174
176{
177 return compose_transform(*this, b);
178}
179
182{
183 return inverse().transpose();
184}
185
186
188{
189 return Transform();
190}
191
193{
194 return m.transpose();
195}
196
198{
199 return m.inverse();
200}
201
203{
204 return m.normal();
205}
206
207Transform Scale( const float x, const float y, const float z )
208{
209 return Transform(
210 x, 0, 0, 0,
211 0, y, 0, 0,
212 0, 0, z, 0,
213 0, 0, 0, 1);
214}
215
217{
218 return Transform(
219 1, 0, 0, v.x,
220 0, 1, 0, v.y,
221 0, 0, 1, v.z,
222 0, 0, 0, 1);
223}
224
225Transform Translation( const float x, const float y, const float z )
226{
227 return Translation( Vector(x, y, z) );
228}
229
230Transform RotationX( const float a )
231{
232 float sin_t= sinf(radians(a));
233 float cos_t= cosf(radians(a));
234
235 return Transform(
236 1, 0, 0, 0,
237 0, cos_t, -sin_t, 0,
238 0, sin_t, cos_t, 0,
239 0, 0, 0, 1 );
240}
241
242Transform RotationY( const float a )
243{
244 float sin_t= sinf(radians(a));
245 float cos_t= cosf(radians(a));
246
247 return Transform(
248 cos_t, 0, sin_t, 0,
249 0, 1, 0, 0,
250 -sin_t, 0, cos_t, 0,
251 0, 0, 0, 1 );
252}
253
254Transform RotationZ( const float a )
255{
256 float sin_t= sinf(radians(a));
257 float cos_t= cosf(radians(a));
258
259 return Transform(
260 cos_t, -sin_t, 0, 0,
261 sin_t, cos_t, 0, 0,
262 0, 0, 1, 0,
263 0, 0, 0, 1 );
264}
265
266Transform Rotation( const Vector& axis, const float angle )
267{
268 Vector a= normalize(axis);
269 float s= sinf(radians(angle));
270 float c= cosf(radians(angle));
271
272 return Transform(
273 a.x * a.x + (1 - a.x * a.x ) * c,
274 a.x * a.y * (1 - c ) - a.z * s,
275 a.x * a.z * (1 - c ) + a.y * s,
276 0,
277
278 a.x * a.y * (1 - c ) + a.z * s,
279 a.y * a.y + (1 - a.y * a.y ) * c,
280 a.y * a.z * (1 - c ) - a.x * s,
281 0,
282
283 a.x * a.z * (1 - c ) - a.y * s,
284 a.y * a.z * (1 - c ) + a.x * s,
285 a.z * a.z + (1 - a.z * a.z ) * c,
286 0,
287
288 0, 0, 0, 1);
289}
290
291
292Transform Rotation( const Vector& u, const Vector& v )
293{
294 Vector a= normalize(u);
295 Vector b= normalize(v);
296 Vector w= cross(a, b); // rotation autour de w, un vecteur perpendiculaire a u et v
297 float s= length(w); // sin theta
298 float c= dot(a, b); // cos theta
299
300 // si u et v sont colineaires, pas d'axe de rotation, renvoyer +1 ou -1
301 if(s < float(0.00001))
303 return Scale(std::copysign(c, 1));
304
305 // normalise l'axe de rotation
306 w= w / s;
307
308 // meme matrice de rotation qu'au dessus , cf Rotation(axis, angle), l'axe est le vecteur w, s et c sont le sinus et le cosinus de l'angle
309 return Transform(
310 w.x * w.x + (1 - w.x * w.x ) * c,
311 w.x * w.y * (1 - c ) - w.z * s,
312 w.x * w.z * (1 - c ) + w.y * s,
313 0,
314
315 w.x * w.y * (1 - c ) + w.z * s,
316 w.y * w.y + (1 - w.y * w.y ) * c,
317 w.y * w.z * (1 - c ) - w.x * s,
318 0,
319
320 w.x * w.z * (1 - c ) - w.y * s,
321 w.y * w.z * (1 - c ) + w.x * s,
322 w.z * w.z + (1 - w.z * w.z ) * c,
323 0,
324
325 0, 0, 0, 1);
326}
327
328
329Transform Perspective( const float fov, const float aspect, const float znear, const float zfar )
330{
331 // perspective, openGL version
332 float itan= 1 / tanf(radians(fov) * 0.5f);
333 float id= 1 / (znear - zfar);
334
335 return Transform(
336 itan/aspect, 0, 0, 0,
337 0, itan, 0, 0,
338 0, 0, (zfar+znear)*id, 2.f*zfar*znear*id,
339 0, 0, -1, 0);
340}
341
342
343Transform Ortho( const float left, const float right, const float bottom, const float top, const float znear, const float zfar )
344{
345 float tx= - (right + left) / (right - left);
346 float ty= - (top + bottom) / (top - bottom);
347 float tz= - (zfar + znear) / (zfar - znear);
348
349 return Transform(
350 2.f / (right - left), 0, 0, tx,
351 0, 2.f / (top - bottom), 0, ty,
352 0, 0, -2.f / (zfar - znear), tz,
353 0, 0, 0, 1);
354}
355
356
357Transform Viewport( const float width, const float height )
358{
359 float w= width / 2.f;
360 float h= height / 2.f;
361
362 return Transform(
363 w, 0, 0, w,
364 0, h, 0, h,
365 0, 0, .5f, .5f,
366 0, 0, 0, 1);
367}
368
369Transform Lookat( const Point& from, const Point& to, const Vector& up )
370{
371 Vector dir= normalize( Vector(from, to) );
372 Vector right= normalize( cross(dir, normalize(up)) );
373 Vector newUp= normalize( cross(right, dir) );
374
375 Transform m(
376 right.x, newUp.x, -dir.x, from.x,
377 right.y, newUp.y, -dir.y, from.y,
378 right.z, newUp.z, -dir.z, from.z,
379 0, 0, 0, 1);
380
381 return m.inverse();
382}
383
385{
386 Transform m;
387 for(int i = 0; i < 4; i++)
388 for(int j = 0; j < 4; j++)
389 m.m[i][j]= a.m[i][0] * b.m[0][j] + a.m[i][1] * b.m[1][j] + a.m[i][2] * b.m[2][j] + a.m[i][3] * b.m[3][j];
390
391 return m;
392}
393
395{
396 return compose_transform(a, b);
397}
398
400{
401 Transform minv= *this;
402
403 int indxc[4], indxr[4];
404 int ipiv[4] = { 0, 0, 0, 0 };
405
406 for (int i = 0; i < 4; i++) {
407 int irow = -1, icol = -1;
408 float big = 0.f;
409
410 // Choose pivot
411 for (int j = 0; j < 4; j++) {
412 if (ipiv[j] != 1) {
413 for (int k = 0; k < 4; k++) {
414 if (ipiv[k] == 0) {
415 if (fabsf(minv.m[j][k]) >= big) {
416 big = std::abs(minv.m[j][k]);
417 irow = j;
418 icol = k;
419 }
420 }
421 else if (ipiv[k] > 1)
422 printf("singular matrix in Transform::inverse()\n");
423 }
424 }
425 }
426
427 assert(irow >= 0 && irow < 4);
428 assert(icol >= 0 && icol < 4);
429
430 ++ipiv[icol];
431 // Swap rows _irow_ and _icol_ for pivot
432 if (irow != icol) {
433 for (int k = 0; k < 4; ++k)
434 std::swap(minv.m[irow][k], minv.m[icol][k]);
435 }
436
437 indxr[i] = irow;
438 indxc[i] = icol;
439 if (minv.m[icol][icol] == 0.)
440 printf("singular matrix in Transform::inverse()\n");
441
442 // Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
443 float pivinv = 1.f / minv.m[icol][icol];
444 minv.m[icol][icol] = 1.f;
445 for (int j = 0; j < 4; j++)
446 minv.m[icol][j] *= pivinv;
447
448 // Subtract this row from others to zero out their columns
449 for (int j = 0; j < 4; j++) {
450 if (j != icol) {
451 float save = minv.m[j][icol];
452 minv.m[j][icol] = 0;
453 for (int k = 0; k < 4; k++)
454 minv.m[j][k] -= minv.m[icol][k]*save;
455 }
456 }
457 }
458
459 // Swap columns to reflect permutation
460 for (int j = 3; j >= 0; j--) {
461 if (indxr[j] != indxc[j]) {
462 for (int k = 0; k < 4; k++)
463 std::swap(minv.m[k][indxr[j]], minv.m[k][indxc[j]]);
464 }
465 }
466
467 return minv;
468}
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition text.cpp:140
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition mat.cpp:197
Transform Transpose(const Transform &m)
renvoie la transposee de la matrice.
Definition mat.cpp:192
Transform Normal(const Transform &m)
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition mat.cpp:202
Transform Rotation(const Vector &axis, const float angle)
renvoie la matrice representation une rotation de angle degree autour de l'axe axis.
Definition mat.cpp:266
Transform Viewport(const float width, const float height)
renvoie la matrice representant une transformation viewport.
Definition mat.cpp:357
float degrees(const float angle)
conversion en degres.
Definition mat.cpp:15
Transform Identity()
construit la transformation identite.
Definition mat.cpp:187
Transform RotationX(const float a)
renvoie la matrice representation une rotation de angle degree autour de l'axe X.
Definition mat.cpp:230
Transform compose_transform(const Transform &a, const Transform &b)
renvoie la composition des transformations a et b, t= a * b.
Definition mat.cpp:384
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition mat.cpp:242
Transform Perspective(const float fov, const float aspect, const float znear, const float zfar)
renvoie la matrice representant une transformation projection perspective.
Definition mat.cpp:329
float dot(const Vector &u, const Vector &v)
renvoie le produit scalaire de 2 vecteurs.
Definition vec.cpp:181
Transform Ortho(const float left, const float right, const float bottom, const float top, const float znear, const float zfar)
renvoie la matrice representant une transformation orthographique, passage d'un cube []x[]x[] vers [-...
Definition mat.cpp:343
Transform operator*(const Transform &a, const Transform &b)
renvoie la composition des transformations a et b, t = a * b.
Definition mat.cpp:394
float radians(const float angle)
conversion en radians.
Definition mat.cpp:10
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Definition vec.cpp:167
Transform Translation(const Vector &v)
renvoie la matrice representant une translation par un vecteur.
Definition mat.cpp:216
Transform Lookat(const Point &from, const Point &to, const Vector &up)
renvoie la matrice representant le placement et l'orientation d'une camera pour observer le point to.
Definition mat.cpp:369
Transform RotationZ(const float a)
renvoie la matrice representation une rotation de angle degree autour de l'axe Z.
Definition mat.cpp:254
Vector cross(const Vector &u, const Vector &v)
renvoie le produit vectoriel de 2 vecteurs.
Definition vec.cpp:173
Transform Scale(const float x, const float y, const float z)
renvoie la matrice representant une mise a l'echelle / etirement.
Definition mat.cpp:207
representation d'un point 3d.
Definition vec.h:21
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition mat.h:21
Transform & column_major(const float matrix[16])
initialise la matrice avec 16 floats organises par colonne.
Definition mat.cpp:32
Transform & row_major(const float matrix[16])
initialise la matrice avec 16 floats organises par ligne.
Definition mat.cpp:39
Transform(const float t00=1, const float t01=0, const float t02=0, const float t03=0, const float t10=0, const float t11=1, const float t12=0, const float t13=0, const float t20=0, const float t21=0, const float t22=1, const float t23=0, const float t30=0, const float t31=0, const float t32=0, const float t33=1)
constructeur.
Definition mat.cpp:20
Vector operator[](const unsigned c) const
renvoie le Vector colonne c de la matrice
Definition mat.cpp:106
Transform & column(const unsigned id, const float t0, const float t1, const float t2, const float t3)
initialise une colonne de la matrice a partir de 4 floats.
Definition mat.cpp:46
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m.
Definition mat.cpp:181
Transform inverse() const
renvoie l'inverse de la matrice.
Definition mat.cpp:399
Transform & row(const unsigned id, const float t0, const float t1, const float t2, const float t3)
initialise une ligne de la matrice.
Definition mat.cpp:68
Point operator()(const Point &p) const
renvoie le point transforme.
Definition mat.cpp:114
Transform transpose() const
renvoie la transposee de la matrice.
Definition mat.cpp:165
representation d'un vecteur 3d.
Definition vec.h:67
vecteur generique 4d, ou 3d homogene, utilitaire.
Definition vec.h:192