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