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