1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Quaternion.h
4 
5   Copyright (C)2009-2010 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   $Revision: 24529 $
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 /* ------------------------------------------------------------------------
25     QUAT用の関数
26    ------------------------------------------------------------------------ */
27 struct QUAT;
28 
29 NN_MATH_INLINE QUAT* QUATAdd(QUAT* pOut, const QUAT* q1, const QUAT* q2);
30 NN_MATH_INLINE QUAT* QUATSub(QUAT* pOut, const QUAT* q1, const QUAT* q2);
31 NN_MATH_INLINE QUAT* QUATDivide(QUAT* pOut, const QUAT* q1, const QUAT* q2);
32 NN_MATH_INLINE QUAT* QUATMult(QUAT* pOut, const QUAT* q1, const QUAT* q2);
33 NN_MATH_INLINE f32   QUATDot(const QUAT* q1, const QUAT* q2);
34 NN_MATH_INLINE QUAT* QUATInverse(QUAT* pOut, const QUAT* q);
35 NN_MATH_INLINE QUAT* QUATScale(QUAT* pOut, const QUAT* q, f32 scale);
36 NN_MATH_INLINE QUAT* QUATNormalize(QUAT* pOut, const QUAT* q);
37 NN_MATH_INLINE QUAT* QUATExp(QUAT* pOut, const QUAT* q);
38 NN_MATH_INLINE QUAT* QUATLogN(QUAT* pOut, const QUAT* q);
39 NN_MATH_INLINE QUAT* QUATLerp(QUAT* pOut, const QUAT* q1, const QUAT* q2, f32 t);
40 NN_MATH_INLINE QUAT* QUATSlerp(QUAT* pOut, const QUAT* q1, const QUAT* q2, f32 t);
41 NN_MATH_INLINE QUAT* MTX34ToQUAT(QUAT* pOut, const MTX34* pMtx);
42 NN_MATH_INLINE QUAT* QUATSquad(QUAT* pOut, const QUAT* p, const QUAT* a, const QUAT* b, const QUAT* q, f32 t);
43 
44 NN_MATH_INLINE QUAT* QUATMakeClosest( QUAT* pOut, const QUAT *q, const QUAT *qto );
45 NN_MATH_INLINE QUAT* QUATRotAxisRad( QUAT* pOut, const VEC3 *axis, f32 rad );
46 
47 
48 NN_FORCE_INLINE QUAT* QUATInverse(QUAT* pOut, const QUAT* __restrict q);
49 NN_FORCE_INLINE QUAT* QUATMult(QUAT* pOut, const QUAT* __restrict q1, const QUAT* __restrict q2);
50 NN_FORCE_INLINE QUAT* QUATNormalize(QUAT* pOut, const QUAT* __restrict q);
51 
52 /* ------------------------------------------------------------------------
53     QUAT
54    ------------------------------------------------------------------------ */
55 struct QUAT_
56 {
57     f32 x;
58     f32 y;
59     f32 z;
60     f32 w;
61 };
62 
63 struct QUAT : public QUAT_
64 {
65 public:
66     typedef QUAT self_type;
67     typedef f32  value_type;
68 public:
QUATQUAT69     QUAT() {}
QUATQUAT70     QUAT(const f32* p) { x = p[0]; y = p[1]; z = p[2]; w = p[3]; }
QUATQUAT71     QUAT(const QUAT_& rhs) { x = rhs.x; y = rhs.y; z = rhs.z; w = rhs.w; }
QUATQUAT72     QUAT(f32 fx, f32 fy, f32 fz, f32 fw) { x = fx; y = fy; z = fz; w = fw; }
73 
74     operator f32*() { return &x; }
75     operator const f32*() const { return &x; }
76 #if 0
77     // 関数名がDolphinSDKと同じになるのでキャスト演算子は見合わせる
78     operator Quaternion*() { return (Quaternion*)&x; }
79     operator const Quaternion*() const { return (const Quaternion*)&x; }
80 #endif
81 
82     self_type& operator += (const self_type& rhs) { (void)QUATAdd(this, this, &rhs); return *this; }
83     self_type& operator -= (const self_type& rhs) { (void)QUATSub(this, this, &rhs); return *this; }
84     self_type& operator *= (f32 f) { (void)QUATScale(this, this, f); return *this; }
85     self_type& operator /= (f32 f) { return operator*=(1.f / f); }
86 
87     self_type operator + () const { return *this; }
88     self_type operator - () const { return self_type(-x, -y, -z, -w); }
89 
90     self_type operator + (const self_type& rhs) const { QUAT tmp; (void)QUATAdd(&tmp, this, &rhs); return tmp; }
91     self_type operator - (const self_type& rhs) const { QUAT tmp; (void)QUATSub(&tmp, this, &rhs); return tmp; }
92     self_type operator * (f32 f) const { QUAT tmp; (void)QUATScale(&tmp, this, f); return tmp; }
93     self_type operator / (f32 f) const { return operator*(1.f / f); }
94 
95     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; }
96     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w; }
97 
98     void Report(bool bNewline = true, const char* name = NULL) const;
99 };
100 
101 typedef struct QUAT Quaternion;
102 
103 inline QUAT
104 operator * (f32 f, const QUAT& rhs) { QUAT tmp; (void)QUATScale(&tmp, &rhs, f); return tmp; }
105 
106 }  // namespace math
107 }  // namespace nn
108 
109 #include <nn/math/ARMv6/math_Quaternion.h>
110 
111 namespace nn {
112 namespace math {
113 
114 /*!
115     @name    クォータニオン
116     @{
117 */
118 
119 /*!--------------------------------------------------------------------------*
120   @brief        クォータニオンの逆数を計算します。
121 
122   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。q と同じクォータニオンを指していても構いません。
123   @param[in]    q     左辺値へのポインタ
124 
125   @return       pOut を返します。
126  *---------------------------------------------------------------------------*/
127 NN_FORCE_INLINE QUAT*
QUATInverse(QUAT * pOut,const QUAT * __restrict q)128 QUATInverse(QUAT* pOut, const QUAT* __restrict q)
129 {
130 #if defined( NN_HARDWARE_CTR )
131     #if (QUATINVERSE_CONFIG == D_ORG)
132         return ARMv6::QUATInverseC( pOut, q );
133     #elif (QUATINVERSE_CONFIG == D_FAST_C)
134         return ARMv6::QUATInverseC_FAST( pOut, q);
135     #elif (QUATINVERSE_CONFIG == D_FAST_ASM)
136     #elif (QUATINVERSE_CONFIG == D_FAST_C_ALGO)
137     #elif (QUATINVERSE_CONFIG == D_FAST_ASM_ALGO)
138     #endif
139 #else
140 #endif // #if defined( NN_HARDWARE_CTR )
141 }
142 
143 /*!--------------------------------------------------------------------------*
144   @brief        クォータニオンの積を計算します。
145 
146   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。q1, q2 と同じクォータニオンを指していても構いません。
147   @param[in]    q1    左辺値へのポインタ
148   @param[in]    q2    右辺値へのポインタ
149 
150   @return       pOut を返します。
151  *---------------------------------------------------------------------------*/
152 NN_FORCE_INLINE QUAT*
QUATMult(QUAT * pOut,const QUAT * __restrict q1,const QUAT * __restrict q2)153 QUATMult(QUAT* pOut, const QUAT* __restrict q1, const QUAT* __restrict q2)
154 {
155 #if defined( NN_HARDWARE_CTR )
156     #if (QUATMULT_CONFIG == D_ORG)
157         return ARMv6::QUATMultC( pOut, q1, q2);
158     #elif (QUATMULT_CONFIG == D_FAST_C)
159         return ARMv6::QUATMultC_FAST( pOut, q1, q2);
160     #elif (QUATMULT_CONFIG == D_FAST_ASM)
161         return ARMv6::QUATMultAsm( pOut, q1, q2);
162     #elif (QUATMULT_CONFIG == D_FAST_C_ALGO)
163     #elif (QUATMULT_CONFIG == D_FAST_ASM_ALGO)
164     #endif
165 #else
166 #endif // #if defined( NN_HARDWARE_CTR )
167 }
168 
169 /*!--------------------------------------------------------------------------*
170   @brief        クォータニオンを正規化します。
171 
172   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。q と同じクォータニオンを指していても構いません。
173   @param[in]    q     正規化するクォータニオンへのポインタ
174 
175   @return       pOut を返します。
176  *---------------------------------------------------------------------------*/
177 NN_FORCE_INLINE QUAT*
QUATNormalize(QUAT * pOut,const QUAT * __restrict q)178 QUATNormalize(QUAT* pOut, const QUAT* __restrict q)
179 {
180 #if defined( NN_HARDWARE_CTR )
181     #if (QUATNORMALIZE_CONFIG == D_ORG)
182         return ARMv6::QUATNormalizeC( pOut, q );
183     #elif (QUATNORMALIZE_CONFIG == D_FAST_C)
184         return ARMv6::QUATNormalizeC_FAST( pOut, q);
185     #elif (QUATNORMALIZE_CONFIG == D_FAST_ASM)
186     #elif (QUATNORMALIZE_CONFIG == D_FAST_C_ALGO)
187     #elif (QUATNORMALIZE_CONFIG == D_FAST_ASM_ALGO)
188     #endif
189 #else
190 #endif // #if defined( NN_HARDWARE_CTR )
191 }
192 
193 /*!
194     @}
195 */
196 
197 }  // namespace math
198 }  // namespace nn
199 
200 
201 #if defined(NN_MATH_AS_INLINE)
202 #include <nn/math/inline/math_Quaternion.ipp>
203 #include <nn/math/ARMv6/inline/math_Quaternion.ipp>
204 #endif
205 
206 namespace nn {
207 namespace math {
208 
209 //-- const 引数を参照にしたオーバーロード
QUATAdd(QUAT * pOut,const QUAT & q1,const QUAT & q2)210 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)211 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)212 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)213 inline QUAT* QUATMult(QUAT* pOut, const QUAT& q1, const QUAT& q2) { return QUATMult( pOut, &q1, &q2 ); }
QUATDot(const QUAT & q1,const QUAT & q2)214 inline f32   QUATDot(const QUAT& q1, const QUAT& q2) { return QUATDot( &q1, &q2 ); }
QUATInverse(QUAT * pOut,const QUAT & q)215 inline QUAT* QUATInverse(QUAT* pOut, const QUAT& q) { return QUATInverse( pOut, &q ); }
QUATScale(QUAT * pOut,const QUAT & q,f32 scale)216 inline QUAT* QUATScale(QUAT* pOut, const QUAT& q, f32 scale) { return QUATScale( pOut, &q, scale ); }
QUATNormalize(QUAT * pOut,const QUAT & q)217 inline QUAT* QUATNormalize(QUAT* pOut, const QUAT& q) { return QUATNormalize( pOut, &q ); }
QUATExp(QUAT * pOut,const QUAT & q)218 inline QUAT* QUATExp(QUAT* pOut, const QUAT& q) { return QUATExp( pOut, &q ); }
QUATLogN(QUAT * pOut,const QUAT & q)219 inline QUAT* QUATLogN(QUAT* pOut, const QUAT& q) { return QUATLogN( pOut, &q ); }
QUATLerp(QUAT * pOut,const QUAT & q1,const QUAT & q2,f32 t)220 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)221 inline QUAT* QUATSlerp(QUAT* pOut, const QUAT& q1, const QUAT& q2, f32 t) { return QUATSlerp( pOut, &q1, &q2, t ); }
MTX34ToQUAT(QUAT * pOut,const MTX34 & mtx)222 inline QUAT* MTX34ToQUAT(QUAT* pOut, const MTX34& mtx) { return MTX34ToQUAT( pOut, &mtx ); }
QUATSquad(QUAT * pOut,const QUAT & p,const QUAT & a,const QUAT & b,const QUAT & q,f32 t)223 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 ); }
224 
QUATMakeClosest(QUAT * pOut,const QUAT & q,const QUAT & qto)225 inline QUAT* QUATMakeClosest( QUAT*  pOut, const QUAT& q, const QUAT& qto ) { return QUATMakeClosest( pOut, &q, &qto ); }
QUATRotAxisRad(QUAT * pOut,const VEC3 & axis,f32 rad)226 inline QUAT* QUATRotAxisRad( QUAT* pOut, const VEC3& axis, f32 rad ) { return QUATRotAxisRad( pOut, &axis, rad ); }
227 
228 }  // namespace math
229 }  // namespace nn
230 
231 
232 #endif // NN_MATH_QUATERNION_H_
233