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