OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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 
62 StdMeshQuaternion StdMeshQuaternion::Zero()
63 {
64  StdMeshQuaternion q;
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 
72 StdMeshQuaternion StdMeshQuaternion::AngleAxis(float theta, const StdMeshVector& axis)
73 {
74  StdMeshQuaternion q;
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 
84 void StdMeshQuaternion::Normalize()
85 {
86  float length = sqrt(LenSqr());
87  w /= length;
88  x /= length;
89  y /= length;
90  z /= length;
91 }
92 
93 StdMeshQuaternion StdMeshQuaternion::Nlerp(const StdMeshQuaternion& lhs, const StdMeshQuaternion& rhs, float w)
94 {
95  StdMeshQuaternion q;
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 
105 StdMeshTransformation StdMeshTransformation::Zero()
106 {
107  StdMeshTransformation t;
108  t.scale = StdMeshVector::Zero();
109  t.rotate = StdMeshQuaternion::Zero();
110  t.translate = StdMeshVector::Zero();
111  return t;
112 }
113 
114 StdMeshTransformation StdMeshTransformation::Identity()
115 {
116  StdMeshTransformation t;
117  t.scale = StdMeshVector::UnitScale();
118  t.rotate.w = 1.0f;
119  t.rotate.x = t.rotate.y = t.rotate.z = 0.0f;
120  t.translate = StdMeshVector::Zero();
121  return t;
122 }
123 
124 StdMeshTransformation StdMeshTransformation::Inverse(const StdMeshTransformation& transform)
125 {
126  StdMeshTransformation t;
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 
136 StdMeshTransformation StdMeshTransformation::Translate(float dx, float dy, float dz)
137 {
138  StdMeshTransformation t;
139  t.scale = StdMeshVector::UnitScale();
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 
146 StdMeshTransformation StdMeshTransformation::Scale(float sx, float sy, float sz)
147 {
148  StdMeshTransformation t;
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;
152  t.translate = StdMeshVector::Zero();
153  return t;
154 }
155 
156 StdMeshTransformation StdMeshTransformation::Rotate(float angle, float rx, float ry, float rz)
157 {
158  StdMeshTransformation t;
159  t.scale = StdMeshVector::UnitScale();
160  t.rotate = StdMeshQuaternion::AngleAxis(angle, StdMeshVector::Translate(rx, ry, rz));
161  t.translate = StdMeshVector::Zero();
162  return t;
163 }
164 
165 StdMeshTransformation StdMeshTransformation::Nlerp(const StdMeshTransformation& lhs, const StdMeshTransformation& rhs, float w)
166 {
167  StdMeshTransformation t;
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 
174 StdMeshMatrix StdMeshMatrix::Zero()
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 
183 StdMeshMatrix StdMeshMatrix::Identity()
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 
192 StdMeshMatrix StdMeshMatrix::Inverse(const StdMeshMatrix& mat)
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 
269 StdMeshMatrix StdMeshMatrix::Transform(const StdMeshTransformation& transform)
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 
303 StdMeshMatrix StdMeshMatrix::TransformInverse(const StdMeshTransformation& transform)
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 
340 StdMeshMatrix StdMeshMatrix::LookAt(const StdMeshVector& eye, const StdMeshVector& center, const StdMeshVector& up)
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 
358 float StdMeshMatrix::Determinant() const
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 
364 StdProjectionMatrix StdProjectionMatrix::Identity()
365 {
366  StdProjectionMatrix m;
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 
374 StdProjectionMatrix StdProjectionMatrix::Translate(float dx, float dy, float dz)
375 {
376  StdProjectionMatrix m;
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 {
386  StdProjectionMatrix m;
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 {
396  StdProjectionMatrix m;
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 
411 StdProjectionMatrix StdProjectionMatrix::Orthographic(float left, float right, float bottom, float top)
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 
433 StdMeshMatrix StdProjectionMatrix::Upper3x4(const StdProjectionMatrix& matrix)
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 
442 StdMeshTransformation StdMeshMatrix::Decompose() const
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 
478 StdMeshMatrix operator*(const StdMeshMatrix& lhs, const StdMeshMatrix& rhs)
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 
524 StdMeshMatrix& operator*=(StdMeshMatrix& lhs, const StdMeshMatrix& rhs)
525 {
526  lhs = lhs * rhs;
527  return lhs;
528 }
529 
530 StdMeshMatrix operator+(const StdMeshMatrix& lhs, const StdMeshMatrix& rhs)
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 
548 StdProjectionMatrix operator*(const StdProjectionMatrix& lhs, const StdProjectionMatrix& rhs)
549 {
550  StdProjectionMatrix m;
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 
575 StdProjectionMatrix& operator*=(StdProjectionMatrix& lhs, const StdProjectionMatrix& rhs)
576 {
577  lhs = lhs * rhs;
578  return lhs;
579 }
580 
581 StdMeshQuaternion operator-(const StdMeshQuaternion& rhs)
582 {
583  StdMeshQuaternion q;
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 
591 StdMeshQuaternion operator*(const StdMeshQuaternion& lhs, const StdMeshQuaternion& rhs)
592 {
593  StdMeshQuaternion q;
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 
601 StdMeshQuaternion& operator*=(StdMeshQuaternion& lhs, float rhs)
602 {
603  lhs.w *= rhs;
604  lhs.x *= rhs;
605  lhs.y *= rhs;
606  lhs.z *= rhs;
607  return lhs;
608 }
609 
610 StdMeshQuaternion operator*(const StdMeshQuaternion& lhs, float rhs)
611 {
612  StdMeshQuaternion q(lhs);
613  q *= rhs;
614  return q;
615 }
616 
617 StdMeshQuaternion operator*(float lhs, const StdMeshQuaternion& rhs)
618 {
619  return rhs * lhs;
620 }
621 
622 StdMeshQuaternion& operator+=(StdMeshQuaternion& lhs, const StdMeshQuaternion& rhs)
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 
631 StdMeshQuaternion operator+(const StdMeshQuaternion& lhs, const StdMeshQuaternion& rhs)
632 {
633  StdMeshQuaternion q(lhs);
634  q += rhs;
635  return q;
636 }
637 
638 StdMeshQuaternion operator-(const StdMeshQuaternion& lhs, const StdMeshQuaternion& rhs)
639 {
640  StdMeshQuaternion q;
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 
648 StdMeshTransformation operator*(const StdMeshTransformation& lhs, const StdMeshTransformation& rhs)
649 {
650  StdMeshTransformation t;
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 
761 StdMeshVector operator*(const StdMeshQuaternion& lhs, const StdMeshVector& rhs)
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 
804 StdMeshVertex operator*(const StdMeshMatrix& lhs, const StdMeshVertex& rhs)
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 }
#define z
StdMeshQuaternion & operator+=(StdMeshQuaternion &lhs, const StdMeshQuaternion &rhs)
StdMeshQuaternion operator-(const StdMeshQuaternion &rhs)
#define a
StdMeshMatrix operator+(const StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
StdMeshVector & operator-=(StdMeshVector &lhs, const StdMeshVector &rhs)
StdMeshVector operator/(const StdMeshVector &lhs, const StdMeshVector &rhs)
StdMeshMatrix & operator*=(StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
static StdMeshVector Translate(float dx, float dy, float dz)
Definition: StdMeshMath.cpp:38
StdMeshMatrix operator*(const StdMeshMatrix &lhs, const StdMeshMatrix &rhs)
void Normalize()
Definition: StdMeshMath.cpp:56
static StdMeshVector UnitScale()
Definition: StdMeshMath.cpp:29
static StdMeshVector Zero()
Definition: StdMeshMath.cpp:20
static StdMeshVector Cross(const StdMeshVector &lhs, const StdMeshVector &rhs)
Definition: StdMeshMath.cpp:47
#define s