1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Matrix33.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: 23346 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_MATRIX33_H_
17 #define NN_MATH_MATRIX33_H_
18 
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21 #include <nn/math/ARMv6/math_Matrix33.h>
22 
23 #pragma push
24 #pragma Otime
25 
26 namespace nn {
27 namespace math {
28 
29 struct MTX33;
30 struct MTX34;
31 
32 /*!
33     @name    行列
34     @{
35 */
36 
37 /*!--------------------------------------------------------------------------*
38   @brief        3x3行列の積を計算します。
39 
40   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。
41   @param[in]    p1    左の行列へのポインタ。
42   @param[in]    p2    右の行列へのポインタ。
43 
44   @return       pOutを返します。
45  *---------------------------------------------------------------------------*/
46 template<typename TMatrix>
47 NN_FORCE_INLINE TMatrix*
MTX33Mult(TMatrix * pOut,const TMatrix * p1,const TMatrix * p2)48 MTX33Mult(TMatrix* pOut, const TMatrix* p1, const TMatrix* p2)
49 {
50 #if defined( NN_HARDWARE_CTR )
51     #if (MTX33MULT_CONFIG == D_ORG)
52         return ARMv6::MTX33MultC( pOut, p1, p2 );
53     #elif (MTX33MULT_CONFIG == D_FAST_C)
54     #elif (MTX33MULT_CONFIG == D_FAST_ASM)
55         return ARMv6::MTX33MultAsm( pOut, p1, p2 );
56     #elif (MTX33MULT_CONFIG == D_FAST_C_ALGO)
57     #elif (MTX33MULT_CONFIG == D_FAST_ASM_ALGO)
58     #endif
59 #else
60 #endif
61 }
62 
63 /*!
64     @}
65 */
66 
67 /* ------------------------------------------------------------------------
68     MTX33用の関数
69    ------------------------------------------------------------------------ */
70 NN_MATH_INLINE bool   MTX33IsIdentity(const MTX33* p);
71 NN_MATH_INLINE MTX33* MTX33Copy(MTX33* pOut, const MTX33* p);
72 NN_MATH_INLINE MTX33* MTX33Zero(MTX33* pOut);
73 NN_MATH_INLINE MTX33* MTX33Identity(MTX33* pOut);
74 NN_MATH_INLINE MTX33* MTX33MAdd(MTX33* pOut, f32 t, const MTX33* p1, const MTX33* p2);
75 
76 NN_MATH_INLINE u32 MTX34InvTranspose(MTX33* pOut, const MTX34* p);
77 
78 NN_MATH_INLINE MTX33* MTX34ToMTX33(MTX33* pOut, const MTX34* pM);
79 NN_MATH_INLINE MTX34* MTX33ToMTX34(MTX34* pOut, const MTX33* pM);
80 
81 
82 NN_FORCE_INLINE MTX33* MTX33MAdd(MTX33* pOut, f32 t, const MTX33* p1, const MTX33* p2);
83 NN_FORCE_INLINE MTX33* MTX33Copy(MTX33* pOut, const MTX33* p);
84 NN_FORCE_INLINE VEC3* VEC3Transform(VEC3* pOut, const MTX33* pM, const VEC3* pV);
85 /* =======================================================================
86         クラスの定義
87    ======================================================================== */
88 
89 struct MTX33_
90 {
91     struct BaseData
92     {
93         f32 _00, _01, _02;
94         f32 _10, _11, _12;
95         f32 _20, _21, _22;
96     };
97 
98     union
99     {
100     #if defined(NN_MATH_USE_ANONYMOUS_STRUCT)
101         struct
102         {
103             f32 _00, _01, _02;
104             f32 _10, _11, _12;
105             f32 _20, _21, _22;
106         };
107     #endif
108         BaseData f;
109         f32 m[3][3];
110         f32 a[9];
111         VEC3_ v[3];
112     };
113 };
114 
115 /*!--------------------------------------------------------------------------*
116     @brief 3行3列の行列クラスです。
117  *---------------------------------------------------------------------------*/
118 // 主に法線行列のために存在する
119 // とりあえず確実に必要になるものだけ実装
120 struct MTX33 : public MTX33_
121 {
122 public:
123     static const int ROW_COUNT = 3; //!< 行数です。
124     static const int COLUMN_COUNT = 3; //!< 列数です。
125 
126     //! @brief 単位行列です。
IdentityMTX33127     static const MTX33& Identity()
128     {
129         static const MTX33 identity(
130             1.0f, 0.0f, 0.0f,
131             0.0f, 1.0f, 0.0f,
132             0.0f, 0.0f, 1.0f);
133 
134         return identity;
135     }
136 
137     typedef MTX33 self_type; //!< 自分の型です。
138     typedef f32   value_type; //!< 要素の型です。
139 public:
140     //----------------------------------------
141     //! @name 作成
142     //@{
143 
144     //! @brief コンストラクタです。
MTX33MTX33145     MTX33() {}
146     //! @brief コンストラクタです。
MTX33MTX33147     MTX33(const f32* p) { MTX33Copy(this, reinterpret_cast<const MTX33*>(p)); }
148     //! @brief コンストラクタです。
MTX33MTX33149     MTX33(const MTX34& rhs) { MTX34ToMTX33(this, &rhs); }
150     //! @brief コンストラクタです。
MTX33MTX33151     MTX33(f32 x00, f32 x01, f32 x02,
152           f32 x10, f32 x11, f32 x12,
153           f32 x20, f32 x21, f32 x22)
154     {
155         f._00 = x00; f._01 = x01; f._02 = x02;
156         f._10 = x10; f._11 = x11; f._12 = x12;
157         f._20 = x20; f._21 = x21; f._22 = x22;
158     }
159     //@}
160 
161     //----------------------------------------
162     //! @name 変換
163     //@{
164 
165     //! @brief f32 型へのキャストです。
166     operator f32*() { return this->a; }
167     //! @brief f32 型へのキャストです。
168     operator const f32*() const { return this->a; }
169 
170     //! @brief VEC3 型として行を取得します。
GetRowMTX33171     VEC3& GetRow(int index)
172     {
173         NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT);
174         return *reinterpret_cast<VEC3*>(&this->v[index]);
175     }
176 
177     //! @brief VEC3 型として行を取得します。
GetRowMTX33178     const VEC3& GetRow(int index) const
179     {
180         NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT);
181         return *reinterpret_cast<const VEC3*>(&this->v[index]);
182     }
183 
184     //! @brief VEC3 型として列を取得します。
GetColumnMTX33185     VEC3 GetColumn(int index) const
186     {
187         NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT);
188         VEC3 column;
189         column.x = this->m[0][index];
190         column.y = this->m[1][index];
191         column.z = this->m[2][index];
192         return column;
193     }
194 
195     //! @brief VEC3 型で列を設定します。
SetColumnMTX33196     void SetColumn(int index, const VEC3& column)
197     {
198         NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT);
199         this->m[0][index] = column.x;
200         this->m[1][index] = column.y;
201         this->m[2][index] = column.z;
202     }
203     //@}
204 
205     //----------------------------------------
206     //! @name 設定
207     //@{
208 
209     //! @brief 単位行列に設定します。
SetupIdentityMTX33210     self_type& SetupIdentity() { return *MTX33Identity(this); }
211 
212     //@}
213 
214     //----------------------------------------
215     //! @name 比較
216     //@{
217 
218     //! @brief 同値であれば true を返します。
219     bool operator == (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX33)) == 0; }
220 
221     //! @brief 同値でなければ true を返します
222     bool operator != (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX33)) != 0; }
223 
224     //! @brief 単位行列であれば true を返します。
IsIdentityMTX33225     bool IsIdentity() const { return MTX33IsIdentity(this); }
226 
227     //@}
228 
229     //! @brief 状態を出力します。
230     void Report(bool bNewline = true, const char* name = NULL) const;
231 };
232 
233 typedef struct MTX33 Matrix33;
234 
235 
236 }  // namespace math
237 }  // namespace nn
238 
239 
240 namespace nn {
241 namespace math {
242 
243 /*!
244     @name    行列
245     @{
246 */
247 
248 /*!--------------------------------------------------------------------------*
249   @brief        行列を実数倍して、別の行列を足します。
250 
251   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。
252   @param[in]    t     掛ける数。
253   @param[in]    p1    元の行列へのポインタ。
254   @param[in]    p2    足す行列へのポインタ。
255 
256   @return       pOut を返します。
257  *---------------------------------------------------------------------------*/
258 NN_FORCE_INLINE MTX33*
MTX33MAdd(MTX33 * pOut,f32 t,const MTX33 * p1,const MTX33 * p2)259 MTX33MAdd(MTX33* pOut, f32 t, const MTX33* p1, const MTX33* p2)
260 {
261 #if defined( NN_HARDWARE_CTR )
262     #if (MTX33MADD_CONFIG == D_ORG)
263         return ARMv6::MTX33MAddC(pOut, t, p1, p2);
264     #elif (MTX33MADD_CONFIG == D_FAST_C)
265         return ARMv6::MTX33MAddC_FAST(pOut, t, p1, p2);
266     #elif (MTX33MADD_CONFIG == D_FAST_ASM)
267         return ARMv6::MTX33MAddAsm(pOut, t, p1, p2);
268     #elif (MTX33MADD_CONFIG == D_FAST_C_ALGO)
269     #elif (MTX33MADD_CONFIG == D_FAST_ASM_ALGO)
270     #endif
271 #else
272 #endif // #if defined( NN_HARDWARE_CTR )
273 }
274 
275 /*!--------------------------------------------------------------------------*
276   @brief        3x3行列をコピーします。
277 
278   @param[out]   pOut  コピー先の行列のポインタ
279   @param[in]    p     コピー元の行列のポインタ
280 
281   @return       pOutを返します。
282  *---------------------------------------------------------------------------*/
283 NN_FORCE_INLINE MTX33*
MTX33Copy(MTX33 * pOut,const MTX33 * p)284 MTX33Copy(MTX33* pOut, const MTX33* p)
285 {
286 #if defined( NN_HARDWARE_CTR )
287     #if (MTX33COPY_CONFIG == D_ORG)
288         return ARMv6::MTX33CopyC(pOut, p);
289     #elif (MTX33COPY_CONFIG == D_FAST_C)
290     #elif (MTX33COPY_CONFIG == D_FAST_ASM)
291         return ARMv6::MTX33CopyAsm(pOut, p);
292     #elif (MTX33COPY_CONFIG == D_FAST_C_ALGO)
293     #elif (MTX33COPY_CONFIG == D_FAST_ASM_ALGO)
294     #endif
295 #else
296 #endif // #if defined( NN_HARDWARE_CTR )
297 }
298 /*!
299     @}
300 */
301 
302 /*!
303     @name    ユーティリティ
304     @{
305 */
306 
307 /*!--------------------------------------------------------------------------*
308   @brief        ベクトルを行列で変換します。
309 
310   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。pV と同じベクトルを指していても構いません。
311   @param[in]    pM    変換行列へのポインタ。
312   @param[in]    pV    元となるベクトルへのポインタ。
313 
314   @return       pOut を返します。
315  *---------------------------------------------------------------------------*/
316 NN_FORCE_INLINE VEC3*
VEC3Transform(VEC3 * pOut,const MTX33 * pM,const VEC3 * pV)317 VEC3Transform(VEC3* pOut, const MTX33* pM, const VEC3* pV)
318 {
319 #if defined( NN_HARDWARE_CTR )
320     #if (VEC3TRANSFORM_33XVEC3_CONFIG == D_ORG)
321         return ARMv6::VEC3TransformC(pOut, pM, pV);
322     #elif (VEC3TRANSFORM_33XVEC3_CONFIG == D_FAST_C)
323     #elif (VEC3TRANSFORM_33XVEC3_CONFIG == D_FAST_ASM)
324         return ARMv6::VEC3TransformAsm(pOut, pM, pV);
325     #elif (VEC3TRANSFORM_33XVEC3_CONFIG == D_FAST_C_ALGO)
326     #elif (VEC3TRANSFORM_33XVEC3_CONFIG == D_FAST_ASM_ALGO)
327     #endif
328 #else
329 #endif // #if defined( NN_HARDWARE_CTR )
330 }
331 
332 /*!
333     @}
334 */
335 
336 //-- const 引数を参照にしたオーバーロード
337 template<typename TMatrix>
MTX33Mult(TMatrix * pOut,const TMatrix & m1,const TMatrix & m2)338 inline TMatrix* MTX33Mult(TMatrix* pOut, const TMatrix& m1, const TMatrix& m2) { return MTX33Mult( pOut, &m1, &m2 ); }
MTX33IsIdentity(const MTX33 & m)339 inline bool   MTX33IsIdentity(const MTX33& m) { return MTX33IsIdentity( &m ); }
MTX33Copy(MTX33 * pOut,const MTX33 & m)340 inline MTX33* MTX33Copy(MTX33* pOut, const MTX33& m) { return MTX33Copy( pOut, &m ); }
MTX33MAdd(MTX33 * pOut,f32 t,const MTX33 & m1,const MTX33 & m2)341 inline MTX33* MTX33MAdd(MTX33* pOut, f32 t, const MTX33& m1, const MTX33& m2) { return MTX33MAdd( pOut, t, &m1, &m2 ); }
MTX34InvTranspose(MTX33 * pOut,const MTX34 & m)342 inline u32 MTX34InvTranspose(MTX33* pOut, const MTX34& m) { return MTX34InvTranspose( pOut, &m ); }
MTX34ToMTX33(MTX33 * pOut,const MTX34 & m)343 inline MTX33* MTX34ToMTX33(MTX33* pOut, const MTX34& m) { return MTX34ToMTX33( pOut, &m ); }
MTX33ToMTX34(MTX34 * pOut,const MTX33 & m)344 inline MTX34* MTX33ToMTX34(MTX34* pOut, const MTX33& m) { return MTX33ToMTX34( pOut, &m ); }
345 
346 
347 }  // namespace math
348 }  // namespace nn
349 
350 
351 #if defined(NN_MATH_AS_INLINE)
352 #include <nn/math/inline/math_Matrix33.ipp>
353 #include <nn/math/ARMv6/inline/math_Matrix33.ipp>
354 #endif
355 
356 #pragma pop
357 
358 #endif
359