1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Quaternion.h
4 
5   Copyright (C)2009-2012 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 48334 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_QUATERNION_H_
17 #define NN_MATH_QUATERNION_H_
18 
19 #include <nn/math/math_Config.h>
20 
21 namespace nn {
22 namespace math {
23 
24 struct QUAT;
25 
26 /* Please see man pages for details
27 
28 
29 */
30 
31 /* ------------------------------------------------------------------------
32     Function for QUAT
33    ------------------------------------------------------------------------ */
34 /*
35 
36 
37 
38 
39 
40 
41 
42 
43  */
44 NN_MATH_INLINE QUAT* QUATAdd(QUAT* pOut, const QUAT* q1, const QUAT* q2);
45 
46 /*
47 
48 
49 
50 
51 
52 
53 
54 
55  */
56 NN_MATH_INLINE QUAT* QUATDivide(QUAT* pOut, const QUAT* q1, const QUAT* q2);
57 
58 /*
59 
60 
61 
62 
63 
64 
65  */
66 NN_MATH_INLINE f32   QUATDot(const QUAT* q1, const QUAT* q2);
67 
68 /*
69 
70 
71 
72 
73 
74 
75 
76 
77  */
78 NN_MATH_INLINE QUAT* QUATExp(QUAT* pOut, const QUAT* q);
79 
80 /*
81 
82 
83 
84 
85 
86 
87  */
88 NN_FORCE_INLINE QUAT* QUATInverse(QUAT* pOut, const QUAT* __restrict q);
89 
90 /*
91 
92 
93 
94 
95 
96 
97 
98 
99  */
100 NN_MATH_INLINE QUAT* QUATLerp(QUAT* pOut, const QUAT* q1, const QUAT* q2, f32 t);
101 
102 /*
103 
104 
105 
106 
107 
108 
109 
110  */
111 NN_MATH_INLINE QUAT* QUATLogN(QUAT* pOut, const QUAT* q);
112 
113 /*
114 
115 
116 
117 
118 
119 
120 
121  */
122 NN_MATH_INLINE QUAT* QUATMakeClosest( QUAT* pOut, const QUAT *q, const QUAT *qto );
123 
124 /*
125 
126 
127 
128 
129 
130 
131 
132  */
133 NN_FORCE_INLINE QUAT* QUATMult(QUAT* pOut, const QUAT* __restrict q1, const QUAT* __restrict q2);
134 
135 /*
136 
137 
138 
139 
140 
141 
142  */
143 NN_FORCE_INLINE QUAT* QUATNormalize(QUAT* pOut, const QUAT* __restrict q);
144 
145 /*
146 
147 
148 
149 
150 
151 
152 
153 
154  */
155 NN_MATH_INLINE QUAT* QUATScale(QUAT* pOut, const QUAT* q, f32 scale);
156 
157 /*
158 
159 
160 
161 
162 
163 
164 
165 
166  */
167 NN_MATH_INLINE QUAT* QUATSlerp(QUAT* pOut, const QUAT* q1, const QUAT* q2, f32 t);
168 
169 /*
170 
171 
172 
173 
174 
175 
176 
177 
178 
179 
180  */
181 NN_MATH_INLINE QUAT* QUATSquad(QUAT* pOut, const QUAT* p, const QUAT* a, const QUAT* b, const QUAT* q, f32 t);
182 
183 /*
184 
185 
186 
187 
188 
189 
190 
191 
192  */
193 NN_MATH_INLINE QUAT* QUATSub(QUAT* pOut, const QUAT* q1, const QUAT* q2);
194 
195 /*
196 
197 
198 
199 
200 
201 
202 
203 
204 
205  */
206 NN_MATH_INLINE QUAT* QUATRotAxisRad( QUAT* pOut, const VEC3 *axis, f32 rad );
207 
208 /*
209 
210 */
211 
212 /* ------------------------------------------------------------------------
213     QUAT
214    ------------------------------------------------------------------------ */
215 /*
216 
217 
218  */
219 struct QUAT_
220 {
221     f32 x;  //
222     f32 y;  //
223     f32 z;  //
224     f32 w;  //
225 };
226 
227 /*
228 
229 
230  */
231 class QUAT : public QUAT_
232 {
233 public:
234     typedef QUAT self_type;     //
235     typedef f32  value_type;    //
236 public:
237     //----------------------------------------
238     //
239     //
240     //
QUAT()241     QUAT() {}
242     //
QUAT(const f32 * p)243     explicit QUAT(const f32* p) { x = p[0]; y = p[1]; z = p[2]; w = p[3]; }
244     //
QUAT(const QUAT_ & rhs)245     QUAT(const QUAT_& rhs) { x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w; }
246     //
QUAT(f32 fx,f32 fy,f32 fz,f32 fw)247     QUAT(f32 fx, f32 fy, f32 fz, f32 fw) { x = fx; y = fy; z = fz; w = fw; }
248 
249     //
250 
251     //----------------------------------------
252     //
253     //
254 
255     //
256     operator f32*() { return &x; }
257     //
258     operator const f32*() const { return &x; }
259 #if 0
260     // The cast operator is put off because the function name is the same as DolphinSDK.
261     operator Quaternion*() { return (Quaternion*)&x; }
262     operator const Quaternion*() const { return (const Quaternion*)&x; }
263 #endif
264     //
265 
266     //----------------------------------------
267     //
268     //
269 
270     //
271     self_type& operator += (const self_type& rhs) { (void)QUATAdd(this, this, &rhs); return *this; }
272 
273     //
274     self_type& operator -= (const self_type& rhs) { (void)QUATSub(this, this, &rhs); return *this; }
275 
276     //
277     self_type& operator *= (f32 f) { (void)QUATScale(this, this, f); return *this; }
278 
279     //
280     self_type& operator /= (f32 f) { return operator*=(1.f / f); }
281 
282     //
283     self_type operator + () const { return *this; }
284 
285     //
286     self_type operator - () const { return self_type(-x, -y, -z, -w); }
287 
288     //
289     self_type operator + (const self_type& rhs) const { QUAT tmp; (void)QUATAdd(&tmp, this, &rhs); return tmp; }
290 
291     //
292     self_type operator - (const self_type& rhs) const { QUAT tmp; (void)QUATSub(&tmp, this, &rhs); return tmp; }
293 
294     //
295     self_type operator * (f32 f) const { QUAT tmp; (void)QUATScale(&tmp, this, f); return tmp; }
296 
297     //
298     self_type operator / (f32 f) const { return operator*(1.f / f); }
299 
300     //
301     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; }
302 
303     //
304     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w; }
305 
306     //
307 
308     //
309     void Report(bool bNewline = true, const char* name = NULL) const;
310 
311 private:
312     typedef void (self_type::*UnspecifiedBoolType)() const;
313     operator UnspecifiedBoolType() const;
314     operator UnspecifiedBoolType();
315 };
316 
317 //
318 //
319 
320 //
321 typedef class QUAT Quaternion;
322 
323 //
324 
325 inline QUAT
326 operator * (f32 f, const QUAT& rhs) { QUAT tmp; (void)QUATScale(&tmp, &rhs, f); return tmp; }
327 
328 }  // namespace math
329 }  // namespace nn
330 
331 #include <nn/math/ARMv6/math_Quaternion.h>
332 
333 namespace nn {
334 namespace math {
335 
336 NN_FORCE_INLINE QUAT*
QUATInverse(QUAT * pOut,const QUAT * __restrict q)337 QUATInverse(QUAT* pOut, const QUAT* __restrict q)
338 {
339 #if defined( NN_HARDWARE_CTR )
340     #if (QUATINVERSE_CONFIG == D_ORG)
341         return ARMv6::QUATInverseC( pOut, q );
342     #elif (QUATINVERSE_CONFIG == D_FAST_C)
343         return ARMv6::QUATInverseC_FAST( pOut, q);
344     #elif (QUATINVERSE_CONFIG == D_FAST_ASM)
345     #elif (QUATINVERSE_CONFIG == D_FAST_C_ALGO)
346     #elif (QUATINVERSE_CONFIG == D_FAST_ASM_ALGO)
347     #endif
348 #else
349 #endif // #if defined( NN_HARDWARE_CTR )
350 }
351 
352 NN_FORCE_INLINE QUAT*
QUATMult(QUAT * pOut,const QUAT * __restrict q1,const QUAT * __restrict q2)353 QUATMult(QUAT* pOut, const QUAT* __restrict q1, const QUAT* __restrict q2)
354 {
355 #if defined( NN_HARDWARE_CTR )
356     #if (QUATMULT_CONFIG == D_ORG)
357         return ARMv6::QUATMultC( pOut, q1, q2);
358     #elif (QUATMULT_CONFIG == D_FAST_C)
359         return ARMv6::QUATMultC_FAST( pOut, q1, q2);
360     #elif (QUATMULT_CONFIG == D_FAST_ASM)
361         return ARMv6::QUATMultAsm( pOut, q1, q2);
362     #elif (QUATMULT_CONFIG == D_FAST_C_ALGO)
363     #elif (QUATMULT_CONFIG == D_FAST_ASM_ALGO)
364     #endif
365 #else
366 #endif // #if defined( NN_HARDWARE_CTR )
367 }
368 
369 NN_FORCE_INLINE QUAT*
QUATNormalize(QUAT * pOut,const QUAT * __restrict q)370 QUATNormalize(QUAT* pOut, const QUAT* __restrict q)
371 {
372 #if defined( NN_HARDWARE_CTR )
373     #if (QUATNORMALIZE_CONFIG == D_ORG)
374         return ARMv6::QUATNormalizeC( pOut, q );
375     #elif (QUATNORMALIZE_CONFIG == D_FAST_C)
376         return ARMv6::QUATNormalizeC_FAST( pOut, q);
377     #elif (QUATNORMALIZE_CONFIG == D_FAST_ASM)
378     #elif (QUATNORMALIZE_CONFIG == D_FAST_C_ALGO)
379     #elif (QUATNORMALIZE_CONFIG == D_FAST_ASM_ALGO)
380     #endif
381 #else
382 #endif // #if defined( NN_HARDWARE_CTR )
383 }
384 
385 }  // namespace math
386 }  // namespace nn
387 
388 
389 #if defined(NN_MATH_AS_INLINE)
390 #include <nn/math/inline/math_Quaternion.ipp>
391 #include <nn/math/ARMv6/inline/math_Quaternion.ipp>
392 #endif
393 
394 namespace nn {
395 namespace math {
396 
397 //Overload referencing the -- const argument
QUATAdd(QUAT * pOut,const QUAT & q1,const QUAT & q2)398 inline QUAT* QUATAdd(QUAT* pOut, const QUAT& q1, const QUAT& q2) { return QUATAdd( pOut, &q1, &q2 ); }
QUATSub(QUAT * pOut,const QUAT & q1,const QUAT & q2)399 inline QUAT* QUATSub(QUAT* pOut, const QUAT& q1, const QUAT& q2) { return QUATSub( pOut, &q1, &q2 ); }
QUATDivide(QUAT * pOut,const QUAT & q1,const QUAT & q2)400 inline QUAT* QUATDivide(QUAT* pOut, const QUAT& q1, const QUAT& q2) { return QUATDivide( pOut, &q1, &q2 ); }
QUATMult(QUAT * pOut,const QUAT & q1,const QUAT & q2)401 inline QUAT* QUATMult(QUAT* pOut, const QUAT& q1, const QUAT& q2) { return QUATMult( pOut, &q1, &q2 ); }
QUATDot(const QUAT & q1,const QUAT & q2)402 inline f32   QUATDot(const QUAT& q1, const QUAT& q2) { return QUATDot( &q1, &q2 ); }
QUATInverse(QUAT * pOut,const QUAT & q)403 inline QUAT* QUATInverse(QUAT* pOut, const QUAT& q) { return QUATInverse( pOut, &q ); }
QUATScale(QUAT * pOut,const QUAT & q,f32 scale)404 inline QUAT* QUATScale(QUAT* pOut, const QUAT& q, f32 scale) { return QUATScale( pOut, &q, scale ); }
QUATNormalize(QUAT * pOut,const QUAT & q)405 inline QUAT* QUATNormalize(QUAT* pOut, const QUAT& q) { return QUATNormalize( pOut, &q ); }
QUATExp(QUAT * pOut,const QUAT & q)406 inline QUAT* QUATExp(QUAT* pOut, const QUAT& q) { return QUATExp( pOut, &q ); }
QUATLogN(QUAT * pOut,const QUAT & q)407 inline QUAT* QUATLogN(QUAT* pOut, const QUAT& q) { return QUATLogN( pOut, &q ); }
QUATLerp(QUAT * pOut,const QUAT & q1,const QUAT & q2,f32 t)408 inline QUAT* QUATLerp(QUAT* pOut, const QUAT& q1, const QUAT& q2, f32 t) { return QUATLerp( pOut, &q1, &q2, t ); }
QUATSlerp(QUAT * pOut,const QUAT & q1,const QUAT & q2,f32 t)409 inline QUAT* QUATSlerp(QUAT* pOut, const QUAT& q1, const QUAT& q2, f32 t) { return QUATSlerp( pOut, &q1, &q2, t ); }
QUATSquad(QUAT * pOut,const QUAT & p,const QUAT & a,const QUAT & b,const QUAT & q,f32 t)410 inline QUAT* QUATSquad(QUAT* pOut, const QUAT& p, const QUAT& a, const QUAT& b, const QUAT& q, f32 t) { return QUATSquad( pOut, &p, &a, &b, &q, t ); }
411 
QUATMakeClosest(QUAT * pOut,const QUAT & q,const QUAT & qto)412 inline QUAT* QUATMakeClosest( QUAT*  pOut, const QUAT& q, const QUAT& qto ) { return QUATMakeClosest( pOut, &q, &qto ); }
QUATRotAxisRad(QUAT * pOut,const VEC3 & axis,f32 rad)413 inline QUAT* QUATRotAxisRad( QUAT* pOut, const VEC3& axis, f32 rad ) { return QUATRotAxisRad( pOut, &axis, rad ); }
414 
415 }  // namespace math
416 }  // namespace nn
417 
418 
419 #endif // NN_MATH_QUATERNION_H_
420