NW4F G3d
Loading...
Searching...
No Matches
g3d_Quaternion-inl.h
Go to the documentation of this file.
1#include <nw/g3d/math/g3d_MathCommon.h>
2#include <nw/g3d/math/g3d_Matrix34.h>
3
4namespace nw { namespace g3d { namespace math {
5
7Quat Quat::Make(float x, float y, float z, float w)
8{
9 return Quat().Set(x, y, z, w);
10}
11
13Quat* Quat::Cast(float* a)
14{
15 return reinterpret_cast<Quat*>(a);
16}
17
19const Quat* Quat::Cast(const float* a)
20{
21 return reinterpret_cast<const Quat*>(a);
22}
23
25Quat& Quat::Set(float x, float y, float z, float w)
26{
27 this->x = x;
28 this->y = y;
29 this->z = z;
30 this->w = w;
31 return *this;
32}
33
35Quat& Quat::Set(const float* a)
36{
38 for (int i = 0; i < DIM; ++i)
39 {
40 this->a[i] = a[i];
41 }
42 return *this;
43}
44
46Quat& Quat::Set(const Mtx34& m)
47{
48 float trace = m.m00 + m.m11 + m.m22;
49 float mag;
50 if (trace >= 0.0f)
51 {
52 w = Math::Sqrt(trace* 0.25f + 0.25f);
53 float s = Math::Rcp(w * 4.0f);
54 x = (m.m21 - m.m12) * s;
55 y = (m.m02 - m.m20) * s;
56 z = (m.m10 - m.m01) * s;
57 }
58 else if ((mag = 2.0f * m.m00 - trace) >= 0.0f)
59 {
60 x = Math::Sqrt(mag * 0.25f + 0.25f);
61 float s = Math::Rcp(x * 4.0f);
62 w = (m.m21 - m.m12) * s;
63 y = (m.m01 + m.m10) * s;
64 z = (m.m02 + m.m20) * s;
65 }
66 else if ((mag = 2.0f * m.m11 - trace) >= 0.0f)
67 {
68 y = Math::Sqrt(mag * 0.25f + 0.25f);
69 float s = Math::Rcp(y * 4.0f);
70 w = (m.m02 - m.m20) * s;
71 z = (m.m12 + m.m21) * s;
72 x = (m.m10 + m.m01) * s;
73 }
74 else
75 {
76 mag = 2.0f * m.m22 - trace;
77 z = Math::Sqrt(mag * 0.25f + 0.25f);
78 float s = Math::Rcp(z * 4.0f);
79 w = (m.m10 - m.m01) * s;
80 x = (m.m20 + m.m02) * s;
81 y = (m.m21 + m.m12) * s;
82 }
83 return *this;
84}
85
88{
89 for (int i = 0; i < DIM; ++i)
90 {
91 a[i] = 0.0f;
92 }
93 return *this;
94}
95
98{
99 Set(0.0f, 0.0f, 0.0f, 1.0f);
100 return *this;
101}
102
104Quat& Quat::Neg(const Quat& q)
105{
106#if defined( __ghs__ )
107 ps[0] = __PS_NEG(q.ps[0]);
108 ps[1] = __PS_NEG(q.ps[1]);
109#else
110 for (int i = 0; i < DIM; ++i)
111 {
112 a[i] = -q.a[i];
113 }
114#endif
115 return *this;
116}
117
118//--------------------------------------------------------------------------------------------------
119
121Quat& Quat::Add(const Quat& lhs, const Quat& rhs)
122{
123#if defined( __ghs__ )
124 ps[0] = __PS_ADD(lhs.ps[0], rhs.ps[0]);
125 ps[1] = __PS_ADD(lhs.ps[1], rhs.ps[1]);
126#else
127 for (int i = 0; i < DIM; ++i)
128 {
129 a[i] = lhs.a[i] + rhs.a[i];
130 }
131#endif
132 return *this;
133}
134
136Quat& Quat::Sub(const Quat& lhs, const Quat& rhs)
137{
138#if defined( __ghs__ )
139 ps[0] = __PS_SUB(lhs.ps[0], rhs.ps[0]);
140 ps[1] = __PS_SUB(lhs.ps[1], rhs.ps[1]);
141#else
142 for (int i = 0; i < DIM; ++i)
143 {
144 a[i] = lhs.a[i] - rhs.a[i];
145 }
146#endif
147 return *this;
148}
149
151Quat& Quat::Mul(const Quat& lhs, const Quat& rhs)
152{
153#if defined( __ghs__ )
154 const f32x2 axay = lhs.ps[0];
155 const f32x2 azaw = lhs.ps[1];
156 const f32x2 bxby = rhs.ps[0];
157 const f32x2 bzbw = rhs.ps[1];
158
159 const f32x2 AxAy = __PS_NEG(axay);
160 const f32x2 Axay = __PS_MERGE01(AxAy, axay);
161 const f32x2 AzAw = __PS_NEG(azaw);
162 const f32x2 Azaw = __PS_MERGE01(AzAw, azaw);
163
164 f32x2 oxy, ozw;
165
166 oxy = __PS_MULS0(azaw, bxby);
167 oxy = __PS_MADDS0(Axay, bzbw, oxy);
168 oxy = __PS_MERGE10(oxy, oxy);
169 oxy = __PS_MADDS1(Azaw, bxby, oxy);
170 oxy = __PS_MADDS1(axay, bzbw, oxy);
171
172 ozw = __PS_MULS0(AxAy, bxby);
173 ozw = __PS_MADDS0(Azaw, bzbw, ozw);
174 ozw = __PS_MERGE10(ozw, ozw);
175 ozw = __PS_MADDS1(azaw, bzbw, ozw);
176 ozw = __PS_SUB(ozw, __PS_MULS1(Axay, bxby));
177
178 ps[0] = oxy;
179 ps[1] = ozw;
180
181 return *this;
182#else
183 Quat out;
184 out.w = lhs.w * rhs.w - lhs.x * rhs.x - lhs.y * rhs.y - lhs.z * rhs.z;
185 out.x = lhs.w * rhs.x + lhs.x * rhs.w + lhs.y * rhs.z - lhs.z * rhs.y;
186 out.y = lhs.w * rhs.y - lhs.x * rhs.z + lhs.y * rhs.w + lhs.z * rhs.x;
187 out.z = lhs.w * rhs.z + lhs.x * rhs.y - lhs.y * rhs.x + lhs.z * rhs.w;
188 return *this = out;
189#endif
190}
191
193Quat& Quat::Mul(const Quat& lhs, float rhs)
194{
195#if defined( __ghs__ )
196 ps[0] = __PS_MULS0F(lhs.ps[0], rhs);
197 ps[1] = __PS_MULS0F(lhs.ps[1], rhs);
198#else
199 for (int i = 0; i < DIM; ++i)
200 {
201 a[i] = lhs.a[i] * rhs;
202 }
203#endif
204 return *this;
205}
206
208Quat& Quat::Div(const Quat& lhs, float rhs)
209{
210 float rcp = Math::Rcp(rhs);
211 this->Mul(lhs, rcp);
212 return *this;
213}
214
215//--------------------------------------------------------------------------------------------------
216
218float Quat::Length(const Quat& q)
219{
221}
222
224float Quat::LengthSq(const Quat& q)
225{
226 return Dot(q, q);
227}
228
230float Quat::Dot(const Quat& lhs, const Quat& rhs)
231{
232#if defined( __ghs__ )
233 f32x2 ps = __PS_MUL(lhs.ps[0], rhs.ps[0]);
234 ps = __PS_MADD(lhs.ps[1], rhs.ps[1], ps);
235 ps = __PS_SUM0(ps, ps, ps);
236 return ps[0];
237#else
238 return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z + lhs.w * rhs.w;
239#endif
240}
241
243float Quat::Normalize(const Quat& q)
244{
245 float lengthSq = LengthSq(q);
246 if (lengthSq > 0.0f)
247 {
248 float rcp = Math::RSqrt(lengthSq);
249 Mul(q, rcp);
250 return lengthSq * rcp;
251 }
252 return 0.0f;
253}
254
257{
258 this->x = -q.x;
259 this->y = -q.y;
260 this->z = -q.z;
261 this->w = q.w;
262 return *this;
263}
264
267{
268 float lengthSq = LengthSq(q);
269 if (lengthSq > 0.0f)
270 {
271 float rcp = Math::RSqrt(lengthSq);
272 Conjugate(q);
273 Mul(*this, rcp);
274 return *this;
275 }
276 Zero();
277 return *this;
278}
279
281Quat& Quat::Lerp(const Quat& q0, const Quat& q1, float t)
282{
283 Quat sub;
284 sub.Sub(q1, q0);
285#if defined( __ghs__ )
286 ps[0] = __PS_MADDS0F(sub.ps[0], t, q0.ps[0]);
287 ps[1] = __PS_MADDS0F(sub.ps[1], t, q0.ps[1]);
288#else
289 x = t * sub.x + q0.x;
290 y = t * sub.y + q0.y;
291 z = t * sub.z + q0.z;
292 w = t * sub.w + q0.w;
293#endif
294 return *this;
295}
296
298Quat& Quat::Slerp(const Quat& q0, const Quat& q1, float t)
299{
300 float cosTheta = Dot(q0, q1);
301 float t0;
302 float t1 = Math::Select(cosTheta, 1.0f, -1.0f);
303 cosTheta = Math::Abs(cosTheta);
304
305 if (cosTheta <= 0.99999f)
306 {
307 u32 theta = Math::AcosIdx(cosTheta);
308 float sinTheta = Math::SinIdx(theta);
309 float rcpSin = Math::Rcp(sinTheta);
310 u32 tTheta = static_cast<u32>(t * theta);
311 t0 = Math::SinIdx(theta - tTheta) * rcpSin;
312 t1 *= Math::SinIdx(tTheta) * rcpSin;
313 }
314 else
315 {
316 t0 = 1.0f - t;
317 t1 *= t;
318 }
319
320#if defined( __ghs__ )
321 ps[0] = __PS_MADDS0F(q0.ps[0], t0, __PS_MULS0F(q1.ps[0], t1));
322 ps[1] = __PS_MADDS0F(q0.ps[1], t0, __PS_MULS0F(q1.ps[1], t1));
323#else
324 x = t0 * q0.x + t1 * q1.x;
325 y = t0 * q0.y + t1 * q1.y;
326 z = t0 * q0.z + t1 * q1.z;
327 w = t0 * q0.w + t1 * q1.w;
328#endif
329 return *this;
330}
331
332} } } // namespace nw::g3d::math
Definition g3d_MathCommon.h:9
static float Sqrt(float x)
Definition g3d_MathCommon-inl.h:163
static float Abs(float x)
Definition g3d_MathCommon-inl.h:16
static float Select(float cond, float pos, float neg)
Definition g3d_MathCommon-inl.h:34
static float RSqrt(float x)
Definition g3d_MathCommon-inl.h:150
static float Rcp(float x)
Definition g3d_MathCommon-inl.h:139
Definition g3d_Matrix34.h:34
Definition g3d_Quaternion.h:28
static float Dot(const Quat &lhs, const Quat &rhs)
Definition g3d_Quaternion-inl.h:230
Quat & Lerp(const Quat &q0, const Quat &q1, float t)
Definition g3d_Quaternion-inl.h:281
Quat & Inverse(const Quat &q)
Definition g3d_Quaternion-inl.h:266
static const Quat * Cast(const float *a)
Definition g3d_Quaternion-inl.h:19
Quat & Zero()
Definition g3d_Quaternion-inl.h:87
Quat & Identity()
Definition g3d_Quaternion-inl.h:97
Quat & Conjugate(const Quat &q)
Definition g3d_Quaternion-inl.h:256
static float LengthSq(const Quat &q)
Definition g3d_Quaternion-inl.h:224
Quat & Div(const Quat &lhs, float rhs)
Definition g3d_Quaternion-inl.h:208
float Normalize(const Quat &q)
Definition g3d_Quaternion-inl.h:243
Quat & Set(const float *a)
Definition g3d_Quaternion-inl.h:35
Quat & Add(const Quat &lhs, const Quat &rhs)
Definition g3d_Quaternion-inl.h:121
Quat & Sub(const Quat &lhs, const Quat &rhs)
Definition g3d_Quaternion-inl.h:136
static Quat Make(float x, float y, float z, float w)
Definition g3d_Quaternion-inl.h:7
Quat & Set(const Mtx34 &m)
Definition g3d_Quaternion-inl.h:46
Quat & Set(float x, float y, float z, float w)
Definition g3d_Quaternion-inl.h:25
static Quat * Cast(float *a)
Definition g3d_Quaternion-inl.h:13
Quat & Slerp(const Quat &q0, const Quat &q1, float t)
Definition g3d_Quaternion-inl.h:298
static float Length(const Quat &q)
Definition g3d_Quaternion-inl.h:218
Quat & Mul(const Quat &lhs, const Quat &rhs)
Definition g3d_Quaternion-inl.h:151
Quat & Neg(const Quat &q)
Definition g3d_Quaternion-inl.h:104
Quat & Mul(const Quat &lhs, float rhs)
Definition g3d_Quaternion-inl.h:193
#define NW_G3D_ASSERT_NOT_NULL(exp)
Definition g3d_assert.h:20
#define NW_G3D_MATH_INLINE
Definition g3d_defs.h:69
Definition g3d_MathCommon.h:6
Definition g3d_GfxManage.cpp:10
@ DIM
Definition g3d_Quaternion.h:12
float a[4]
Definition g3d_Quaternion.h:20