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
27namespace QDEngine {
28
29class Archive;
30
31class Vect2f;
32class Vect2i;
33class Vect2s;
34class Vect3f;
35
36enum 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
54const double DBL_EPS = 1.e-15;
55const double DBL_INF = 1.e+100;
56const double DBL_COMPARE_TOLERANCE = 1.e-10;
57
58const float FLT_EPS = 1.192092896e-07f; //1.e-7f;
59const float FLT_INF = 1.e+30f;
60const float FLT_COMPARE_TOLERANCE = 1.e-5f;
61
62const int INT_INF = 0x7fffffff;
63
64inline 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
76inline float cycle(float f, float size) {
77 return fmod(fmod(f, size) + size, size);
78}
79
80inline 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
88inline float getDeltaAngle(float to, float from) {
89 return getDist(to, from, 2 * M_PI);
90}
91
92inline float cycleAngle(float a) {
93 return cycle(a, 2 * M_PI);
94}
95
96
98//
99// Scalar Functions
100//
102
103template <class T>
104inline 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
117class Vect2f {
118public:
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
268class Vect2i {
269public:
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
419class Vect2s {
420public:
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
533class Vect3f {
534
535public:
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 // Conversion 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 ////////////////////////////////
732inline 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//
753inline Vect2i::Vect2i(const Vect2s &v) {
754 x = v.x;
755 y = v.y;
756}
757inline Vect2f::Vect2f(const Vect2i &v) {
758 x = float(v.x);
759 y = float(v.y);
760}
761inline Vect2f::Vect2f(const Vect2s &v) {
762 x = v.x;
763 y = v.y;
764}
765
766Vect2f &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
784bool 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
790Vect3f Vect3f::operator- () const {
791 return Vect3f(-x, -y, -z);
792}
793
794// Norm operations /////////
795float Vect3f::sumAbs() const {
796 return (float)(fabs(x) + fabs(y) + fabs(z));
797}
798
799
800// Descart - spherical function //////////////
801float Vect3f::psi() const {
802 return (float)atan2(y, x);
803}
804float Vect3f::theta() const {
805 return (float)acos(z / (norm() + FLT_EPS));
806}
807Vect3f &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
815float Vect3f::dot(const Vect3f &other) const {
816 return x * other.x + y * other.y + z * other.z;
817}
818
819
820float Vect3f::norm() const {
821 return (float)sqrt(x * x + y * y + z * z);
822}
823
824
825float Vect3f::norm2() const {
826 return (x * x + y * y + z * z);
827}
828
829
830float Vect3f::distance(const Vect3f &other) const {
831 Vect3f w;
832
833 w.sub(other, *this);
834 return w.norm();
835}
836
837
838float Vect3f::distance2(const Vect3f &other) const {
839 Vect3f w;
840
841 w.sub(other, *this);
842 return w.norm2();
843}
844
845
846float Vect3f::min() const {
847 return (x <= y) ? ((x <= z) ? x : z) : ((y <= z) ? y : z);
848}
849
850
851float Vect3f::max() const {
852 return (x >= y) ? ((x >= z) ? x : z) : ((y >= z) ? y : z);
853}
854
855
856float 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
866float 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
876void Vect3f::swap(Vect3f &other) {
877 Vect3f tmp;
878
879 tmp = *this;
880 *this = other;
881 other = tmp;
882}
883
884
885Vect3f &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
894Vect3f &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
902Vect3f &Vect3f::negate(const Vect3f &v) {
903 x = - v.x;
904 y = - v.y;
905 z = - v.z;
906 return *this;
907}
908
909
910Vect3f &Vect3f::negate() {
911 x = - x;
912 y = - y;
913 z = - z;
914 return *this;
915}
916
917
918Vect3f &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
926Vect3f &Vect3f::add(const Vect3f &v) {
927 x += v.x;
928 y += v.y;
929 z += v.z;
930 return *this;
931}
932
933
934Vect3f &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
942Vect3f &Vect3f::sub(const Vect3f &v) {
943 x -= v.x;
944 y -= v.y;
945 z -= v.z;
946 return *this;
947}
948
949
950Vect3f &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
958Vect3f &Vect3f::mult(const Vect3f &v) {
959 x *= v.x;
960 y *= v.y;
961 z *= v.z;
962 return *this;
963}
964
965Vect3f &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
973Vect3f &Vect3f::div(const Vect3f &v) {
974 x /= v.x;
975 y /= v.y;
976 z /= v.z;
977 return *this;
978}
979
980
981
982Vect3f &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
990Vect3f &Vect3f::scale(float s) {
991 x *= s;
992 y *= s;
993 z *= s;
994 return *this;
995}
996
997
998
999Vect3f &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
1007Vect3f &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
1019Vect3f &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
1031Vect3f &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
1039Vect3f &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
1047Vect3f &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
1055Vect3f &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
1063Vect3f &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:268
Definition: xmath.h:419
Definition: xmath.h:533
Базовый класс для игровых ресурсов.
Definition: console.h:28