A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
Quat.cc
1#include "Quat.hh"
2
3namespace EGG {
4
7void Quatf::setRPY(const Vector3f &rpy) {
8 *this = FromRPY(rpy.x, rpy.y, rpy.z);
9}
10
12void Quatf::setRPY(f32 r, f32 p, f32 y) {
13 const f32 cy = Mathf::cos(y * 0.5f);
14 const f32 cp = Mathf::cos(p * 0.5f);
15 const f32 cr = Mathf::cos(r * 0.5f);
16 const f32 sy = Mathf::sin(y * 0.5f);
17 const f32 sp = Mathf::sin(p * 0.5f);
18 const f32 sr = Mathf::sin(r * 0.5f);
19
20 w = cy * cp * cr + sy * sp * sr;
21 v.x = cy * cp * sr - sy * sp * cr;
22 v.y = cy * sp * cr + sy * cp * sr;
23 v.z = sy * cp * cr - cy * sp * sr;
24}
25
29 f32 len = squaredNorm() > std::numeric_limits<f32>::epsilon() ? norm() : 0.0f;
30
31 if (len != 0.0f) {
32 f32 inv = 1.0f / len;
33 w *= inv;
34 v *= inv;
35 }
36}
37
40void Quatf::makeVectorRotation(const Vector3f &from, const Vector3f &to) {
41 f32 t0 = std::max(0.0f, (from.dot(to) + 1) * 2.0f);
42 t0 = Mathf::sqrt(t0);
43
44 if (t0 <= std::numeric_limits<f32>::epsilon()) {
45 *this = Quatf::ident;
46 } else {
47 const f32 inv = 1.0f / t0;
48 w = t0 * 0.5f;
49 v = from.cross(to) * inv;
50 }
51}
52
56 Quatf conj = conjugate();
57 Quatf res = *this * vec;
58 Quatf ret;
59
60 ret.v.x = (res.v.y * conj.v.z + (res.v.x * conj.w + res.w * conj.v.x)) - res.v.z * conj.v.y;
61 ret.v.y = (res.v.z * conj.v.x + (res.v.y * conj.w + res.w * conj.v.y)) - res.v.x * conj.v.z;
62 ret.v.z = (res.v.x * conj.v.y + (res.v.z * conj.w + res.w * conj.v.z)) - res.v.y * conj.v.x;
63
64 return ret.v;
65}
66
70 Quatf conj = conjugate();
71 Quatf res = conj * vec;
72 Quatf ret;
73
74 ret.v.x = (res.v.y * v.z + (res.v.x * w + res.w * v.x)) - res.v.z * v.y;
75 ret.v.y = (res.v.z * v.x + (res.v.y * w + res.w * v.y)) - res.v.x * v.z;
76 ret.v.z = (res.v.x * v.y + (res.v.z * w + res.w * v.z)) - res.v.y * v.x;
77
78 return ret.v;
79}
80
84Quatf Quatf::slerpTo(const Quatf &q1, f32 t) const {
85 f32 dot_ = std::max(-1.0f, std::min(1.0f, dot(q1)));
86 bool bDot = dot_ < 0.0f;
87 dot_ = Mathf::abs(dot_);
88
89 f32 acos = Mathf::acos(dot_);
90 f32 sin = Mathf::sin(acos);
91
92 f32 s;
93 if (Mathf::abs(sin) < 0.00001f) {
94 s = 1.0f - t;
95 } else {
96 f32 invSin = 1.0f / sin;
97 f32 tmp0 = t * acos;
98 s = invSin * Mathf::sin(acos - tmp0);
99 t = invSin * Mathf::sin(tmp0);
100 }
101
102 if (bDot) {
103 t = -t;
104 }
105
106 return Quatf(s * w + t * q1.w, s * v + t * q1.v);
107}
108
111void Quatf::setAxisRotation(f32 angle, const EGG::Vector3f &axis) {
112 const f32 half_angle = angle * 0.5f;
113 const f32 c = Mathf::cos(half_angle);
114 const f32 s = Mathf::sin(half_angle);
115
116 w = c;
117 v = axis * s;
118}
119
120Quatf Quatf::multSwap(const Vector3f &vec) const {
121 f32 _w = -(v.dot(vec));
122 f32 _x = (w * vec.x + v.y * vec.z) - v.z * vec.y;
123 f32 _y = (w * vec.y + v.z * vec.x) - v.x * vec.z;
124 f32 _z = (w * vec.z + v.x * vec.y) - v.y * vec.x;
125
126 return Quatf(_w, _x, _y, _z);
127}
128
129Quatf Quatf::multSwap(const Quatf &q) const {
130 f32 _w = ((w * q.w - v.x * q.v.x) - v.y * q.v.y) - v.z * q.v.z;
131 f32 _x = (v.y * q.v.z + (v.x * q.w + w * q.v.x)) - v.z * q.v.y;
132 f32 _y = (v.z * q.v.x + (v.y * q.w + w * q.v.y)) - v.x * q.v.z;
133 f32 _z = (v.x * q.v.y + (v.z * q.w + w * q.v.z)) - v.y * q.v.x;
134
135 return Quatf(_w, _x, _y, _z);
136}
137
138void Quatf::read(Stream &stream) {
139 v.read(stream);
140 w = stream.read_f32();
141}
142
143Quatf Quatf::FromRPY(const EGG::Vector3f &rpy) {
144 Quatf ret;
145 ret.setRPY(rpy);
146 return ret;
147}
148
150Quatf Quatf::FromRPY(f32 r, f32 p, f32 y) {
151 Quatf ret;
152 ret.setRPY(r, p, y);
153 return ret;
154}
155
156} // namespace EGG
static f32 sin(f32 x)
Definition Math.hh:34
static f32 cos(f32 x)
Definition Math.hh:40
EGG core library.
Definition Archive.cc:6
A quaternion, used to represent 3D rotation.
Definition Quat.hh:12
void normalise()
Scales the quaternion to a unit length.
Definition Quat.cc:28
Vector3f rotateVector(const Vector3f &vec) const
Rotates a vector based on the quat.
Definition Quat.cc:55
f32 squaredNorm() const
Computes .
Definition Quat.hh:97
Quatf slerpTo(const Quatf &q2, f32 t) const
Performs spherical linear interpolation.
Definition Quat.cc:84
void setAxisRotation(f32 angle, const Vector3f &axis)
Set the quat given angle and axis.
Definition Quat.cc:111
f32 dot(const Quatf &q) const
Computes .
Definition Quat.hh:107
Vector3f rotateVectorInv(const Vector3f &vec) const
Rotates a vector on the inverse quat.
Definition Quat.cc:69
void setRPY(const Vector3f &rpy)
Sets roll, pitch, and yaw.
Definition Quat.cc:7
Quatf conjugate() const
Computes .
Definition Quat.hh:87
void makeVectorRotation(const Vector3f &from, const Vector3f &to)
Captures rotation between two vectors.
Definition Quat.cc:40
A 3D float vector.
Definition Vector.hh:87
f32 dot(const Vector3f &rhs) const
The dot product between two vectors.
Definition Vector.hh:186
void read(Stream &stream)
Initializes a Vector3f by reading 12 bytes from the stream.
Definition Vector.cc:115