1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Matrix43.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: 23442 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_MATRIX43_H_
17 #define NN_MATH_MATRIX43_H_
18 
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21 
22 #pragma push
23 #pragma Otime
24 
25 namespace nn {
26 namespace math {
27 
28 struct MTX43;
29 
30 /* ------------------------------------------------------------------------
31     MTX43用の関数
32    ------------------------------------------------------------------------ */
33 NN_MATH_INLINE MTX43* MTX43Zero(MTX43* pOut);
34 NN_MATH_INLINE MTX43* MTX43Identity(MTX43* pOut);
35 NN_MATH_INLINE bool   MTX43IsIdentity(const MTX43* p);
36 NN_MATH_INLINE MTX43* MTX43Copy(MTX43* pOut, const MTX43* p);
37 NN_MATH_INLINE MTX43* MTX43Add(MTX43* pOut, const MTX43* p1, const MTX43* p2);
38 NN_MATH_INLINE MTX43* MTX43Sub(MTX43* pOut, const MTX43* p1, const MTX43* p2);
39 NN_MATH_INLINE MTX43* MTX43Mult(MTX43* pOut, const MTX43* p1, const MTX43* p2);
40 NN_MATH_INLINE MTX43* MTX43Mult(MTX43* pOut, const MTX43* p, f32 f);
41 
42 NN_FORCE_INLINE MTX43* MTX43Add(MTX43* pOut, const MTX43* p1, const MTX43* p2);
43 NN_FORCE_INLINE MTX43* MTX43Copy(MTX43* pOut, const MTX43* p);
44 NN_FORCE_INLINE MTX43* MTX43Mult(MTX43* pOut, const MTX43* p1, const MTX43* p2);
45 NN_FORCE_INLINE MTX43* MTX43Mult(MTX43* pOut, const MTX43* p, f32 f);
46 /* =======================================================================
47         クラスの定義
48    ======================================================================== */
49 struct MTX43_
50 {
51     struct BaseData
52     {
53         f32 _00, _01, _02;
54         f32 _10, _11, _12;
55         f32 _20, _21, _22;
56         f32 _30, _31, _32;
57     };
58 
59     union
60     {
61     #if defined(NN_MATH_USE_ANONYMOUS_STRUCT)
62         struct
63         {
64             f32 _00, _01, _02;
65             f32 _10, _11, _12;
66             f32 _20, _21, _22;
67             f32 _30, _31, _32;
68         };
69     #endif
70         BaseData f;
71         f32 m[4][3];
72         f32 a[12];
73         VEC3_ v[4];
74     };
75 };
76 
77 /*!--------------------------------------------------------------------------*
78   @brief        4行3列の行列クラスです。
79  *---------------------------------------------------------------------------*/
80 struct MTX43 : public MTX43_
81 {
82 public:
83     static const int ROW_COUNT = 4; //!< 行数です。
84     static const int COLUMN_COUNT = 3; //!< 列数です。
85 
86     //! @brief 単位行列です。
IdentityMTX4387     static const MTX43& Identity()
88     {
89         static const MTX43 identity(
90             1.0f, 0.0f, 0.0f,
91             0.0f, 1.0f, 0.0f,
92             0.0f, 0.0f, 1.0f,
93             0.0f, 0.0f, 0.0f);
94 
95         return identity;
96     }
97     typedef MTX43 self_type; //!< 自分の型です。
98     typedef f32   value_type; //!< 要素の型です。
99 
100 public:
101     //----------------------------------------
102     //! @name 作成
103     //@{
104 
105     //! @brief コンストラクタです。
MTX43MTX43106     MTX43() {}
107 
108     //! @brief コンストラクタです。
MTX43MTX43109     MTX43(const f32* p) { (void)MTX43Copy(this, (MTX43*)p); }
110 
111     //! @brief コンストラクタです。
MTX43MTX43112     MTX43(f32 x00, f32 x01, f32 x02,
113           f32 x10, f32 x11, f32 x12,
114           f32 x20, f32 x21, f32 x22,
115           f32 x30, f32 x31, f32 x32)
116     {
117         f._00 = x00; f._01 = x01; f._02 = x02;
118         f._10 = x10; f._11 = x11; f._12 = x12;
119         f._20 = x20; f._21 = x21; f._22 = x22;
120         f._30 = x30; f._31 = x31; f._32 = x32;
121     }
122     //@}
123 
124     //----------------------------------------
125     //! @name 変換
126     //@{
127 
128     //! @brief f32 型へのキャストです。
129     operator f32*() { return this->a; }
130     //! @brief f32 型へのキャストです。
131     operator const f32*() const { return this->a; }
132 
133     //! @brief VEC3 型として行を取得します。
GetRowMTX43134     VEC3& GetRow(int index)
135     {
136         NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT);
137         return *reinterpret_cast<VEC3*>(&this->v[index]);
138     }
139 
140     //! @brief VEC3 型として行を取得します。
GetRowMTX43141     const VEC3& GetRow(int index) const
142     {
143         NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT);
144         return *reinterpret_cast<const VEC3*>(&this->v[index]);
145     }
146 
147     //! @brief VEC4 型として列を取得します。
GetColumnMTX43148     VEC4 GetColumn(int index) const
149     {
150         NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT);
151         VEC4 column;
152         column.x = this->m[0][index];
153         column.y = this->m[1][index];
154         column.z = this->m[2][index];
155         column.w = this->m[3][index];
156         return column;
157     }
158 
159     //! @brief VEC4 型で列を設定します。
SetColumnMTX43160     void SetColumn(int index, const VEC4& column)
161     {
162         NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT);
163         this->m[0][index] = column.x;
164         this->m[1][index] = column.y;
165         this->m[2][index] = column.z;
166         this->m[3][index] = column.w;
167     }
168 
169     //@}
170 
171     //----------------------------------------
172     //! @name 演算
173     //@{
174 
175     self_type& operator += (const self_type& rhs) { return *MTX43Add(this, this, &rhs); }
176     self_type& operator -= (const self_type& rhs) { return *MTX43Sub(this, this, &rhs); }
177 
178     self_type& operator *= (const self_type& rhs) { return *MTX43Mult(this, this, &rhs); }
179     self_type& operator *= (f32 f) { return *MTX43Mult(this, this, f); }
180     self_type& operator /= (f32 f) { return operator*=(1.f / f); }
181 
182     self_type operator + () const { return *this; }
183     self_type operator - () const
184         {
185             return MTX43(-f._00, -f._01, -f._02,
186                          -f._10, -f._11, -f._12,
187                          -f._20, -f._21, -f._22,
188                          -f._30, -f._31, -f._32);
189         }
190 
191     self_type operator + (const self_type& rhs) const { MTX43 tmp; return *MTX43Add(&tmp, this, &rhs); }
192     self_type operator - (const self_type& rhs) const { MTX43 tmp; return *MTX43Add(&tmp, this, &rhs); }
193 
194     self_type operator * (f32 f) const { MTX43 tmp; return *MTX43Mult(&tmp, this, f); }
195     self_type operator / (f32 f) const { return *this * (1.f / f); }
196 
197     //@}
198 
199     //----------------------------------------
200     //! @name 設定
201     //@{
202 
203     //! @brief 単位行列に設定します。
SetupIdentityMTX43204     self_type& SetupIdentity() { return *MTX43Identity(this); }
205 
206     //@}
207 
208     //----------------------------------------
209     //! @name 比較
210     //@{
211 
212     //! @brief 同値であれば true を返します。
213     bool operator == (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX43)) == 0; }
214 
215     //! @brief 同値でなければ true を返します。
216     bool operator != (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX43)) != 0; }
217 
218     //! @brief 単位行列であれば true を返します。
IsIdentityMTX43219     bool IsIdentity() const { return MTX43IsIdentity(this); }
220 
221     //@}
222 
223     //! @brief 状態を出力します。
224     void Report(bool bNewline = true, const char* name = NULL) const;
225 };
226 #include <nn/math/ARMv6/math_Matrix43.h>
227 
228 /*!
229     @name    行列
230     @{
231 */
232 
233 /*!--------------------------------------------------------------------------*
234   @brief        行列の和を計算します。
235 
236   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。
237   @param[in]    p1    左辺値へのポインタ。
238   @param[in]    p2    右辺値へのポインタ。
239 
240   @return       pOut を返します。
241  *---------------------------------------------------------------------------*/
242 NN_FORCE_INLINE MTX43*
MTX43Add(MTX43 * pOut,const MTX43 * p1,const MTX43 * p2)243 MTX43Add(MTX43* pOut, const MTX43* p1, const MTX43* p2)
244 {
245 #if defined( NN_HARDWARE_CTR )
246     #if (MTX43ADD_CONFIG == D_ORG)
247         return ARMv6::MTX43AddC(pOut, p1, p2);
248     #elif (MTX43ADD_CONFIG == D_FAST_C)
249     #elif (MTX43ADD_CONFIG == D_FAST_ASM)
250         return ARMv6::MTX43AddAsm(pOut, p1, p2);
251     #elif (MTX43ADD_CONFIG == D_FAST_C_ALGO)
252     #elif (MTX43ADD_CONFIG == D_FAST_ASM_ALGO)
253     #endif
254 #else
255 #endif // #if defined( NN_HARDWARE_CTR )
256 
257 }
258 
259 /*!--------------------------------------------------------------------------*
260   @brief        行列をコピーします。
261 
262   @param[out]   pOut  コピー先の行列へのポインタ。
263   @param[in]    p     コピー元の行列へのポインタ
264 
265   @return       pOut を返します。
266  *---------------------------------------------------------------------------*/
267 NN_FORCE_INLINE MTX43*
MTX43Copy(MTX43 * pOut,const MTX43 * p)268 MTX43Copy(MTX43* pOut, const MTX43* p)
269 {
270 #if defined( NN_HARDWARE_CTR )
271     #if (MTX43COPY_CONFIG == D_ORG)
272         return ARMv6::MTX43CopyC(pOut, p);
273     #elif (MTX43COPY_CONFIG == D_FAST_C)
274     #elif (MTX43COPY_CONFIG == D_FAST_ASM)
275         return ARMv6::MTX43CopyAsm(pOut, p);
276     #elif (MTX43COPY_CONFIG == D_FAST_C_ALGO)
277     #elif (MTX43COPY_CONFIG == D_FAST_ASM_ALGO)
278     #endif
279 #else
280 #endif // #if defined( NN_HARDWARE_CTR )
281 
282 }
283 
284 /*!--------------------------------------------------------------------------*
285   @brief        行列の積を計算します。
286 
287   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。
288   @param[in]    p1    左辺値へのポインタ。
289   @param[in]    p2    右辺値へのポインタ。
290 
291   @return       pOut を返します。
292  *---------------------------------------------------------------------------*/
293 NN_FORCE_INLINE MTX43*
MTX43Mult(MTX43 * pOut,const MTX43 * p1,const MTX43 * p2)294 MTX43Mult(MTX43* pOut, const MTX43* p1, const MTX43* p2)
295 {
296 #if defined( NN_HARDWARE_CTR )
297     #if (MTX43MULT_43_CONFIG == D_ORG)
298         return ARMv6::MTX43MultC(pOut, p1, p2);
299     #elif (MTX43MULT_43_CONFIG == D_FAST_C)
300     #elif (MTX43MULT_43_CONFIG == D_FAST_ASM)
301         return ARMv6::MTX43MultAsm(pOut, p1, p2);
302     #elif (MTX43MULT_43_CONFIG == D_FAST_C_ALGO)
303     #elif (MTX43MULT_43_CONFIG == D_FAST_ASM_ALGO)
304     #endif
305 #else
306 #endif // #if defined( NN_HARDWARE_CTR )
307 }
308 
309 /*!--------------------------------------------------------------------------*
310   @brief        行列にスカラを乗算します。
311 
312   @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p と同じ行列を指していても構いません。
313   @param[in]    p   元となる行列へのポインタ。
314   @param[in]    f   乗算するスカラ値。。
315 
316   @return       pOut を返します。
317  *---------------------------------------------------------------------------*/
318 NN_FORCE_INLINE MTX43*
MTX43Mult(MTX43 * pOut,const MTX43 * p,f32 f)319 MTX43Mult(MTX43* pOut, const MTX43* p, f32 f)
320 {
321 #if defined( NN_HARDWARE_CTR )
322     #if (MTX43MULT_F32_CONFIG == D_ORG)
323         return ARMv6::MTX43MultC(pOut, p, f);
324     #elif (MTX43MULT_F32_CONFIG == D_FAST_C)
325     #elif (MTX43MULT_F32_CONFIG == D_FAST_ASM)
326         return ARMv6::MTX43MultAsm(pOut, p, f);
327     #elif (MTX43MULT_F32_CONFIG == D_FAST_C_ALGO)
328     #elif (MTX43MULT_F32_CONFIG == D_FAST_ASM_ALGO)
329     #endif
330 #else
331 #endif // #if defined( NN_HARDWARE_CTR )
332 }
333 
334 
335 typedef struct MTX43 Matrix43;
336 
337 //-- const 引数を参照にしたオーバーロード
MTX44IsIdentity(const MTX43 & m)338 inline bool   MTX44IsIdentity(const MTX43& m) { return MTX43IsIdentity( &m ); }
MTX43Copy(MTX43 * pOut,const MTX43 & m)339 inline MTX43* MTX43Copy(MTX43* pOut, const MTX43& m) { return MTX43Copy( pOut, &m ); }
MTX43Add(MTX43 * pOut,const MTX43 & m1,const MTX43 & m2)340 inline MTX43* MTX43Add(MTX43* pOut, const MTX43& m1, const MTX43& m2) { return MTX43Add( pOut, &m1, &m2 ); }
MTX43Sub(MTX43 * pOut,const MTX43 & m1,const MTX43 & m2)341 inline MTX43* MTX43Sub(MTX43* pOut, const MTX43& m1, const MTX43& m2) { return MTX43Sub( pOut, &m1, &m2 ); }
MTX43Mult(MTX43 * pOut,const MTX43 & m1,const MTX43 & m2)342 inline MTX43* MTX43Mult(MTX43* pOut, const MTX43& m1, const MTX43& m2) { return MTX43Mult( pOut, &m1, &m2 ); }
MTX43Mult(MTX43 * pOut,const MTX43 & m,f32 f)343 inline MTX43* MTX43Mult(MTX43* pOut, const MTX43& m, f32 f) { return MTX43Mult( pOut, &m, f); }
344 
345 /*!
346     @}
347 */
348 
349 }  // namespace math
350 }  // namespace nn
351 
352 
353 #if defined(NN_MATH_AS_INLINE)
354 #include <nn/math/inline/math_Matrix43.ipp>
355 #include <nn/math/ARMv6/inline/math_Matrix43.ipp>
356 #endif
357 
358 #pragma pop
359 
360 #endif
361