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