gKit2 light

- Main Page
- Related Pages
- Modules
- Classes
- Files

- File List
- File Members

mat.cpp
1
2 #include <cassert>
3 #include <cstdio>
4 #include <cmath>
5 #include <algorithm>
6
7 //#define _USE_MATH_DEFINES
8 #include "mat.h"
9
10
11 float radians( const float deg )
12 {
13 const float pi = 3.1415926535f;
14 return (pi / 180.f) * deg;
15 }
16
17 float degrees( const float rad )
18 {
19 const float pi = 3.1415926535f;
20 return (180.f / pi) * rad;
21 }
22
23 Transform::Transform (
24 const float t00, const float t01, const float t02, const float t03,
25 const float t10, const float t11, const float t12, const float t13,
26 const float t20, const float t21, const float t22, const float t23,
27 const float t30, const float t31, const float t32, const float t33 )
28 {
29 m[0][0]= t00; m[0][1]= t01; m[0][2]= t02; m[0][3]= t03;
30 m[1][0]= t10; m[1][1]= t11; m[1][2]= t12; m[1][3]= t13;
31 m[2][0]= t20; m[2][1]= t21; m[2][2]= t22; m[2][3]= t23;
32 m[3][0]= t30; m[3][1]= t31; m[3][2]= t32; m[3][3]= t33;
33 }
34
36 Point Transform::operator() ( const Point& p ) const
37 {
38 float x= p.x;
39 float y= p.y;
40 float z= p.z;
41
42 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3]; // dot(vec4(m[0]), vec4(p, 1))
43 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3]; // dot(vec4(m[1]), vec4(p, 1))
44 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3]; // dot(vec4(m[2]), vec4(p, 1))
45 float wt= m[3][0] * x + m[3][1] * y + m[3][2] * z + m[3][3]; // dot(vec4(m[3]), vec4(p, 1))
46
47 assert(wt != 0);
48 float w= 1.f / wt;
49 if(wt == 1.f)
50 return Point(xt, yt, zt);
51 else
52 return Point(xt*w, yt*w, zt*w);
53 }
54
56 Vector Transform::operator() ( const Vector& v ) const
57 {
58 float x= v.x;
59 float y= v.y;
60 float z= v.z;
61
62 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z; // dot(vec4(m[0]), vec4(v, 0))
63 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z; // dot(vec4(m[1]), vec4(v, 0))
64 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z; // dot(vec4(m[2]), vec4(v, 0))
65 // dot(vec4(m[3]), vec4(v, 0)) == dot(vec4(0, 0, 0, 1), vec4(v, 0)) == 0 par definition
66
67 return Vector(xt, yt, zt);
68 }
69
71 vec4 Transform::operator() ( const vec4& v ) const
72 {
73 float x= v.x;
74 float y= v.y;
75 float z= v.z;
76 float w= v.w;
77
78 float xt= m[0][0] * x + m[0][1] * y + m[0][2] * z + m[0][3] * w; // dot(vec4(m[0]), v)
79 float yt= m[1][0] * x + m[1][1] * y + m[1][2] * z + m[1][3] * w; // dot(vec4(m[1]), v)
80 float zt= m[2][0] * x + m[2][1] * y + m[2][2] * z + m[2][3] * w; // dot(vec4(m[2]), v)
81 float wt= m[3][0] * x + m[3][1] * y + m[3][2] * z + m[3][3] * w; // dot(vec4(m[3]), v)
82
83 return vec4(xt, yt, zt, wt);
84 }
85
87 Transform Transform::transpose( ) const
88 {
89 return Transform(
90 m[0][0], m[1][0], m[2][0], m[3][0],
91 m[0][1], m[1][1], m[2][1], m[3][1],
92 m[0][2], m[1][2], m[2][2], m[3][2],
93 m[0][3], m[1][3], m[2][3], m[3][3]);
94 }
95
97 Transform Transform::normal( ) const
98 {
99 return inverse().transpose();
100 }
101
102
103 Transform Identity( )
104 {
105 return Transform();
106 }
107
108 Transform Transpose( const Transform& m )
109 {
110 return m.transpose();
111 }
112
113 Transform Inverse( const Transform& m )
114 {
115 return m.inverse();
116 }
117
118 Transform Normal( const Transform& m )
119 {
120 return m.normal();
121 }
122
123 Transform Scale( const float x, const float y, const float z )
124 {
125 return Transform(
126 x, 0, 0, 0,
127 0, y, 0, 0,
128 0, 0, z, 0,
129 0, 0, 0, 1);
130 }
131
132 Transform Translation( const Vector& v )
133 {
134 return Transform(
135 1, 0, 0, v.x,
136 0, 1, 0, v.y,
137 0, 0, 1, v.z,
138 0, 0, 0, 1);
139 }
140
141 Transform Translation( const float x, const float y, const float z )
142 {
143 return Translation( Vector(x, y, z) );
144 }
145
146 Transform RotationX( const float a )
147 {
148 float sin_t= sinf(radians(a));
149 float cos_t= cosf(radians(a));
150
151 return Transform(
152 1, 0, 0, 0,
153 0, cos_t, -sin_t, 0,
154 0, sin_t, cos_t, 0,
155 0, 0, 0, 1 );
156 }
157
158 Transform RotationY( const float a )
159 {
160 float sin_t= sinf(radians(a));
161 float cos_t= cosf(radians(a));
162
163 return Transform(
164 cos_t, 0, sin_t, 0,
165 0, 1, 0, 0,
166 -sin_t, 0, cos_t, 0,
167 0, 0, 0, 1 );
168 }
169
170 Transform RotationZ( const float a )
171 {
172 float sin_t= sinf(radians(a));
173 float cos_t= cosf(radians(a));
174
175 return Transform(
176 cos_t, -sin_t, 0, 0,
177 sin_t, cos_t, 0, 0,
178 0, 0, 1, 0,
179 0, 0, 0, 1 );
180 }
181
182 Transform Rotation( const Vector& axis, const float angle )
183 {
184 Vector a= normalize(axis);
185 float s= sinf(radians(angle));
186 float c= cosf(radians(angle));
187
188 return Transform(
189 a.x * a.x + (1 - a.x * a.x ) * c,
190 a.x * a.y * (1 - c ) - a.z * s,
191 a.x * a.z * (1 - c ) + a.y * s,
192 0,
193
194 a.x * a.y * (1 - c ) + a.z * s,
195 a.y * a.y + (1 - a.y * a.y ) * c,
196 a.y * a.z * (1 - c ) - a.x * s,
197 0,
198
199 a.x * a.z * (1 - c ) - a.y * s,
200 a.y * a.z * (1 - c ) + a.x * s,
201 a.z * a.z + (1 - a.z * a.z ) * c,
202 0,
203
204 0, 0, 0, 1);
205 }
206
207
208 Transform Perspective( const float fov, const float aspect, const float znear, const float zfar )
209 {
210 // perspective, openGL version
211 float itan= 1 / tanf(radians(fov) * 0.5f);
212 float id= 1 / (znear - zfar);
213
214 return Transform(
215 itan/aspect, 0, 0, 0,
216 0, itan, 0, 0,
217 0, 0, (zfar+znear)*id, 2.f*zfar*znear*id,
218 0, 0, -1, 0);
219 }
220
221 Transform Viewport( const float width, const float height )
222 {
223 float w= width / 2.f;
224 float h= height / 2.f;
225
226 return Transform(
227 w, 0, 0, w,
228 0, h, 0, h,
229 0, 0, .5f, .5f,
230 0, 0, 0, 1);
231 }
232
233 Transform Lookat( const Point& from, const Point& to, const Vector& up )
234 {
235 Vector dir= normalize( Vector(from, to) );
236 Vector right= normalize( cross(dir, normalize(up)) );
237 Vector newUp= normalize( cross(right, dir) );
238
239 Transform m(
240 right.x, newUp.x, -dir.x, from.x,
241 right.y, newUp.y, -dir.y, from.y,
242 right.z, newUp.z, -dir.z, from.z,
243 0, 0, 0, 1);
244
245 return m.inverse();
246 }
247
248 Transform compose_transform( const Transform& a, const Transform& b )
249 {
250 Transform m;
251 for(int i = 0; i < 4; i++)
252 for(int j = 0; j < 4; j++)
253 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];
254
255 return m;
256 }
257
258 Transform operator* ( const Transform& a, const Transform& b )
259 {
260 return compose_transform(a, b);
261 }
262
263 Transform Transform::inverse( ) const
264 {
265 Transform minv= *this;
266
267 int indxc[4], indxr[4];
268 int ipiv[4] = { 0, 0, 0, 0 };
269
270 for (int i = 0; i < 4; i++) {
271 int irow = -1, icol = -1;
272 float big = 0.f;
273
274 // Choose pivot
275 for (int j = 0; j < 4; j++) {
276 if (ipiv[j] != 1) {
277 for (int k = 0; k < 4; k++) {
278 if (ipiv[k] == 0) {
279 if (fabsf(minv.m[j][k]) >= big) {
280 big = std::abs(minv.m[j][k]);
281 irow = j;
282 icol = k;
283 }
284 }
285 else if (ipiv[k] > 1)
286 printf("singular matrix in make_inverse()\n");
287 }
288 }
289 }
290
291 assert(irow >= 0 && irow < 4);
292 assert(icol >= 0 && icol < 4);
293
294 ++ipiv[icol];
295 // Swap rows _irow_ and _icol_ for pivot
296 if (irow != icol) {
297 for (int k = 0; k < 4; ++k)
298 std::swap(minv.m[irow][k], minv.m[icol][k]);
299 }
300
301 indxr[i] = irow;
302 indxc[i] = icol;
303 if (minv.m[icol][icol] == 0.)
304 printf("singular matrix in make_inverse()\n");
305
306 // Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
307 float pivinv = 1.f / minv.m[icol][icol];
308 minv.m[icol][icol] = 1.f;
309 for (int j = 0; j < 4; j++)
310 minv.m[icol][j] *= pivinv;
311
312 // Subtract this row from others to zero out their columns
313 for (int j = 0; j < 4; j++) {
314 if (j != icol) {
315 float save = minv.m[j][icol];
316 minv.m[j][icol] = 0;
317 for (int k = 0; k < 4; k++)
318 minv.m[j][k] -= minv.m[icol][k]*save;
319 }
320 }
321 }
322
323 // Swap columns to reflect permutation
324 for (int j = 3; j >= 0; j--) {
325 if (indxr[j] != indxc[j]) {
326 for (int k = 0; k < 4; k++)
327 std::swap(minv.m[k][indxr[j]], minv.m[k][indxc[j]]);
328 }
329 }
330
331 return minv;
332 }
degrees
float degrees(const float rad)
conversion en degres.
Definition: mat.cpp:17
Transform::Transform
Transform(const float t00=1.f, const float t01=0.f, const float t02=0.f, const float t03=0.f, const float t10=0.f, const float t11=1.f, const float t12=0.f, const float t13=0.f, const float t20=0.f, const float t21=0.f, const float t22=1.f, const float t23=0.f, const float t30=0.f, const float t31=0.f, const float t32=0.f, const float t33=1.f)
constructeur.
Definition: mat.cpp:23
normalize
Vector normalize(const Vector &v)
renvoie un vecteur unitaire / longueur == 1.
Definition: vec.cpp:79
Transform::inverse
Transform inverse() const
renvoie l'inverse de la matrice.
Definition: mat.cpp:263
Transpose
Transform Transpose(const Transform &m)
renvoie la transposee de la matrice.
Definition: mat.cpp:108
Transform::normal
Transform normal() const
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m...
Definition: mat.cpp:97
operator*
Transform operator*(const Transform &a, const Transform &b)
renvoie la composition des transformations a et b, t = a * b.
Definition: mat.cpp:258
Transform::operator()
Point operator()(const Point &p) const
renvoie le point transforme.
Definition: mat.cpp:36
Identity
Transform Identity()
construit la transformation identite.
Definition: mat.cpp:103
Viewport
Transform Viewport(const float width, const float height)
renvoie la matrice representant une transformation viewport.
Definition: mat.cpp:221
vec4
vecteur generique 4d, ou 3d homogene, utilitaire.
Definition: vec.h:121
radians
float radians(const float deg)
conversion en radians.
Definition: mat.cpp:11
Normal
Transform Normal(const Transform &m)
renvoie la transformation a appliquer aux normales d'un objet transforme par la matrice m...
Definition: mat.cpp:118
Inverse
Transform Inverse(const Transform &m)
renvoie l'inverse de la matrice.
Definition: mat.cpp:113
Vector
representation d'un vecteur 3d.
Definition: vec.h:42
mat.h
Transform::transpose
Transform transpose() const
renvoie la transposee de la matrice.
Definition: mat.cpp:87
RotationX
Transform RotationX(const float a)
renvoie la matrice representation une rotation de angle degree autour de l'axe X. ...
Definition: mat.cpp:146
Lookat
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:233
Rotation
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:182
compose_transform
Transform compose_transform(const Transform &a, const Transform &b)
renvoie la composition des transformations a et b, t= a * b.
Definition: mat.cpp:248
Scale
Transform Scale(const float x, const float y, const float z)
renvoie la matrice representant une mise a l'echelle / etirement.
Definition: mat.cpp:123
Translation
Transform Translation(const Vector &v)
renvoie la matrice representant une translation par un vecteur.
Definition: mat.cpp:132
RotationZ
Transform RotationZ(const float a)
renvoie la matrice representation une rotation de angle degree autour de l'axe Z. ...
Definition: mat.cpp:170
printf
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
Perspective
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:208
Transform
representation d'une transformation, une matrice 4x4, organisee par ligne / row major.
Definition: mat.h:20
Point
representation d'un point 3d.
Definition: vec.h:19
cross
Vector cross(const Vector &u, const Vector &v)
renvoie le produit vectoriel de 2 vecteurs.
Definition: vec.cpp:85
RotationY
Transform RotationY(const float a)
renvoie la matrice representation une rotation de a degree autour de l'axe Y.
Definition: mat.cpp:158