ScummVM API documentation
xmath.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef QDENGINE_XMATH_H
23 #define QDENGINE_XMATH_H
24 
25 #include "common/scummsys.h"
26 
27 namespace QDEngine {
28 
29 class Archive;
30 
31 class Vect2f;
32 class Vect2i;
33 class Vect2s;
34 class Vect3f;
35 
36 enum eAxis {
37  X_AXIS = 0,
38  Y_AXIS = 1,
39  Z_AXIS = 2,
40  W_AXIS = 3
41 };
42 
43 
45 // Constants
47 #undef M_PI
48 #define M_PI 3.14159265358979323846f
49 #undef M_PI_2
50 #define M_PI_2 1.57079632679489661923f
51 #undef M_PI_4
52 #define M_PI_4 0.785398163397448309616f
53 
54 const double DBL_EPS = 1.e-15;
55 const double DBL_INF = 1.e+100;
56 const double DBL_COMPARE_TOLERANCE = 1.e-10;
57 
58 const float FLT_EPS = 1.192092896e-07f; //1.e-7f;
59 const float FLT_INF = 1.e+30f;
60 const float FLT_COMPARE_TOLERANCE = 1.e-5f;
61 
62 const int INT_INF = 0x7fffffff;
63 
64 inline float invSqrtFast(float x) {
65  x += 1e-7f; // Добавка, устраняющая деление на 0
66  float xhalf = 0.5f * x;
67 
68  uint32 i;
69  memcpy(&i, &x, 4);
70  i = 0x5f375a86 - (i >> 1); // gives initial guess y0
71  memcpy(&x, &i, 4);
72  x = x * (1.5f - xhalf * x * x); // Newton step, repeating increases accuracy
73  return x;
74 }
75 
76 inline float cycle(float f, float size) {
77  return fmod(fmod(f, size) + size, size);
78 }
79 
80 inline float getDist(float v0, float v1, float size) {
81  float d = fmod(v0 - v1, size);
82  float ad = (float)fabs(d);
83  float dd = size - ad;
84  if (ad <= dd) return d;
85  return d < 0 ? d + size : d - size;
86 }
87 
88 inline float getDeltaAngle(float to, float from) {
89  return getDist(to, from, 2 * M_PI);
90 }
91 
92 inline float cycleAngle(float a) {
93  return cycle(a, 2 * M_PI);
94 }
95 
96 
98 //
99 // Scalar Functions
100 //
102 
103 template <class T>
104 inline T sqr(const T &x) {
105  return x*x;
106 }
107 
108 #define G2R(x) ((x)*M_PI/180.f)
109 #define R2G(x) ((x)*180.f/M_PI)
110 
112 //
113 // class Vect2f
114 //
116 
117 class Vect2f {
118 public:
119  float x, y;
120 
121  inline Vect2f() { x = y = 0.0; }
122  inline Vect2f(float x_, float y_) {
123  x = x_;
124  y = y_;
125  }
126 
127  typedef float float2[2];
128  inline Vect2f(const float2 &v) {
129  x = v[0];
130  y = v[1];
131  }
132 
133  inline Vect2f(const Vect2i &v);
134  inline Vect2f(const Vect2s &v);
135 
136  inline Vect2f &set(float x_, float y_) {
137  x = x_;
138  y = y_;
139  return *this;
140  }
141  inline Vect2f operator - () const {
142  return Vect2f(-x, -y);
143  }
144 
145  inline int xi() const {
146  return round(x);
147  }
148  inline int yi() const {
149  return round(y);
150  }
151 
152  inline const float &operator[](int i) const {
153  return *(&x + i);
154  }
155  inline float &operator[](int i) {
156  return *(&x + i);
157  }
158 
159  inline Vect2f &operator += (const Vect2f &v) {
160  x += v.x;
161  y += v.y;
162  return *this;
163  }
164  inline Vect2f &operator -= (const Vect2f &v) {
165  x -= v.x;
166  y -= v.y;
167  return *this;
168  }
169  inline Vect2f &operator *= (const Vect2f &v) {
170  x *= v.x;
171  y *= v.y;
172  return *this;
173  }
174  inline Vect2f &operator /= (const Vect2f &v) {
175  x /= v.x;
176  y /= v.y;
177  return *this;
178  }
179  inline Vect2f &operator *= (float f) {
180  x *= f;
181  y *= f;
182  return *this;
183  }
184  inline Vect2f &operator /= (float f) {
185  if (f != 0.f) f = 1 / f;
186  else f = 0.0001f;
187  x *= f;
188  y *= f;
189  return *this;
190  }
191 
192  inline Vect2f operator + (const Vect2f &v) const {
193  return Vect2f(*this) += v;
194  }
195  inline Vect2f operator - (const Vect2f &v) const {
196  return Vect2f(*this) -= v;
197  }
198  inline Vect2f operator * (const Vect2f &v) const {
199  return Vect2f(*this) *= v;
200  }
201  inline Vect2f operator / (const Vect2f &v) const {
202  return Vect2f(*this) /= v;
203  }
204  inline Vect2f operator * (float f) const {
205  return Vect2f(*this) *= f;
206  }
207  inline Vect2f operator / (float f) const {
208  return Vect2f(*this) /= f;
209  }
210 
211  inline bool eq(const Vect2f &v, float delta = FLT_COMPARE_TOLERANCE) const {
212  return fabsf(v.x - x) < delta && fabsf(v.y - y) < delta;
213  }
214 
215  inline float dot(const Vect2f &v) const {
216  return x * v.x + y * v.y;
217  }
218  inline friend float dot(const Vect2f &u, const Vect2f &v) {
219  return u.dot(v);
220  }
221 
222  inline float operator % (const Vect2f &v) const {
223  return x * v.y - y * v.x;
224  }
225 
226  inline Vect2f &scaleAdd(const Vect2f &u, float lambda) {
227  x += lambda * u.x;
228  y += lambda * u.y;
229  return *this;
230  }
231 
232  inline Vect2f &interpolate(const Vect2f &u, const Vect2f &v, float lambda); // (1-lambda)*u + lambda*v
233 
234  inline float norm() const {
235  return sqrtf(x * x + y * y);
236  }
237  inline float norm2() const {
238  return x * x + y * y;
239  }
240  inline Vect2f &normalize(float norma) {
241  float f = norma * invSqrtFast(x * x + y * y);
242  x *= f;
243  y *= f;
244  return *this;
245  }
246  inline float distance(const Vect2f &v) const {
247  return sqrtf(distance2(v));
248  }
249  inline float distance2(const Vect2f &v) const {
250  float dx = x - v.x, dy = y - v.y;
251  return dx * dx + dy * dy;
252  }
253 
254  inline void swap(Vect2f &v) {
255  Vect2f tmp = v;
256  v = *this;
257  *this = tmp;
258  }
259 };
260 
261 
263 //
264 // class Vect2i
265 //
267 
268 class Vect2i {
269 public:
270  int x, y;
271 
272  inline Vect2i() { x = y = 0; }
273  inline Vect2i(int x_, int y_) {
274  x = x_;
275  y = y_;
276  }
277  inline Vect2i(float x_, float y_) {
278  x = round(x_);
279  y = round(y_);
280  }
281 
282  inline Vect2i(const Vect2f &v) {
283  x = round(v.x);
284  y = round(v.y);
285  }
286  inline Vect2i(const Vect2s &v);
287 
288  inline void set(int x_, int y_) {
289  x = x_;
290  y = y_;
291  }
292  inline void set(float x_, float y_) {
293  x = round(x_);
294  y = round(y_);
295  }
296  inline Vect2i operator - () const {
297  return Vect2i(-x, -y);
298  }
299 
300  inline const int &operator[](int i) const {
301  return *(&x + i);
302  }
303  inline int &operator[](int i) {
304  return *(&x + i);
305  }
306 
307  inline Vect2i &operator += (const Vect2i &v) {
308  x += v.x;
309  y += v.y;
310  return *this;
311  }
312  inline Vect2i &operator -= (const Vect2i &v) {
313  x -= v.x;
314  y -= v.y;
315  return *this;
316  }
317  inline Vect2i &operator *= (const Vect2i &v) {
318  x *= v.x;
319  y *= v.y;
320  return *this;
321  }
322  inline Vect2i &operator /= (const Vect2i &v) {
323  x /= v.x;
324  y /= v.y;
325  return *this;
326  }
327 
328  inline Vect2i operator + (const Vect2i &v) const {
329  return Vect2i(*this) += v;
330  }
331  inline Vect2i operator - (const Vect2i &v) const {
332  return Vect2i(*this) -= v;
333  }
334  inline Vect2i operator * (const Vect2i &v) const {
335  return Vect2i(*this) *= v;
336  }
337 
338  inline Vect2i &operator *= (int f) {
339  x *= f;
340  y *= f;
341  return *this;
342  }
343  inline Vect2i operator * (int f) const {
344  return Vect2i(*this) *= f;
345  }
346 
347  inline Vect2i &operator >>= (int n) {
348  x >>= n;
349  y >>= n;
350  return *this;
351  }
352  inline Vect2i operator >> (int n) const {
353  return Vect2i(*this) >>= n;
354  }
355 
356  inline Vect2i &operator *= (float f) {
357  x = round(x * f);
358  y = round(y * f);
359  return *this;
360  }
361  inline Vect2i &operator /= (float f) {
362  return *this *= 1.f / f;
363  }
364  inline Vect2i operator * (float f) const {
365  return Vect2i(*this) *= f;
366  }
367  inline Vect2i operator / (float f) const {
368  return Vect2i(*this) /= f;
369  }
370 
371  inline int dot(const Vect2i &v) const {
372  return x * v.x + y * v.y;
373  }
374  inline friend int dot(const Vect2i &u, const Vect2i &v) {
375  return u.dot(v);
376  }
377 
378  inline int operator % (const Vect2i &v) const {
379  return x * v.y - y * v.x;
380  }
381 
382  inline int norm() const {
383  return round(sqrtf(float(x * x + y * y)));
384  }
385  inline int norm2() const {
386  return x * x + y * y;
387  }
388 
389  inline void normalize(int norma) {
390  float f = (float)norma * invSqrtFast((float)(x * x + y * y));
391  x = round(x * f);
392  y = round(y * f);
393  }
394  inline int distance2(const Vect2i &v) const {
395  return sqr(x - v.x) + sqr(y - v.y);
396  }
397 
398  inline int operator == (const Vect2i &v) const {
399  return x == v.x && y == v.y;
400  }
401  inline int operator != (const Vect2i &v) const {
402  return x != v.x || y != v.y;
403  }
404 
405  inline void swap(Vect2i &v) {
406  Vect2i tmp = v;
407  v = *this;
408  *this = tmp;
409  }
410 };
411 
412 
414 //
415 // class Vect2s
416 //
418 
419 class Vect2s {
420 public:
421  int16 x, y;
422 
423  inline Vect2s() { x = y = 0; }
424  inline Vect2s(int x_, int y_) {
425  x = x_;
426  y = y_;
427  }
428 
429  inline Vect2s(const Vect2f &v) {
430  x = round(v.x);
431  y = round(v.y);
432  }
433  inline Vect2s(const Vect2i &v) {
434  x = v.x;
435  y = v.y;
436  }
437 
438  inline void set(int x_, int y_) {
439  x = x_;
440  y = y_;
441  }
442  inline Vect2s operator - () const {
443  return Vect2s(-x, -y);
444  }
445 
446  inline const int16 &operator[](int i) const {
447  return *(&x + i);
448  }
449  inline int16 &operator[](int i) {
450  return *(&x + i);
451  }
452 
453  inline Vect2s &operator += (const Vect2s &v) {
454  x += v.x;
455  y += v.y;
456  return *this;
457  }
458  inline Vect2s &operator -= (const Vect2s &v) {
459  x -= v.x;
460  y -= v.y;
461  return *this;
462  }
463  inline Vect2s &operator *= (const Vect2s &v) {
464  x *= v.x;
465  y *= v.y;
466  return *this;
467  }
468  inline Vect2s &operator *= (float f) {
469  x = round(x * f);
470  y = round(y * f);
471  return *this;
472  }
473  inline Vect2s &operator /= (float f) {
474  if (f != 0.f) f = 1 / f;
475  else f = 0.0001f;
476  x = round(x * f);
477  y = round(y * f);
478  return *this;
479  }
480  inline Vect2s operator - (const Vect2s &v) const {
481  return Vect2s(x - v.x, y - v.y);
482  }
483  inline Vect2s operator + (const Vect2s &v) const {
484  return Vect2s(x + v.x, y + v.y);
485  }
486  inline Vect2s operator * (const Vect2s &v) const {
487  return Vect2s(x * v.x, y * v.y);
488  }
489  inline Vect2s operator * (float f) const {
490  Vect2s tmp(round(x * f), round(y * f));
491  return tmp;
492  }
493  inline Vect2s operator / (float f) const {
494  if (f != 0.f) f = 1 / f;
495  else f = 0.0001f;
496  Vect2s tmp(round(x * f), round(y * f));
497  return tmp;
498  }
499 
500  inline int operator == (const Vect2s &v) const {
501  return x == v.x && y == v.y;
502  }
503 
504  inline int norm() const {
505  return round(sqrtf((float)(x * x + y * y)));
506  }
507  inline int norm2() const {
508  return x * x + y * y;
509  }
510  inline int distance(const Vect2s &v) const {
511  int dx = v.x - x, dy = v.y - y;
512  return round(sqrtf((float)(dx * dx + dy * dy)));
513  }
514  inline void normalize(int norma) {
515  float f = (float)norma * invSqrtFast((float)((int)x * x + (int)y * y));
516  x = round(x * f);
517  y = round(y * f);
518  }
519 
520  inline void swap(Vect2s &v) {
521  Vect2s tmp = v;
522  v = *this;
523  *this = tmp;
524  }
525 };
526 
528 //
529 // class Vect3f
530 //
532 
533 class Vect3f {
534 
535 public:
536  typedef float float3[3];
537 
538  float x, y, z;
539 
540  // constructors //////////////////////////////////////////////////////////////
541 
542  inline Vect3f() { x = y = z = 0.0;}
543  inline Vect3f(float x_, float y_, float z_) {
544  x = x_;
545  y = y_;
546  z = z_;
547  }
548  explicit inline Vect3f(const Vect2f &v, float z_ = 0) {
549  x = v.x;
550  y = v.y;
551  z = z_;
552  }
553 
554  inline Vect3f(const float3 &v) {
555  x = v[0];
556  y = v[1];
557  z = v[2];
558  }
559 
560  inline operator const Vect2f &() const {
561  return *reinterpret_cast<const Vect2f *>(this);
562  }
563 
564  // setters / accessors / translators /////////////////////////////////////////
565 
566  inline Vect3f &set(float x_, float y_, float z_) {
567  x = x_;
568  y = y_;
569  z = z_;
570  return *this;
571  }
572 
573  inline Vect3f &setSpherical(float psi, float theta, float radius);
574 
575  // index-based access: 0=x, 1=y, 2=z.
576  inline const float &operator[](int i) const {
577  return *(&x + i);
578  }
579  inline float &operator[](int i) {
580  return *(&x + i);
581  }
582 
583  // Fortran index-based access: 1=x, 2=y, 3=z.
584  inline const float &operator()(int i) const {
585  return *(&x + i - 1);
586  }
587  inline float &operator()(int i) {
588  return *(&x + i - 1);
589  }
590 
591  // Convertion to int ///////
592  inline int xi() const {
593  return round(x);
594  }
595  inline int yi() const {
596  return round(y);
597  }
598  inline int zi() const {
599  return round(z);
600  }
601 
602  // Negate ////////////////////////////////////
603  inline Vect3f operator- () const;
604  inline Vect3f &negate(const Vect3f &v);
605  inline Vect3f &negate();
606 
607  // Logical operations ////////////////////////////////
608  inline bool eq(const Vect3f &v, float delta = FLT_COMPARE_TOLERANCE) const;
609 
610  // Addition and substruction ////////////////////
611  inline Vect3f &add(const Vect3f &u, const Vect3f &v);
612  inline Vect3f &add(const Vect3f &v);
613  inline Vect3f &sub(const Vect3f &u, const Vect3f &v);
614  inline Vect3f &sub(const Vect3f &v);
615  inline Vect3f &operator+= (const Vect3f &v) {
616  return add(v);
617  }
618  inline Vect3f &operator-= (const Vect3f &v) {
619  return sub(v);
620  }
621  inline Vect3f operator+ (const Vect3f &v) const {
622  Vect3f u;
623  return u.add(*this, v);
624  }
625  inline Vect3f operator- (const Vect3f &v) const {
626  Vect3f u;
627  return u.sub(*this, v);
628  }
629 
630  // Component-wise multiplication and division ////////////////
631  inline Vect3f &mult(const Vect3f &u, const Vect3f &v);
632  inline Vect3f &mult(const Vect3f &v);
633  inline Vect3f &div(const Vect3f &u, const Vect3f &v);
634  inline Vect3f &div(const Vect3f &v);
635  inline Vect3f &operator*= (const Vect3f &v) {
636  return mult(v);
637  }
638  inline Vect3f &operator/= (const Vect3f &v) {
639  return div(v);
640  }
641  inline Vect3f operator* (const Vect3f &v) const {
642  Vect3f u;
643  return u.mult(*this, v);
644  }
645  inline Vect3f operator/ (const Vect3f &v) const {
646  Vect3f u;
647  return u.div(*this, v);
648  }
649 
650  // Cross product //////////////////////
651  inline Vect3f &cross(const Vect3f &u, const Vect3f &v);// u x v [!]
652  inline Vect3f &precross(const Vect3f &v); // v x this [!]
653  inline Vect3f &postcross(const Vect3f &v); // this x v [!]
654  inline Vect3f &operator%= (const Vect3f &v) {
655  return postcross(v); // this x v [!]
656  }
657  inline Vect3f operator% (const Vect3f &v) const {
658  Vect3f u;
659  return u.cross(*this, v);
660  }
661 
662  // Dot product //////////////////////
663  inline float dot(const Vect3f &other) const;
664  inline friend float dot(const Vect3f &u, const Vect3f &v) {
665  return u.dot(v);
666  }
667 
668  // Multiplication & division by scalar ///////////
669  inline Vect3f &scale(const Vect3f &v, float s);
670  inline Vect3f &scale(float s);
671 
672  inline Vect3f &operator*= (float s) {
673  return scale(s);
674  }
675  inline Vect3f &operator/= (float s) {
676  return scale(1 / s);
677  }
678  inline Vect3f operator* (float s) const {
679  Vect3f u;
680  return u.scale(*this, s);
681  }
682  inline Vect3f operator/ (float s) const {
683  Vect3f u;
684  return u.scale(*this, 1 / s);
685  }
686  inline friend Vect3f operator* (float s, const Vect3f &v) {
687  Vect3f u;
688  return u.scale(v, s);
689  }
690 
691  // Normalize ///////////////////////////
692  inline Vect3f &normalize(float r = 1.0f);
693  inline Vect3f &normalize(const Vect3f &v, float r = 1.0f);
694 
695  // Operation returning scalar ////////////
696  inline float norm() const;
697  inline float norm2() const; // norm^2
698  inline float distance(const Vect3f &other) const;
699  inline float distance2(const Vect3f &other) const; // distance^2
700 
701  inline float psi() const;
702  inline float theta() const;
703 
704  inline float min() const;
705  inline float max() const;
706  inline float minAbs() const;
707  inline float maxAbs() const;
708  inline float sumAbs() const; // |x| + |y| + |z|
709 
710 
711  // Composite functions ////////////////////////////////
712  inline Vect3f &crossAdd(const Vect3f &u, const Vect3f &v, const Vect3f &w); // u x v + w [!] this must be distinct from u and v, but not necessarily from w.
713  inline Vect3f &crossAdd(const Vect3f &u, const Vect3f &v); // u x v + this [!]
714  inline Vect3f &scaleAdd(const Vect3f &v, const Vect3f &u, float lambda); // v + lambda * u
715  inline Vect3f &scaleAdd(const Vect3f &u, float lambda);// this + lambda * u
716  inline Vect3f &interpolate(const Vect3f &u, const Vect3f &v, float lambda); // (1-lambda)*u + lambda*v
717 
718  // Swap /////////////////////////
719  inline void swap(Vect3f &other);
720  inline friend void swap(Vect3f &u, Vect3f &v) {
721  u.swap(v);
722  }
723 };
724 
725 
727 //
728 // Miscellaneous functions
729 //
731 // Decomposition ////////////////////////////////
732 inline void decomposition(const Vect3f &axis, const Vect3f &v, Vect3f &v_normal, Vect3f &v_tangent) {
733  // axis - axis of decomposition, v_normal - collinear to axis, v_tangent - perpendicular to axis
734  v_normal.scale(axis, dot(axis, v) / ((axis).norm2()));
735  v_tangent.sub(v, v_normal);
736 }
737 
738 
739 
747 
749 //
750 // Vect2 definitions
751 //
753 inline Vect2i::Vect2i(const Vect2s &v) {
754  x = v.x;
755  y = v.y;
756 }
757 inline Vect2f::Vect2f(const Vect2i &v) {
758  x = float(v.x);
759  y = float(v.y);
760 }
761 inline Vect2f::Vect2f(const Vect2s &v) {
762  x = v.x;
763  y = v.y;
764 }
765 
766 Vect2f &Vect2f::interpolate(const Vect2f &u, const Vect2f &v, float lambda) {
767  float lambda2 = 1.0f - lambda;
768 
769  x = lambda2 * u.x + lambda * v.x;
770  y = lambda2 * u.y + lambda * v.y;
771  return *this;
772 }
773 
775 //
776 // Vect3f inline definitions
777 //
779 
780 // Dot product //////////////////////
781 //inline double dot(const Vect3d& u, const Vect3f& v) { return u.dot(v); }
782 //inline float dot(const Vect3f& u, const Vect3d& v) { return u.dot(v); }
783 
784 bool Vect3f::eq(const Vect3f &other, float delta) const {
785  return fabs(x - other.x) < delta &&
786  fabs(y - other.y) < delta &&
787  fabs(z - other.z) < delta;
788 }
789 
790 Vect3f Vect3f::operator- () const {
791  return Vect3f(-x, -y, -z);
792 }
793 
794 // Norm operations /////////
795 float Vect3f::sumAbs() const {
796  return (float)(fabs(x) + fabs(y) + fabs(z));
797 }
798 
799 
800 // Descart - spherical function //////////////
801 float Vect3f::psi() const {
802  return (float)atan2(y, x);
803 }
804 float Vect3f::theta() const {
805  return (float)acos(z / (norm() + FLT_EPS));
806 }
807 Vect3f &Vect3f::setSpherical(float psi, float theta, float radius) {
808  x = radius * (float)sin(theta);
809  y = x * (float)sin(psi);
810  x = x * (float)cos(psi);
811  z = radius * (float)cos(theta);
812  return *this;
813 }
814 
815 float Vect3f::dot(const Vect3f &other) const {
816  return x * other.x + y * other.y + z * other.z;
817 }
818 
819 
820 float Vect3f::norm() const {
821  return (float)sqrt(x * x + y * y + z * z);
822 }
823 
824 
825 float Vect3f::norm2() const {
826  return (x * x + y * y + z * z);
827 }
828 
829 
830 float Vect3f::distance(const Vect3f &other) const {
831  Vect3f w;
832 
833  w.sub(other, *this);
834  return w.norm();
835 }
836 
837 
838 float Vect3f::distance2(const Vect3f &other) const {
839  Vect3f w;
840 
841  w.sub(other, *this);
842  return w.norm2();
843 }
844 
845 
846 float Vect3f::min() const {
847  return (x <= y) ? ((x <= z) ? x : z) : ((y <= z) ? y : z);
848 }
849 
850 
851 float Vect3f::max() const {
852  return (x >= y) ? ((x >= z) ? x : z) : ((y >= z) ? y : z);
853 }
854 
855 
856 float Vect3f::minAbs() const {
857  float ax, ay, az;
858 
859  ax = (float)fabs(x);
860  ay = (float)fabs(y);
861  az = (float)fabs(z);
862  return (ax <= ay) ? ((ax <= az) ? ax : az) : ((ay <= az) ? ay : az);
863 }
864 
865 
866 float Vect3f::maxAbs() const {
867  float ax, ay, az;
868 
869  ax = (float)fabs(x);
870  ay = (float)fabs(y);
871  az = (float)fabs(z);
872  return (ax >= ay) ? ((ax >= az) ? ax : az) : ((ay >= az) ? ay : az);
873 }
874 
875 
876 void Vect3f::swap(Vect3f &other) {
877  Vect3f tmp;
878 
879  tmp = *this;
880  *this = other;
881  other = tmp;
882 }
883 
884 
885 Vect3f &Vect3f::normalize(const Vect3f &v, float r) {
886  float s = r * invSqrtFast(v.x * v.x + v.y * v.y + v.z * v.z);
887  x = s * v.x;
888  y = s * v.y;
889  z = s * v.z;
890  return *this;
891 }
892 
893 
894 Vect3f &Vect3f::normalize(float r) {
895  float s = r * invSqrtFast(x * x + y * y + z * z);
896  x *= s;
897  y *= s;
898  z *= s;
899  return *this;
900 }
901 
902 Vect3f &Vect3f::negate(const Vect3f &v) {
903  x = - v.x;
904  y = - v.y;
905  z = - v.z;
906  return *this;
907 }
908 
909 
910 Vect3f &Vect3f::negate() {
911  x = - x;
912  y = - y;
913  z = - z;
914  return *this;
915 }
916 
917 
918 Vect3f &Vect3f::add(const Vect3f &u, const Vect3f &v) {
919  x = u.x + v.x;
920  y = u.y + v.y;
921  z = u.z + v.z;
922  return *this;
923 }
924 
925 
926 Vect3f &Vect3f::add(const Vect3f &v) {
927  x += v.x;
928  y += v.y;
929  z += v.z;
930  return *this;
931 }
932 
933 
934 Vect3f &Vect3f::sub(const Vect3f &u, const Vect3f &v) {
935  x = u.x - v.x;
936  y = u.y - v.y;
937  z = u.z - v.z;
938  return *this;
939 }
940 
941 
942 Vect3f &Vect3f::sub(const Vect3f &v) {
943  x -= v.x;
944  y -= v.y;
945  z -= v.z;
946  return *this;
947 }
948 
949 
950 Vect3f &Vect3f::mult(const Vect3f &u, const Vect3f &v) {
951  x = u.x * v.x;
952  y = u.y * v.y;
953  z = u.z * v.z;
954  return *this;
955 }
956 
957 
958 Vect3f &Vect3f::mult(const Vect3f &v) {
959  x *= v.x;
960  y *= v.y;
961  z *= v.z;
962  return *this;
963 }
964 
965 Vect3f &Vect3f::div(const Vect3f &u, const Vect3f &v) {
966  x = u.x / v.x;
967  y = u.y / v.y;
968  z = u.z / v.z;
969  return *this;
970 }
971 
972 
973 Vect3f &Vect3f::div(const Vect3f &v) {
974  x /= v.x;
975  y /= v.y;
976  z /= v.z;
977  return *this;
978 }
979 
980 
981 
982 Vect3f &Vect3f::scale(const Vect3f &v, float s) {
983  x = s * v.x;
984  y = s * v.y;
985  z = s * v.z;
986  return *this;
987 }
988 
989 
990 Vect3f &Vect3f::scale(float s) {
991  x *= s;
992  y *= s;
993  z *= s;
994  return *this;
995 }
996 
997 
998 
999 Vect3f &Vect3f::cross(const Vect3f &u, const Vect3f &v) {
1000  x = u.y * v.z - u.z * v.y;
1001  y = u.z * v.x - u.x * v.z;
1002  z = u.x * v.y - u.y * v.x;
1003  return *this;
1004 }
1005 
1006 
1007 Vect3f &Vect3f::precross(const Vect3f &v) {
1008  float ox, oy;
1009 
1010  ox = x;
1011  oy = y;
1012  x = v.y * z - v.z * oy;
1013  y = v.z * ox - v.x * z;
1014  z = v.x * oy - v.y * ox;
1015  return *this;
1016 }
1017 
1018 
1019 Vect3f &Vect3f::postcross(const Vect3f &v) {
1020  float ox, oy;
1021 
1022  ox = x;
1023  oy = y;
1024  x = oy * v.z - z * v.y;
1025  y = z * v.x - ox * v.z;
1026  z = ox * v.y - oy * v.x;
1027  return *this;
1028 }
1029 
1030 
1031 Vect3f &Vect3f::crossAdd(const Vect3f &u, const Vect3f &v, const Vect3f &w) {
1032  x = u.y * v.z - u.z * v.y + w.x;
1033  y = u.z * v.x - u.x * v.z + w.y;
1034  z = u.x * v.y - u.y * v.x + w.z;
1035  return *this;
1036 }
1037 
1038 
1039 Vect3f &Vect3f::crossAdd(const Vect3f &u, const Vect3f &v) {
1040  x += u.y * v.z - u.z * v.y;
1041  y += u.z * v.x - u.x * v.z;
1042  z += u.x * v.y - u.y * v.x;
1043  return *this;
1044 }
1045 
1046 
1047 Vect3f &Vect3f::scaleAdd(const Vect3f &v, const Vect3f &u, float lambda) {
1048  x = v.x + lambda * u.x;
1049  y = v.y + lambda * u.y;
1050  z = v.z + lambda * u.z;
1051  return *this;
1052 }
1053 
1054 
1055 Vect3f &Vect3f::scaleAdd(const Vect3f &u, float lambda) {
1056  x += lambda * u.x;
1057  y += lambda * u.y;
1058  z += lambda * u.z;
1059  return *this;
1060 }
1061 
1062 
1063 Vect3f &Vect3f::interpolate(const Vect3f &u, const Vect3f &v, float lambda) {
1064  float lambda2 = 1.0f - lambda;
1065 
1066  x = lambda2 * u.x + lambda * v.x;
1067  y = lambda2 * u.y + lambda * v.y;
1068  z = lambda2 * u.z + lambda * v.z;
1069  return *this;
1070 }
1071 
1072 } // namespace QDEngine
1073 
1074 #endif // QDENGINE_XMATH_H
Definition: xmath.h:117
Definition: xmath.h:419
Graphics::Surface * scale(const Graphics::Surface &srcImage, int xSize, int ySize)
Базовый класс для игровых ресурсов.
Definition: console.h:28
Definition: xmath.h:268
Definition: xmath.h:533