SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
Quaternion.cpp
Go to the documentation of this file.
1#include <Math/Quaternion.hpp>
2#include <cmath>
3#include <Math/Matrix.hpp>
4
5namespace Sleak {
6 namespace Math {
7
8 // Constructors
9 Quaternion::Quaternion() : w(1.0f), x(0.0f), y(0.0f), z(0.0f) {}
10
11 Quaternion::Quaternion(float w, float x, float y, float z)
12 : w(w), x(x), y(y), z(z) {}
13
14 Quaternion::Quaternion(const Vector3D& axis, float angle) {
15 float halfAngle = angle / 2.0f;
16 float sinHalfAngle = sin(halfAngle);
17 axis.Normalized();
18 w = cos(halfAngle);
19 x = axis.GetX() * sinHalfAngle;
20 y = axis.GetY() * sinHalfAngle;
21 z = axis.GetZ() * sinHalfAngle;
22 }
23
25 float trace = matrix(0, 0) + matrix(1, 1) + matrix(2, 2);
26 if (trace > 0) {
27 float s = 0.5f / sqrt(trace + 1.0f);
28 w = 0.25f / s;
29 x = (matrix(2, 1) - matrix(1, 2)) * s;
30 y = (matrix(0, 2) - matrix(2, 0)) * s;
31 z = (matrix(1, 0) - matrix(0, 1)) * s;
32 } else {
33 if (matrix(0, 0) > matrix(1, 1) && matrix(0, 0) > matrix(2, 2)) {
34 float s = 2.0f * sqrt(1.0f + matrix(0, 0) - matrix(1, 1) - matrix(2, 2));
35 w = (matrix(2, 1) - matrix(1, 2)) / s;
36 x = 0.25f * s;
37 y = (matrix(0, 1) + matrix(1, 0)) / s;
38 z = (matrix(0, 2) + matrix(2, 0)) / s;
39 } else if (matrix(1, 1) > matrix(2, 2)) {
40 float s = 2.0f * sqrt(1.0f + matrix(1, 1) - matrix(0, 0) - matrix(2, 2));
41 w = (matrix(0, 2) - matrix(2, 0)) / s;
42 x = (matrix(0, 1) + matrix(1, 0)) / s;
43 y = 0.25f * s;
44 z = (matrix(1, 2) + matrix(2, 1)) / s;
45 } else {
46 float s = 2.0f * sqrt(1.0f + matrix(2, 2) - matrix(0, 0) - matrix(1, 1));
47 w = (matrix(1, 0) - matrix(0, 1)) / s;
48 x = (matrix(0, 2) + matrix(2, 0)) / s;
49 y = (matrix(1, 2) + matrix(2, 1)) / s;
50 z = 0.25f * s;
51 }
52 }
53 }
54
55 // Accessors and Mutators
56 float& Quaternion::operator[](int index) {
57 switch (index) {
58 case 0: return w;
59 case 1: return x;
60 case 2: return y;
61 case 3: return z;
62 default: throw IndexOutOfBoundsException("Quaternion index out of range");
63 }
64 }
65
66 const float& Quaternion::operator[](int index) const {
67 switch (index) {
68 case 0: return w;
69 case 1: return x;
70 case 2: return y;
71 case 3: return z;
72 default: throw IndexOutOfBoundsException("Quaternion index out of range");
73 }
74 }
75
76 // Quaternion Operations
78 return Quaternion(
79 w * other.w - x * other.x - y * other.y - z * other.z,
80 w * other.x + x * other.w + y * other.z - z * other.y,
81 w * other.y - x * other.z + y * other.w + z * other.x,
82 w * other.z + x * other.y - y * other.x + z * other.w
83 );
84 }
85
87 *this = *this * other;
88 return *this;
89 }
90
92 return Quaternion(-w, -x, -y, -z);
93 }
94
95 float Quaternion::GetX() const { return x; }
96 float Quaternion::GetY() const { return y; }
97 float Quaternion::GetZ() const { return z; }
98 float Quaternion::GetW() const { return w; }
99
100 // Normalize the quaternion
102 float magnitude = sqrt(w * w + x * x + y * y + z * z);
103 if (magnitude > 0.0f) {
104 w /= magnitude;
105 x /= magnitude;
106 y /= magnitude;
107 z /= magnitude;
108 }
109 }
110
111 // Calculate the magnitude of the quaternion
112 float Quaternion::magnitude() const {
113 return sqrt(w * w + x * x + y * y + z * z);
114 }
115
116 // Calculate the conjugate of the quaternion
118 return Quaternion(w, -x, -y, -z);
119 }
120
121 // Calculate the inverse of the quaternion
123 float magSq = w * w + x * x + y * y + z * z;
124 if (magSq > 0.0f) {
125 float invMagSq = 1.0f / magSq;
126 return Quaternion(w * invMagSq, -x * invMagSq, -y * invMagSq, -z * invMagSq);
127 }
128 return Quaternion();
129 }
130
131 // Rotate a vector by this quaternion
133 Quaternion qVec(0.0f, vec.GetX(), vec.GetY(), vec.GetZ());
134 Quaternion result = *this * qVec * inverse();
135 return Vector3D(result.x, result.y, result.z);
136 }
137
138 // Conversion to Rotation Matrix
140 Matrix4 matrix;
141 matrix(0, 0) = 1.0f - 2.0f * y * y - 2.0f * z * z;
142 matrix(0, 1) = 2.0f * x * y - 2.0f * w * z;
143 matrix(0, 2) = 2.0f * x * z + 2.0f * w * y;
144 matrix(0, 3) = 0.0f;
145
146 matrix(1, 0) = 2.0f * x * y + 2.0f * w * z;
147 matrix(1, 1) = 1.0f - 2.0f * x * x - 2.0f * z * z;
148 matrix(1, 2) = 2.0f * y * z - 2.0f * w * x;
149 matrix(1, 3) = 0.0f;
150
151 matrix(2, 0) = 2.0f * x * z - 2.0f * w * y;
152 matrix(2, 1) = 2.0f * y * z + 2.0f * w * x;
153 matrix(2, 2) = 1.0f - 2.0f * x * x - 2.0f * y * y;
154 matrix(2, 3) = 0.0f;
155
156 matrix(3, 0) = 0.0f;
157 matrix(3, 1) = 0.0f;
158 matrix(3, 2) = 0.0f;
159 matrix(3, 3) = 1.0f;
160
161 return matrix;
162 }
163
164 // Static method for look rotation
166 Vector3D f = forward.Normalize();
167 Vector3D r = f.Cross(up).Normalize();
168 Vector3D u = r.Cross(f);
169 u.Normalize();
170
171 Matrix4 rotationMatrix;
172 rotationMatrix(0, 0) = r.GetX(); rotationMatrix(0, 1) = r.GetY(); rotationMatrix(0, 2) = r.GetZ(); rotationMatrix(0, 3) = 0.0f;
173 rotationMatrix(1, 0) = u.GetX(); rotationMatrix(1, 1) = u.GetY(); rotationMatrix(1, 2) = u.GetZ(); rotationMatrix(1, 3) = 0.0f;
174 rotationMatrix(2, 0) = -f.GetX(); rotationMatrix(2, 1) = -f.GetY(); rotationMatrix(2, 2) = -f.GetZ(); rotationMatrix(2, 3) = 0.0f;
175 rotationMatrix(3, 0) = 0.0f; rotationMatrix(3, 1) = 0.0f; rotationMatrix(3, 2) = 0.0f; rotationMatrix(3, 3) = 1.0f;
176
177 return Quaternion(rotationMatrix);
178 }
179
180 // Free function for quaternion-vector multiplication
181 Vector3D operator*(const Quaternion& quat, const Vector3D& vec) {
182 Quaternion vecQuat(0, vec.GetX(), vec.GetY(), vec.GetZ());
183 Quaternion resultQuat = quat * vecQuat * quat.conjugate();
184 return Vector3D(resultQuat.x, resultQuat.y, resultQuat.z);
185 }
186
187 } // namespace Math
188} // namespace Sleak
Represents a quaternion for 3D rotations.
Quaternion operator*(const Quaternion &other) const
Quaternion conjugate() const
Quaternion & operator*=(const Quaternion &other)
Vector3D rotateVector(const Vector3D &vec) const
static Quaternion LookRotation(Vector3D &forward, Vector3D &up)
float & operator[](int index)
Matrix< float, 4, 4 > toRotationMatrix() const
Quaternion operator-() const
Quaternion inverse() const
float GetY() const
Definition Vector.hpp:361
float GetX() const
Definition Vector.hpp:360
Vector3D & Normalize()
Definition Vector.hpp:435
Vector3D Normalized() const
Definition Vector.hpp:454
float GetZ() const
Definition Vector.hpp:362
Vector3D Cross(const Vector3D &other) const
Definition Vector.hpp:421
Vectors, matrices, quaternions, colors, AABBs, and random helpers.
Vector3D operator*(const Quaternion &quat, const Vector3D &vec)
Matrix< float, 4, 4 > Matrix4
Definition Matrix.hpp:413
Root namespace for everything the engine exposes.
Definition Camera.hpp:10