2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
7 Lugaru 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 2 of the License, or
10 (at your option) any later version.
12 Lugaru 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.
17 You should have received a copy of the GNU General Public License
18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef _PHYSICSMATH_H_
22 #define _PHYSICSMATH_H_
26 #include "MacCompatibility.h"
28 //------------------------------------------------------------------------//
30 //------------------------------------------------------------------------//
32 float const pi = 3.14159265f;
33 float const g = -32.174f; // acceleration due to gravity, ft/s^2
34 float const rho = 0.0023769f; // desity of air at sea level, slugs/ft^3
35 float const tol = 0.0000000001f; // float type tolerance
38 //------------------------------------------------------------------------//
40 //------------------------------------------------------------------------//
41 inline float DegreesToRadians(float deg);
42 inline float RadiansToDegrees(float rad);
44 inline float DegreesToRadians(float deg)
46 return deg * pi / 180.0f;
49 inline float RadiansToDegrees(float rad)
51 return rad * 180.0f / pi;
54 //------------------------------------------------------------------------//
55 // Vector Class and vector functions
56 //------------------------------------------------------------------------//
65 Vector(float xi, float yi, float zi);
67 float Magnitude(void);
71 Vector& operator+=(Vector u); // vector addition
72 Vector& operator-=(Vector u); // vector subtraction
73 Vector& operator*=(float s); // scalar multiply
74 Vector& operator/=(float s); // scalar divide
76 Vector operator-(void);
80 inline Vector operator+(Vector u, Vector v);
81 inline Vector operator-(Vector u, Vector v);
82 inline Vector operator^(Vector u, Vector v);
83 inline float operator*(Vector u, Vector v);
84 inline Vector operator*(float s, Vector u);
85 inline Vector operator*(Vector u, float s);
86 inline Vector operator/(Vector u, float s);
87 inline float TripleScalarProduct(Vector u, Vector v, Vector w);
89 float fast_sqrt2 (register float arg);
90 float fast_sqrt2 (register float arg)
92 // Can replace with slower return std::sqrt(arg);
93 register float result;
95 if (arg == 0.0) return 0.0;
98 frsqrte result,arg // Calculate Square root
101 // Newton Rhapson iterations.
102 result = result + 0.5 * result * (1.0 - arg * result * result);
103 result = result + 0.5 * result * (1.0 - arg * result * result);
108 inline Vector::Vector(void)
115 inline Vector::Vector(float xi, float yi, float zi)
122 inline float Vector::Magnitude(void)
124 return (float) sqrt(x * x + y * y + z * z);
127 inline void Vector::Normalize(void)
129 float m = (float) sqrt(x * x + y * y + z * z);
144 inline void Vector::Reverse(void)
151 inline Vector& Vector::operator+=(Vector u)
159 inline Vector& Vector::operator-=(Vector u)
167 inline Vector& Vector::operator*=(float s)
175 inline Vector& Vector::operator/=(float s)
183 inline Vector Vector::operator-(void)
185 return Vector(-x, -y, -z);
189 inline Vector operator+(Vector u, Vector v)
191 return Vector(u.x + v.x, u.y + v.y, u.z + v.z);
194 inline Vector operator-(Vector u, Vector v)
196 return Vector(u.x - v.x, u.y - v.y, u.z - v.z);
199 // Vector cross product (u cross v)
200 inline Vector operator^(Vector u, Vector v)
202 return Vector( u.y * v.z - u.z * v.y,
203 -u.x * v.z + u.z * v.x,
204 u.x * v.y - u.y * v.x );
207 // Vector dot product
208 inline float operator*(Vector u, Vector v)
210 return (u.x * v.x + u.y * v.y + u.z * v.z);
213 inline Vector operator*(float s, Vector u)
215 return Vector(u.x * s, u.y * s, u.z * s);
218 inline Vector operator*(Vector u, float s)
220 return Vector(u.x * s, u.y * s, u.z * s);
223 inline Vector operator/(Vector u, float s)
225 return Vector(u.x / s, u.y / s, u.z / s);
228 // triple scalar product (u dot (v cross w))
229 inline float TripleScalarProduct(Vector u, Vector v, Vector w)
231 return float( (u.x * (v.y * w.z - v.z * w.y)) +
232 (u.y * (-v.x * w.z + v.z * w.x)) +
233 (u.z * (v.x * w.y - v.y * w.x)) );
240 //------------------------------------------------------------------------//
241 // Matrix Class and matrix functions
242 //------------------------------------------------------------------------//
247 // elements eij: i -> row, j -> column
248 float e11, e12, e13, e21, e22, e23, e31, e32, e33;
251 Matrix3x3( float r1c1, float r1c2, float r1c3,
252 float r2c1, float r2c2, float r2c3,
253 float r3c1, float r3c2, float r3c3 );
256 Matrix3x3 Transpose(void);
257 Matrix3x3 Inverse(void);
259 Matrix3x3& operator+=(Matrix3x3 m);
260 Matrix3x3& operator-=(Matrix3x3 m);
261 Matrix3x3& operator*=(float s);
262 Matrix3x3& operator/=(float s);
265 inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2);
266 inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2);
267 inline Matrix3x3 operator/(Matrix3x3 m, float s);
268 inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2);
269 inline Matrix3x3 operator*(Matrix3x3 m, float s);
270 inline Matrix3x3 operator*(float s, Matrix3x3 m);
271 inline Vector operator*(Matrix3x3 m, Vector u);
272 inline Vector operator*(Vector u, Matrix3x3 m);
278 inline Matrix3x3::Matrix3x3(void)
291 inline Matrix3x3::Matrix3x3( float r1c1, float r1c2, float r1c3,
292 float r2c1, float r2c2, float r2c3,
293 float r3c1, float r3c2, float r3c3 )
306 inline float Matrix3x3::det(void)
308 return e11 * e22 * e33 -
316 inline Matrix3x3 Matrix3x3::Transpose(void)
318 return Matrix3x3(e11, e21, e31, e12, e22, e32, e13, e23, e33);
321 inline Matrix3x3 Matrix3x3::Inverse(void)
323 float d = e11 * e22 * e33 -
333 return Matrix3x3( (e22 * e33 - e23 * e32) / d,
334 -(e12 * e33 - e13 * e32) / d,
335 (e12 * e23 - e13 * e22) / d,
336 -(e21 * e33 - e23 * e31) / d,
337 (e11 * e33 - e13 * e31) / d,
338 -(e11 * e23 - e13 * e21) / d,
339 (e21 * e32 - e22 * e31) / d,
340 -(e11 * e32 - e12 * e31) / d,
341 (e11 * e22 - e12 * e21) / d );
344 inline Matrix3x3& Matrix3x3::operator+=(Matrix3x3 m)
358 inline Matrix3x3& Matrix3x3::operator-=(Matrix3x3 m)
372 inline Matrix3x3& Matrix3x3::operator*=(float s)
386 inline Matrix3x3& Matrix3x3::operator/=(float s)
400 inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2)
402 return Matrix3x3( m1.e11 + m2.e11,
413 inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2)
415 return Matrix3x3( m1.e11 - m2.e11,
426 inline Matrix3x3 operator/(Matrix3x3 m, float s)
428 return Matrix3x3( m.e11 / s,
439 inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2)
441 return Matrix3x3( m1.e11 * m2.e11 + m1.e12 * m2.e21 + m1.e13 * m2.e31,
442 m1.e11 * m2.e12 + m1.e12 * m2.e22 + m1.e13 * m2.e32,
443 m1.e11 * m2.e13 + m1.e12 * m2.e23 + m1.e13 * m2.e33,
444 m1.e21 * m2.e11 + m1.e22 * m2.e21 + m1.e23 * m2.e31,
445 m1.e21 * m2.e12 + m1.e22 * m2.e22 + m1.e23 * m2.e32,
446 m1.e21 * m2.e13 + m1.e22 * m2.e23 + m1.e23 * m2.e33,
447 m1.e31 * m2.e11 + m1.e32 * m2.e21 + m1.e33 * m2.e31,
448 m1.e31 * m2.e12 + m1.e32 * m2.e22 + m1.e33 * m2.e32,
449 m1.e31 * m2.e13 + m1.e32 * m2.e23 + m1.e33 * m2.e33 );
452 inline Matrix3x3 operator*(Matrix3x3 m, float s)
454 return Matrix3x3( m.e11 * s,
465 inline Matrix3x3 operator*(float s, Matrix3x3 m)
467 return Matrix3x3( m.e11 * s,
478 inline Vector operator*(Matrix3x3 m, Vector u)
480 return Vector( m.e11 * u.x + m.e12 * u.y + m.e13 * u.z,
481 m.e21 * u.x + m.e22 * u.y + m.e23 * u.z,
482 m.e31 * u.x + m.e32 * u.y + m.e33 * u.z);
485 inline Vector operator*(Vector u, Matrix3x3 m)
487 return Vector( u.x * m.e11 + u.y * m.e21 + u.z * m.e31,
488 u.x * m.e12 + u.y * m.e22 + u.z * m.e32,
489 u.x * m.e13 + u.y * m.e23 + u.z * m.e33);
492 //------------------------------------------------------------------------//
493 // Quaternion Class and Quaternion functions
494 //------------------------------------------------------------------------//
499 float n; // number (scalar) part
500 Vector v; // vector part: v.x, v.y, v.z
503 Quaternion(float e0, float e1, float e2, float e3);
505 float Magnitude(void);
506 Vector GetVector(void);
507 float GetScalar(void);
508 Quaternion operator+=(Quaternion q);
509 Quaternion operator-=(Quaternion q);
510 Quaternion operator*=(float s);
511 Quaternion operator/=(float s);
512 Quaternion operator~(void) const {
513 return Quaternion(n, -v.x, -v.y, -v.z);
517 inline Quaternion operator+(Quaternion q1, Quaternion q2);
518 inline Quaternion operator-(Quaternion q1, Quaternion q2);
519 inline Quaternion operator*(Quaternion q1, Quaternion q2);
520 inline Quaternion operator*(Quaternion q, float s);
521 inline Quaternion operator*(float s, Quaternion q);
522 inline Quaternion operator*(Quaternion q, Vector v);
523 inline Quaternion operator*(Vector v, Quaternion q);
524 inline Quaternion operator/(Quaternion q, float s);
525 inline float QGetAngle(Quaternion q);
526 inline Vector QGetAxis(Quaternion q);
527 inline Quaternion QRotate(Quaternion q1, Quaternion q2);
528 inline Vector QVRotate(Quaternion q, Vector v);
529 inline Quaternion MakeQFromEulerAngles(float x, float y, float z);
530 inline Vector MakeEulerAnglesFromQ(Quaternion q);
533 inline Quaternion::Quaternion(void)
541 inline Quaternion::Quaternion(float e0, float e1, float e2, float e3)
549 inline float Quaternion::Magnitude(void)
551 return (float) sqrt(n * n + v.x * v.x + v.y * v.y + v.z * v.z);
554 inline Vector Quaternion::GetVector(void)
556 return Vector(v.x, v.y, v.z);
559 inline float Quaternion::GetScalar(void)
564 inline Quaternion Quaternion::operator+=(Quaternion q)
573 inline Quaternion Quaternion::operator-=(Quaternion q)
582 inline Quaternion Quaternion::operator*=(float s)
591 inline Quaternion Quaternion::operator/=(float s)
600 /*inline Quaternion Quaternion::operator~()
602 return Quaternion(n, -v.x, -v.y, -v.z);
605 inline Quaternion operator+(Quaternion q1, Quaternion q2)
607 return Quaternion( q1.n + q2.n,
613 inline Quaternion operator-(Quaternion q1, Quaternion q2)
615 return Quaternion( q1.n - q2.n,
621 inline Quaternion operator*(Quaternion q1, Quaternion q2)
623 return Quaternion( q1.n * q2.n - q1.v.x * q2.v.x - q1.v.y * q2.v.y - q1.v.z * q2.v.z,
624 q1.n * q2.v.x + q1.v.x * q2.n + q1.v.y * q2.v.z - q1.v.z * q2.v.y,
625 q1.n * q2.v.y + q1.v.y * q2.n + q1.v.z * q2.v.x - q1.v.x * q2.v.z,
626 q1.n * q2.v.z + q1.v.z * q2.n + q1.v.x * q2.v.y - q1.v.y * q2.v.x);
629 inline Quaternion operator*(Quaternion q, float s)
631 return Quaternion(q.n * s, q.v.x * s, q.v.y * s, q.v.z * s);
634 inline Quaternion operator*(float s, Quaternion q)
636 return Quaternion(q.n * s, q.v.x * s, q.v.y * s, q.v.z * s);
639 inline Quaternion operator*(Quaternion q, Vector v)
641 return Quaternion( -(q.v.x * v.x + q.v.y * v.y + q.v.z * v.z),
642 q.n * v.x + q.v.y * v.z - q.v.z * v.y,
643 q.n * v.y + q.v.z * v.x - q.v.x * v.z,
644 q.n * v.z + q.v.x * v.y - q.v.y * v.x);
647 inline Quaternion operator*(Vector v, Quaternion q)
649 return Quaternion( -(q.v.x * v.x + q.v.y * v.y + q.v.z * v.z),
650 q.n * v.x + q.v.z * v.y - q.v.y * v.z,
651 q.n * v.y + q.v.x * v.z - q.v.z * v.x,
652 q.n * v.z + q.v.y * v.x - q.v.x * v.y);
655 inline Quaternion operator/(Quaternion q, float s)
657 return Quaternion(q.n / s, q.v.x / s, q.v.y / s, q.v.z / s);
660 inline float QGetAngle(Quaternion q)
662 return (float) (2 * acosf(q.n));
665 inline Vector QGetAxis(Quaternion q)
679 inline Quaternion QRotate(Quaternion q1, Quaternion q2)
681 return q1 * q2 * (~q1);
684 inline Vector QVRotate(Quaternion q, Vector v)
691 return t.GetVector();
694 inline Quaternion MakeQFromEulerAngles(float x, float y, float z)
697 double roll = DegreesToRadians(x);
698 double pitch = DegreesToRadians(y);
699 double yaw = DegreesToRadians(z);
701 double cyaw, cpitch, croll, syaw, spitch, sroll;
702 double cyawcpitch, syawspitch, cyawspitch, syawcpitch;
704 cyaw = cos(0.5f * yaw);
705 cpitch = cos(0.5f * pitch);
706 croll = cos(0.5f * roll);
707 syaw = sin(0.5f * yaw);
708 spitch = sin(0.5f * pitch);
709 sroll = sin(0.5f * roll);
711 cyawcpitch = cyaw * cpitch;
712 syawspitch = syaw * spitch;
713 cyawspitch = cyaw * spitch;
714 syawcpitch = syaw * cpitch;
716 q.n = (float) (cyawcpitch * croll + syawspitch * sroll);
717 q.v.x = (float) (cyawcpitch * sroll - syawspitch * croll);
718 q.v.y = (float) (cyawspitch * croll + syawcpitch * sroll);
719 q.v.z = (float) (syawcpitch * croll - cyawspitch * sroll);
724 inline Vector MakeEulerAnglesFromQ(Quaternion q)
726 double r11, r21, r31, r32, r33;
727 double q00, q11, q22, q33;
736 r11 = q00 + q11 - q22 - q33;
737 r21 = 2 * (q.v.x * q.v.y + q.n * q.v.z);
738 r31 = 2 * (q.v.x * q.v.z - q.n * q.v.y);
739 r32 = 2 * (q.v.y * q.v.z + q.n * q.v.x);
740 r33 = q00 - q11 - q22 + q33;
743 if (tmp > 0.999999) {
744 double r12 = 2 * (q.v.x * q.v.y - q.n * q.v.z);
745 double r13 = 2 * (q.v.x * q.v.z + q.n * q.v.y);
747 u.x = RadiansToDegrees(0.0f); //roll
748 u.y = RadiansToDegrees((float) (-(pi / 2) * r31 / tmp)); // pitch
749 u.z = RadiansToDegrees((float) atan2(-r12, -r31 * r13)); // yaw
753 u.x = RadiansToDegrees((float) atan2(r32, r33)); // roll
754 u.y = RadiansToDegrees((float) asinf(-r31)); // pitch
755 u.z = RadiansToDegrees((float) atan2(r21, r11)); // yaw