OpenClonk
StdMeshMath.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 
17 #include "C4Include.h"
18 #include "lib/StdMeshMath.h"
19 
21 {
22  StdMeshVector v;
23  v.x = 0.0f;
24  v.y = 0.0f;
25  v.z = 0.0f;
26  return v;
27 }
28 
30 {
31  StdMeshVector v;
32  v.x = 1.0f;
33  v.y = 1.0f;
34  v.z = 1.0f;
35  return v;
36 }
37 
38 StdMeshVector StdMeshVector::Translate(float dx, float dy, float dz)
39 {
40  StdMeshVector v;
41  v.x = dx;
42  v.y = dy;
43  v.z = dz;
44  return v;
45 }
46 
48 {
49  StdMeshVector v;
50  v.x = lhs.y*rhs.z - lhs.z*rhs.y;
51  v.y = lhs.z*rhs.x - lhs.x*rhs.z;
52  v.z = lhs.x*rhs.y - lhs.y*rhs.x;
53  return v;
54 }
55 
57 {
58  const float len = sqrt(x*x + y*y + z*z);
59  x /= len; y /= len; z /= len;
60 }
61 
63 {
65  q.w = 0.0f;
66  q.x = 0.0f;
67  q.y = 0.0f;
68  q.z = 0.0f;
69  return q;
70 }
71 
73 {
75  const float theta2 = theta/2.0f;
76  const float s = sin(theta2);
77  q.w = cos(theta2);
78  q.x = s*axis.x;
79  q.y = s*axis.y;
80  q.z = s*axis.z;
81  return q;
82 }
83 
85 {
86  float length = sqrt(LenSqr());
87  w /= length;
88  x /= length;
89  y /= length;
90  z /= length;
91 }
92 
94 {
96  float c = lhs.w * rhs.w + lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
97  if (c < 0.0f)
98  q = lhs + w * (-rhs - lhs);
99  else
100  q = lhs + w * ( rhs - lhs);
101  q.Normalize();
102  return q;
103 }
104 
106 {
111  return t;
112 }
113 
115 {
118  t.rotate.w = 1.0f;
119  t.rotate.x = t.rotate.y = t.rotate.z = 0.0f;
121  return t;
122 }
123 
125 {
127  t.scale = 1.0f/transform.scale;
128  t.rotate.w = transform.rotate.w;
129  t.rotate.x = -transform.rotate.x;
130  t.rotate.y = -transform.rotate.y;
131  t.rotate.z = -transform.rotate.z;
132  t.translate = t.rotate * (t.scale * -transform.translate);
133  return t;
134 }
135 
137 {
140  t.rotate.w = 1.0f;
141  t.rotate.x = t.rotate.y = t.rotate.z = 0.0f;
142  t.translate = StdMeshVector::Translate(dx, dy, dz);
143  return t;
144 }
145 
147 {
149  t.scale = StdMeshVector::Translate(sx, sy, sz);
150  t.rotate.w = 1.0f;
151  t.rotate.x = t.rotate.y = t.rotate.z = 0.0f;
153  return t;
154 }
155 
156 StdMeshTransformation StdMeshTransformation::Rotate(float angle, float rx, float ry, float rz)
157 {
162  return t;
163 }
164 
166 {
168  t.translate = (1 - w) * lhs.translate + w * rhs.translate;
169  t.rotate = StdMeshQuaternion::Nlerp(lhs.rotate, rhs.rotate, w);
170  t.scale = (1 - w) * lhs.scale + w * rhs.scale;
171  return t;
172 }
173 
175 {
176  StdMeshMatrix m;
177  m.a[0][0] = 0.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
178  m.a[1][0] = 0.0f; m.a[1][1] = 0.0f; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
179  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 0.0f; m.a[2][3] = 0.0f;
180  return m;
181 }
182 
184 {
185  StdMeshMatrix m;
186  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
187  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
188  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = 0.0f;
189  return m;
190 }
191 
193 {
194  StdMeshMatrix m;
195 
196  const float det = mat.Determinant();
197  assert(det != 0.0f);
198 
199  m.a[0][0] = (mat.a[1][1]*mat.a[2][2] - mat.a[1][2]*mat.a[2][1]) / det;
200  m.a[1][0] = (mat.a[1][2]*mat.a[2][0] - mat.a[1][0]*mat.a[2][2]) / det;
201  m.a[2][0] = (mat.a[1][0]*mat.a[2][1] - mat.a[1][1]*mat.a[2][0]) / det;
202 
203  m.a[0][1] = (mat.a[0][2]*mat.a[2][1] - mat.a[0][1]*mat.a[2][2]) / det;
204  m.a[1][1] = (mat.a[0][0]*mat.a[2][2] - mat.a[0][2]*mat.a[2][0]) / det;
205  m.a[2][1] = (mat.a[0][1]*mat.a[2][0] - mat.a[0][0]*mat.a[2][1]) / det;
206 
207  m.a[0][2] = (mat.a[0][1]*mat.a[1][2] - mat.a[0][2]*mat.a[1][1]) / det;
208  m.a[1][2] = (mat.a[0][2]*mat.a[1][0] - mat.a[0][0]*mat.a[1][2]) / det;
209  m.a[2][2] = (mat.a[0][0]*mat.a[1][1] - mat.a[0][1]*mat.a[1][0]) / det;
210 
211  m.a[0][3] = (mat.a[0][1]*mat.a[1][3]*mat.a[2][2]
212  + mat.a[0][2]*mat.a[1][1]*mat.a[2][3]
213  + mat.a[0][3]*mat.a[1][2]*mat.a[2][1]
214  - mat.a[0][1]*mat.a[1][2]*mat.a[2][3]
215  - mat.a[0][2]*mat.a[1][3]*mat.a[2][1]
216  - mat.a[0][3]*mat.a[1][1]*mat.a[2][2]) / det;
217 
218  m.a[1][3] = (mat.a[0][0]*mat.a[1][2]*mat.a[2][3]
219  + mat.a[0][2]*mat.a[1][3]*mat.a[2][0]
220  + mat.a[0][3]*mat.a[1][0]*mat.a[2][2]
221  - mat.a[0][0]*mat.a[1][3]*mat.a[2][2]
222  - mat.a[0][2]*mat.a[1][0]*mat.a[2][3]
223  - mat.a[0][3]*mat.a[1][2]*mat.a[2][0]) / det;
224 
225  m.a[2][3] = (mat.a[0][0]*mat.a[1][3]*mat.a[2][1]
226  + mat.a[0][1]*mat.a[1][0]*mat.a[2][3]
227  + mat.a[0][3]*mat.a[1][1]*mat.a[2][0]
228  - mat.a[0][0]*mat.a[1][1]*mat.a[2][3]
229  - mat.a[0][1]*mat.a[1][3]*mat.a[2][0]
230  - mat.a[0][3]*mat.a[1][0]*mat.a[2][1]) / det;
231 
232  return m;
233 }
234 
235 StdMeshMatrix StdMeshMatrix::Translate(float dx, float dy, float dz)
236 {
237  StdMeshMatrix m;
238  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = dx;
239  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = dy;
240  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = dz;
241  return m;
242 }
243 
244 StdMeshMatrix StdMeshMatrix::Scale(float sx, float sy, float sz)
245 {
246  StdMeshMatrix m;
247  m.a[0][0] = sx; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
248  m.a[1][0] = 0.0f; m.a[1][1] = sy; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
249  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = sz; m.a[2][3] = 0.0f;
250  return m;
251 }
252 
253 StdMeshMatrix StdMeshMatrix::Rotate(float angle, float rx, float ry, float rz)
254 {
255  StdMeshMatrix m;
256 
257  // We do normalize the rx,ry,rz vector here: This is only required for
258  // precalculations anyway, thus not time-critical.
259  float abs = sqrt(rx*rx+ry*ry+rz*rz);
260  rx/=abs; ry/=abs; rz/=abs;
261  float c = cos(angle), s = sin(angle);
262 
263  m.a[0][0] = rx*rx*(1-c)+c; m.a[0][1] = rx*ry*(1-c)-rz*s; m.a[0][2] = rx*rz*(1-c)+ry*s; m.a[0][3] = 0.0f;
264  m.a[1][0] = ry*rx*(1-c)+rz*s; m.a[1][1] = ry*ry*(1-c)+c; m.a[1][2] = ry*rz*(1-c)-rx*s; m.a[1][3] = 0.0f;
265  m.a[2][0] = rz*rx*(1-c)-ry*s; m.a[2][1] = ry*rz*(1-c)+rx*s; m.a[2][2] = rz*rz*(1-c)+c; m.a[2][3] = 0.0f;
266  return m;
267 }
268 
270 {
271  StdMeshMatrix m;
272 
273  float tx = 2*transform.rotate.x;
274  float ty = 2*transform.rotate.y;
275  float tz = 2*transform.rotate.z;
276  float twx = tx*transform.rotate.w;
277  float twy = ty*transform.rotate.w;
278  float twz = tz*transform.rotate.w;
279  float txx = tx*transform.rotate.x;
280  float txy = ty*transform.rotate.x;
281  float txz = tz*transform.rotate.x;
282  float tyy = ty*transform.rotate.y;
283  float tyz = tz*transform.rotate.y;
284  float tzz = tz*transform.rotate.z;
285 
286  m.a[0][0] = (1.0f - (tyy + tzz) ) * transform.scale.x;
287  m.a[0][1] = (txy - twz) * transform.scale.y;
288  m.a[0][2] = (txz + twy) * transform.scale.z;
289  m.a[1][0] = (txy + twz) * transform.scale.x;
290  m.a[1][1] = (1.0f - (txx + tzz) ) * transform.scale.y;
291  m.a[1][2] = (tyz - twx) * transform.scale.z;
292  m.a[2][0] = (txz - twy) * transform.scale.x;
293  m.a[2][1] = (tyz + twx) * transform.scale.y;
294  m.a[2][2] = (1.0f - (txx + tyy) ) * transform.scale.z;
295 
296  m.a[0][3] = transform.translate.x;
297  m.a[1][3] = transform.translate.y;
298  m.a[2][3] = transform.translate.z;
299 
300  return m;
301 }
302 
304 {
305  StdMeshMatrix m;
306 
307  float tx = 2*transform.rotate.x;
308  float ty = 2*transform.rotate.y;
309  float tz = 2*transform.rotate.z;
310  float twx = -tx*transform.rotate.w;
311  float twy = -ty*transform.rotate.w;
312  float twz = -tz*transform.rotate.w;
313  float txx = tx*transform.rotate.x;
314  float txy = ty*transform.rotate.x;
315  float txz = tz*transform.rotate.x;
316  float tyy = ty*transform.rotate.y;
317  float tyz = tz*transform.rotate.y;
318  float tzz = tz*transform.rotate.z;
319 
320  m.a[0][0] = (1.0f - (tyy + tzz) ) / transform.scale.x;
321  m.a[0][1] = (txy - twz) / transform.scale.x;
322  m.a[0][2] = (txz + twy) / transform.scale.x;
323  m.a[1][0] = (txy + twz) / transform.scale.y;
324  m.a[1][1] = (1.0f - (txx + tzz) ) / transform.scale.y;
325  m.a[1][2] = (tyz - twx) / transform.scale.y;
326  m.a[2][0] = (txz - twy) / transform.scale.z;
327  m.a[2][1] = (tyz + twx) / transform.scale.z;
328  m.a[2][2] = (1.0f - (txx + tyy) ) / transform.scale.z;
329 
330  // Signs do not cancel!
331  StdMeshVector invtranslate = (-transform.rotate) * (-transform.translate/transform.scale);
332 
333  m.a[0][3] = invtranslate.x;
334  m.a[1][3] = invtranslate.y;
335  m.a[2][3] = invtranslate.z;
336 
337  return m;
338 }
339 
341 {
342  // See http://stackoverflow.com/questions/349050/calculating-a-lookat-matrix
343  StdMeshVector z = eye - center;
344  z.Normalize();
345 
347  x.Normalize();
348 
350 
351  StdMeshMatrix m;
352  m.a[0][0] = x.x; m.a[0][1] = x.y; m.a[0][2] = x.z; m.a[0][3] = -x.x*eye.x - x.y*eye.y - x.z*eye.z;
353  m.a[1][0] = y.x; m.a[1][1] = y.y; m.a[1][2] = y.z; m.a[1][3] = -y.x*eye.x - y.y*eye.y - y.z*eye.z;
354  m.a[2][0] = z.x; m.a[2][1] = z.y; m.a[2][2] = z.z; m.a[2][3] = -z.x*eye.x - z.y*eye.y - z.z*eye.z;
355  return m;
356 }
357 
359 {
360  return a[0][0]*a[1][1]*a[2][2] + a[0][1]*a[1][2]*a[2][0] + a[0][2]*a[1][0]*a[2][1]
361  - a[0][0]*a[1][2]*a[2][1] - a[0][1]*a[1][0]*a[2][2] - a[0][2]*a[1][1]*a[2][0];
362 }
363 
365 {
367  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
368  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
369  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = 0.0f;
370  m.a[3][0] = 0.0f; m.a[3][1] = 0.0f; m.a[3][2] = 0.0f; m.a[3][3] = 1.0f;
371  return m;
372 }
373 
375 {
377  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = dx;
378  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = dy;
379  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = dz;
380  m.a[3][0] = 0.0f; m.a[3][1] = 0.0f; m.a[3][2] = 0.0f; m.a[3][3] = 1.0f;
381  return m;
382 }
383 
384 StdProjectionMatrix StdProjectionMatrix::Scale(float sx, float sy, float sz)
385 {
387  m.a[0][0] = sx; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
388  m.a[1][0] = 0.0f; m.a[1][1] = sy; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
389  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = sz; m.a[2][3] = 0.0f;
390  m.a[3][0] = 0.0f; m.a[3][1] = 0.0f; m.a[3][2] = 0.0f; m.a[3][3] = 1.0f;
391  return m;
392 }
393 
394 StdProjectionMatrix StdProjectionMatrix::Rotate(float angle, float rx, float ry, float rz)
395 {
397 
398  // We do normalize the rx,ry,rz vector here: This is only required for
399  // precalculations anyway, thus not time-critical.
400  float abs = sqrt(rx*rx+ry*ry+rz*rz);
401  rx/=abs; ry/=abs; rz/=abs;
402  float c = cos(angle), s = sin(angle);
403 
404  m.a[0][0] = rx*rx*(1-c)+c; m.a[0][1] = rx*ry*(1-c)-rz*s; m.a[0][2] = rx*rz*(1-c)+ry*s; m.a[0][3] = 0.0f;
405  m.a[1][0] = ry*rx*(1-c)+rz*s; m.a[1][1] = ry*ry*(1-c)+c; m.a[1][2] = ry*rz*(1-c)-rx*s; m.a[1][3] = 0.0f;
406  m.a[2][0] = rz*rx*(1-c)-ry*s; m.a[2][1] = ry*rz*(1-c)+rx*s; m.a[2][2] = rz*rz*(1-c)+c; m.a[2][3] = 0.0f;
407  m.a[3][0] = 0.0f; m.a[3][1] = 0.0f; m.a[3][2] = 0.0f; m.a[3][3] = 1.0f;
408  return m;
409 }
410 
412 {
413  StdProjectionMatrix matrix;
414  matrix(0,0) = 2.0f / (right - left);
415  matrix(0,1) = 0.0f;
416  matrix(0,2) = 0.0f;
417  matrix(0,3) = -(right + left) / (right - left);
418  matrix(1,0) = 0.0f;
419  matrix(1,1) = 2.0f / (top - bottom);
420  matrix(1,2) = 0.0f;
421  matrix(1,3) = -(top + bottom) / (top - bottom);
422  matrix(2,0) = 0.0f;
423  matrix(2,1) = 0.0f;
424  matrix(2,2) = -1.0f;
425  matrix(2,3) = 0.0f;
426  matrix(3,0) = 0.0f;
427  matrix(3,1) = 0.0f;
428  matrix(3,2) = 0.0f;
429  matrix(3,3) = 1.0f;
430  return matrix;
431 }
432 
434 {
435  StdMeshMatrix m;
436  m(0, 0) = matrix.a[0][0]; m(0, 1) = matrix.a[0][1]; m(0, 2) = matrix.a[0][2]; m(0, 3) = matrix.a[0][3];
437  m(1, 0) = matrix.a[1][0]; m(1, 1) = matrix.a[1][1]; m(1, 2) = matrix.a[1][2]; m(1, 3) = matrix.a[1][3];
438  m(2, 0) = matrix.a[2][0]; m(2, 1) = matrix.a[2][1]; m(2, 2) = matrix.a[2][2]; m(2, 3) = matrix.a[2][3];
439  return m;
440 }
441 
443 {
444  // Extract the scale part of the matrix
445  const float sx = sqrt(a[0][0]*a[0][0] + a[1][0]*a[1][0] + a[2][0]*a[2][0]);
446  const float sy = sqrt(a[0][1]*a[0][1] + a[1][1]*a[1][1] + a[2][1]*a[2][1]);
447  const float sz = sqrt(a[0][2]*a[0][2] + a[1][2]*a[1][2] + a[2][2]*a[2][2]);
448 
449  // What remains is the rotation part
450  // TODO: This can be optimized by not doing the full matrix multiplication
451  StdMeshMatrix rot = Scale(1.0f/sx, 1.0f/sy, 1.0f/sz) * *this;
452 
453  // Note that this does not work for skew matrices -- we cannot
454  // represent skews in StdMeshTransformation
455  const float cos_angle = 0.5f * (rot.a[0][0] + rot.a[1][1] + rot.a[2][2] - 1.0f);
456 
457  const float rdx = rot.a[2][1] - rot.a[1][2];
458  const float rdy = rot.a[0][2] - rot.a[2][0];
459  const float rdz = rot.a[1][0] - rot.a[0][1];
460  const float det = sqrt(rdx*rdx + rdy*rdy + rdz*rdz);
461 
462  const float rx = (rot.a[2][1] - rot.a[1][2]) / det;
463  const float ry = (rot.a[0][2] - rot.a[2][0]) / det;
464  const float rz = (rot.a[1][0] - rot.a[0][1]) / det;
465 
466  StdMeshTransformation trans;
467  trans.scale.x = sx;
468  trans.scale.y = sy;
469  trans.scale.z = sz;
470  trans.rotate = StdMeshQuaternion::AngleAxis(acos(cos_angle), StdMeshVector::Translate(rx, ry, rz));
471  trans.translate.x = a[0][3];
472  trans.translate.y = a[1][3];
473  trans.translate.z = a[2][3];
474 
475  return trans;
476 }
477 
479 {
480  StdMeshMatrix m;
481 
482  m(0,0) = lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0);
483  m(1,0) = lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0);
484  m(2,0) = lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0);
485 
486  m(0,1) = lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1);
487  m(1,1) = lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1);
488  m(2,1) = lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1);
489 
490  m(0,2) = lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2);
491  m(1,2) = lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2);
492  m(2,2) = lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2);
493 
494  m(0,3) = lhs(0,0)*rhs(0,3) + lhs(0,1)*rhs(1,3) + lhs(0,2)*rhs(2,3) + lhs(0,3);
495  m(1,3) = lhs(1,0)*rhs(0,3) + lhs(1,1)*rhs(1,3) + lhs(1,2)*rhs(2,3) + lhs(1,3);
496  m(2,3) = lhs(2,0)*rhs(0,3) + lhs(2,1)*rhs(1,3) + lhs(2,2)*rhs(2,3) + lhs(2,3);
497 
498  return m;
499 }
500 
501 StdMeshMatrix operator*(float lhs, const StdMeshMatrix& rhs)
502 {
503  StdMeshMatrix m;
504  m(0,0) = lhs * rhs(0,0);
505  m(1,0) = lhs * rhs(1,0);
506  m(2,0) = lhs * rhs(2,0);
507  m(0,1) = lhs * rhs(0,1);
508  m(1,1) = lhs * rhs(1,1);
509  m(2,1) = lhs * rhs(2,1);
510  m(0,2) = lhs * rhs(0,2);
511  m(1,2) = lhs * rhs(1,2);
512  m(2,2) = lhs * rhs(2,2);
513  m(0,3) = lhs * rhs(0,3);
514  m(1,3) = lhs * rhs(1,3);
515  m(2,3) = lhs * rhs(2,3);
516  return m;
517 }
518 
519 StdMeshMatrix operator*(const StdMeshMatrix& lhs, float rhs)
520 {
521  return rhs * lhs;
522 }
523 
525 {
526  lhs = lhs * rhs;
527  return lhs;
528 }
529 
531 {
532  StdMeshMatrix m;
533  m(0,0) = lhs(0,0) + rhs(0,0);
534  m(1,0) = lhs(1,0) + rhs(1,0);
535  m(2,0) = lhs(2,0) + rhs(2,0);
536  m(0,1) = lhs(0,1) + rhs(0,1);
537  m(1,1) = lhs(1,1) + rhs(1,1);
538  m(2,1) = lhs(2,1) + rhs(2,1);
539  m(0,2) = lhs(0,2) + rhs(0,2);
540  m(1,2) = lhs(1,2) + rhs(1,2);
541  m(2,2) = lhs(2,2) + rhs(2,2);
542  m(0,3) = lhs(0,3) + rhs(0,3);
543  m(1,3) = lhs(1,3) + rhs(1,3);
544  m(2,3) = lhs(2,3) + rhs(2,3);
545  return m;
546 }
547 
549 {
551 
552  m(0,0) = lhs(0,0)*rhs(0,0) + lhs(0,1)*rhs(1,0) + lhs(0,2)*rhs(2,0) + lhs(0,3)*rhs(3,0);
553  m(1,0) = lhs(1,0)*rhs(0,0) + lhs(1,1)*rhs(1,0) + lhs(1,2)*rhs(2,0) + lhs(1,3)*rhs(3,0);
554  m(2,0) = lhs(2,0)*rhs(0,0) + lhs(2,1)*rhs(1,0) + lhs(2,2)*rhs(2,0) + lhs(2,3)*rhs(3,0);
555  m(3,0) = lhs(3,0)*rhs(0,0) + lhs(3,1)*rhs(1,0) + lhs(3,2)*rhs(2,0) + lhs(3,3)*rhs(3,0);
556 
557  m(0,1) = lhs(0,0)*rhs(0,1) + lhs(0,1)*rhs(1,1) + lhs(0,2)*rhs(2,1) + lhs(0,3)*rhs(3,1);
558  m(1,1) = lhs(1,0)*rhs(0,1) + lhs(1,1)*rhs(1,1) + lhs(1,2)*rhs(2,1) + lhs(1,3)*rhs(3,1);
559  m(2,1) = lhs(2,0)*rhs(0,1) + lhs(2,1)*rhs(1,1) + lhs(2,2)*rhs(2,1) + lhs(2,3)*rhs(3,1);
560  m(3,1) = lhs(3,0)*rhs(0,1) + lhs(3,1)*rhs(1,1) + lhs(3,2)*rhs(2,1) + lhs(3,3)*rhs(3,1);
561 
562  m(0,2) = lhs(0,0)*rhs(0,2) + lhs(0,1)*rhs(1,2) + lhs(0,2)*rhs(2,2) + lhs(0,3)*rhs(3,2);
563  m(1,2) = lhs(1,0)*rhs(0,2) + lhs(1,1)*rhs(1,2) + lhs(1,2)*rhs(2,2) + lhs(1,3)*rhs(3,2);
564  m(2,2) = lhs(2,0)*rhs(0,2) + lhs(2,1)*rhs(1,2) + lhs(2,2)*rhs(2,2) + lhs(2,3)*rhs(3,2);
565  m(3,2) = lhs(3,0)*rhs(0,2) + lhs(3,1)*rhs(1,2) + lhs(3,2)*rhs(2,2) + lhs(3,3)*rhs(3,2);
566 
567  m(0,3) = lhs(0,0)*rhs(0,3) + lhs(0,1)*rhs(1,3) + lhs(0,2)*rhs(2,3) + lhs(0,3)*rhs(3,3);
568  m(1,3) = lhs(1,0)*rhs(0,3) + lhs(1,1)*rhs(1,3) + lhs(1,2)*rhs(2,3) + lhs(1,3)*rhs(3,3);
569  m(2,3) = lhs(2,0)*rhs(0,3) + lhs(2,1)*rhs(1,3) + lhs(2,2)*rhs(2,3) + lhs(2,3)*rhs(3,3);
570  m(3,3) = lhs(3,0)*rhs(0,3) + lhs(3,1)*rhs(1,3) + lhs(3,2)*rhs(2,3) + lhs(3,3)*rhs(3,3);
571 
572  return m;
573 }
574 
576 {
577  lhs = lhs * rhs;
578  return lhs;
579 }
580 
582 {
584  q.w = -rhs.w;
585  q.x = -rhs.x;
586  q.y = -rhs.y;
587  q.z = -rhs.z;
588  return q;
589 }
590 
592 {
594  q.w = lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z*rhs.z;
595  q.x = lhs.w*rhs.x + lhs.x*rhs.w + lhs.y*rhs.z - lhs.z*rhs.y;
596  q.y = lhs.w*rhs.y + lhs.y*rhs.w + lhs.z*rhs.x - lhs.x*rhs.z;
597  q.z = lhs.w*rhs.z + lhs.z*rhs.w + lhs.x*rhs.y - lhs.y*rhs.x;
598  return q;
599 }
600 
602 {
603  lhs.w *= rhs;
604  lhs.x *= rhs;
605  lhs.y *= rhs;
606  lhs.z *= rhs;
607  return lhs;
608 }
609 
611 {
612  StdMeshQuaternion q(lhs);
613  q *= rhs;
614  return q;
615 }
616 
618 {
619  return rhs * lhs;
620 }
621 
623 {
624  lhs.w += rhs.w;
625  lhs.x += rhs.x;
626  lhs.y += rhs.y;
627  lhs.z += rhs.z;
628  return lhs;
629 }
630 
632 {
633  StdMeshQuaternion q(lhs);
634  q += rhs;
635  return q;
636 }
637 
639 {
641  q.w = lhs.w - rhs.w;
642  q.x = lhs.x - rhs.x;
643  q.y = lhs.y - rhs.y;
644  q.z = lhs.z - rhs.z;
645  return q;
646 }
647 
649 {
651  t.rotate = lhs.rotate * rhs.rotate;
652  t.scale = lhs.scale * rhs.scale;
653  t.translate = lhs.translate + lhs.rotate * (lhs.scale * rhs.translate);
654  return t;
655 }
656 
658 {
659  StdMeshVector v;
660  v.x = -rhs.x;
661  v.y = -rhs.y;
662  v.z = -rhs.z;
663  return v;
664 }
665 
667 {
668  lhs.x += rhs.x;
669  lhs.y += rhs.y;
670  lhs.z += rhs.z;
671  return lhs;
672 }
673 
675 {
676  StdMeshVector v(lhs);
677  v += rhs;
678  return v;
679 }
680 
682 {
683  lhs.x -= rhs.x;
684  lhs.y -= rhs.y;
685  lhs.z -= rhs.z;
686  return lhs;
687 }
688 
690 {
691  StdMeshVector v(lhs);
692  v -= rhs;
693  return v;
694 }
695 
697 {
698  StdMeshVector v;
699  v.x = lhs.x * rhs.x;
700  v.y = lhs.y * rhs.y;
701  v.z = lhs.z * rhs.z;
702  return v;
703 }
704 
706 {
707  lhs.x *= rhs;
708  lhs.y *= rhs;
709  lhs.z *= rhs;
710  return lhs;
711 }
712 
713 StdMeshVector operator*(const StdMeshVector& lhs, float rhs)
714 {
715  StdMeshVector v(lhs);
716  v *= rhs;
717  return v;
718 }
719 
720 StdMeshVector operator*(float lhs, const StdMeshVector& rhs)
721 {
722  return rhs * lhs;
723 }
724 
726 {
727  StdMeshVector v;
728  v.x = lhs.x/rhs.x;
729  v.y = lhs.y/rhs.y;
730  v.z = lhs.z/rhs.z;
731  return v;
732 }
733 
734 StdMeshVector operator/(float lhs, const StdMeshVector& rhs)
735 {
736  StdMeshVector v;
737  v.x = lhs/rhs.x;
738  v.y = lhs/rhs.y;
739  v.z = lhs/rhs.z;
740  return v;
741 }
742 
743 StdMeshVector operator/(const StdMeshVector& lhs, float rhs)
744 {
745  StdMeshVector v;
746  v.x = lhs.x/rhs;
747  v.y = lhs.y/rhs;
748  v.z = lhs.z/rhs;
749  return v;
750 }
751 
752 StdMeshVector operator*(const StdMeshMatrix& lhs, const StdMeshVector& rhs) // does not apply translation part
753 {
754  StdMeshVector v;
755  v.x = lhs(0,0)*rhs.x + lhs(0,1)*rhs.y + lhs(0,2)*rhs.z;
756  v.y = lhs(1,0)*rhs.x + lhs(1,1)*rhs.y + lhs(1,2)*rhs.z;
757  v.z = lhs(2,0)*rhs.x + lhs(2,1)*rhs.y + lhs(2,2)*rhs.z;
758  return v;
759 }
760 
762 {
763  StdMeshVector v = { lhs.x, lhs.y, lhs.z };
764  StdMeshVector uv = 2.0f * StdMeshVector::Cross(v, rhs);
765  StdMeshVector uuv = StdMeshVector::Cross(v, uv);
766  return rhs + lhs.w * uv + uuv;
767 }
768 
770 {
771  lhs.nx += rhs.nx;
772  lhs.ny += rhs.ny;
773  lhs.nz += rhs.nz;
774  lhs.x += rhs.x;
775  lhs.y += rhs.y;
776  lhs.z += rhs.z;
777  return lhs;
778 }
779 
781 {
782  StdMeshVertex vtx(lhs);
783  vtx += rhs;
784  return vtx;
785 }
786 
787 StdMeshVertex operator*(float lhs, const StdMeshVertex& rhs)
788 {
789  StdMeshVertex vtx;
790  vtx.nx = lhs*rhs.nx;
791  vtx.ny = lhs*rhs.ny;
792  vtx.nz = lhs*rhs.nz;
793  vtx.x = lhs*rhs.x;
794  vtx.y = lhs*rhs.y;
795  vtx.z = lhs*rhs.z;
796  return vtx;
797 }
798 
799 StdMeshVertex operator*(const StdMeshVertex& lhs, float rhs)
800 {
801  return rhs * lhs;
802 }
803 
805 {
806  StdMeshVertex vtx;
807  vtx.nx = lhs(0,0)*rhs.nx + lhs(0,1)*rhs.ny + lhs(0,2)*rhs.nz;
808  vtx.ny = lhs(1,0)*rhs.nx + lhs(1,1)*rhs.ny + lhs(0,2)*rhs.nz;
809  vtx.nz = lhs(2,0)*rhs.nx + lhs(2,1)*rhs.ny + lhs(2,2)*rhs.nz;
810  vtx.x = lhs(0,0)*rhs.x + lhs(0,1)*rhs.y + lhs(0,2)*rhs.z + lhs(0,3);
811  vtx.y = lhs(1,0)*rhs.x + lhs(1,1)*rhs.y + lhs(1,2)*rhs.z + lhs(1,3);
812  vtx.z = lhs(2,0)*rhs.x + lhs(2,1)*rhs.y + lhs(2,2)*rhs.z + lhs(2,3);
813  vtx.u = rhs.u; vtx.v = rhs.v;
814  return vtx;
815 }
static StdMeshQuaternion AngleAxis(float theta, const StdMeshVector &axis)
Definition: StdMeshMath.cpp:72
static StdMeshMatrix Upper3x4(const StdProjectionMatrix &matrix)
static StdMeshQuaternion Zero()
Definition: StdMeshMath.cpp:62
float Determinant() const
StdMeshTransformation Decompose() const
StdMeshQuaternion rotate
Definition: StdMeshMath.h:75
StdMeshQuaternion & operator+=(StdMeshQuaternion &lhs, const StdMeshQuaternion &rhs)
static StdMeshTransformation Identity()
StdMeshQuaternion operator-(const StdMeshQuaternion &rhs)
#define a
static StdMeshMatrix Rotate(float angle, float rx, float ry, float rz)
static StdMeshTransformation Nlerp(const StdMeshTransformation &lhs, const StdMeshTransformation &rhs, float w)
StdMeshMatrix operator+(const StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
StdMeshVector & operator-=(StdMeshVector &lhs, const StdMeshVector &rhs)
static StdMeshTransformation Inverse(const StdMeshTransformation &transform)
static StdMeshMatrix Identity()
void Scale(MatrixType &mat, float sx, float sy, float sz)
Definition: StdMeshMath.h:195
StdMeshVector operator/(const StdMeshVector &lhs, const StdMeshVector &rhs)
static StdMeshTransformation Translate(float dx, float dy, float dz)
StdMeshMatrix & operator*=(StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
static StdMeshMatrix Zero()
static StdMeshVector Translate(float dx, float dy, float dz)
Definition: StdMeshMath.cpp:38
static StdMeshMatrix Translate(float dx, float dy, float dz)
StdMeshMatrix operator*(const StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
static StdMeshMatrix Inverse(const StdMeshMatrix &mat)
void Normalize()
Definition: StdMeshMath.cpp:56
static StdMeshVector UnitScale()
Definition: StdMeshMath.cpp:29
static StdMeshVector Zero()
Definition: StdMeshMath.cpp:20
static StdMeshMatrix TransformInverse(const StdMeshTransformation &transform)
static StdProjectionMatrix Orthographic(float left, float right, float bottom, float top)
static StdMeshTransformation Rotate(float angle, float rx, float ry, float rz)
static StdProjectionMatrix Rotate(float angle, float rx, float ry, float rz)
StdMeshVector scale
Definition: StdMeshMath.h:74
static StdMeshTransformation Scale(float sx, float sy, float sz)
static StdProjectionMatrix Scale(float sx, float sy, float sz)
static StdMeshMatrix Scale(float sx, float sy, float sz)
static StdProjectionMatrix Translate(float dx, float dy, float dz)
static StdProjectionMatrix Identity()
StdMeshVector translate
Definition: StdMeshMath.h:76
static StdMeshMatrix LookAt(const StdMeshVector &eye, const StdMeshVector &center, const StdMeshVector &up)
static StdMeshMatrix Transform(const StdMeshTransformation &transform)
static StdMeshVector Cross(const StdMeshVector &lhs, const StdMeshVector &rhs)
Definition: StdMeshMath.cpp:47
static StdMeshTransformation Zero()
#define s
static StdMeshQuaternion Nlerp(const StdMeshQuaternion &lhs, const StdMeshQuaternion &rhs, float w)
Definition: StdMeshMath.cpp:93