/*---------------------------------------------------------------------------* Project: Horizon File: math_Matrix44.h Copyright (C)2009-2010 Nintendo Co., Ltd. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 24788 $ *---------------------------------------------------------------------------*/ #ifndef NN_MATH_MATRIX44_H_ #define NN_MATH_MATRIX44_H_ #include #include #pragma push #pragma Otime namespace nn { namespace math { /*! @name 行列 @{ */ /*!--------------------------------------------------------------------------* @brief 射影行列に掛ける回転行列を指定するための列挙型です。 *---------------------------------------------------------------------------*/ enum PivotDirection { PIVOT_NONE, //!< 回転処理をおこないません。 PIVOT_UPSIDE_TO_TOP, //!< カメラ上方向が画面上方向を向くように回転します。 PIVOT_UPSIDE_TO_RIGHT, //!< カメラ上方向が画面右方向を向くように回転します。 PIVOT_UPSIDE_TO_BOTTOM, //!< カメラ上方向が画面下方向を向くように回転します。 PIVOT_UPSIDE_TO_LEFT, //!< カメラ上方向が画面左方向を向くように回転します。 PIVOT_NUM }; /*! @} */ /* ------------------------------------------------------------------------ MTX44用の関数 ------------------------------------------------------------------------ */ struct MTX44; NN_MATH_INLINE MTX44* MTX44Zero(MTX44* pOut); NN_MATH_INLINE bool MTX44IsIdentity(const MTX44* p); NN_MATH_INLINE MTX44* MTX44Identity(MTX44* pOut); NN_MATH_INLINE MTX44* MTX44Copy(MTX44* pOut, const MTX44* p); NN_MATH_INLINE MTX44* MTX44Add(MTX44* pOut, const MTX44* p1, const MTX44* p2); NN_MATH_INLINE MTX44* MTX44Sub(MTX44* pOut, const MTX44* p1, const MTX44* p2); NN_MATH_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* p, f32 f); NN_MATH_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* p1, const MTX44* p2); NN_MATH_INLINE MTX44* MTX44Frustum(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f); NN_MATH_INLINE MTX44* MTX44Ortho(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f); NN_MATH_INLINE MTX44* MTX44PerspectiveRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f); NN_MATH_INLINE MTX44* MTX44Transpose(MTX44* pOut, const MTX44 *pSrc); NN_MATH_INLINE MTX44* MTX44MultArray(MTX44* pOut, const MTX44* p1, const MTX44* pSrc, s32 count); NN_MATH_INLINE u32 MTX44Inverse(MTX44* pOut, const MTX44* p); NN_MATH_INLINE MTX44* MTX44RotXYZFIdx(MTX44* pOut, f32 fIdxX, f32 fIdxY, f32 fIdxZ); NN_MATH_INLINE MTX44* MTX44RotAxisFIdx(MTX44* pOut, const VEC3* pAxis, f32 fIdx); NN_MATH_INLINE MTX44* MTX44Scale(MTX44* pOut, const VEC3* pS); NN_MATH_INLINE MTX44* MTX44MultScale(MTX44* pOut, const MTX44* pM, const VEC3* pS); NN_MATH_INLINE MTX44* MTX44MultScale(MTX44* pOut, const VEC3* pS, const MTX44* pM); NN_MATH_INLINE MTX44* MTX44Translate(MTX44* pOut, const VEC3* pT); NN_MATH_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const MTX44* pM, const VEC3* pT); NN_MATH_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const VEC3* pT, const MTX44* pM); NN_MATH_INLINE MTX44* MTX44FrustumPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE); NN_MATH_INLINE MTX44* MTX44OrthoPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE); NN_MATH_INLINE MTX44* MTX44PerspectivePivotRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE); NN_FORCE_INLINE MTX44* MTX44Add(MTX44* pOut, const MTX44* p1, const MTX44* p2); NN_FORCE_INLINE MTX44* MTX44Copy(MTX44* pOut, const MTX44* p); NN_FORCE_INLINE MTX44* MTX44Frustum(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f); NN_FORCE_INLINE u32 MTX44Inverse(MTX44* pOut, const MTX44* p); NN_FORCE_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* __restrict p1, const MTX44* __restrict p2); NN_FORCE_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* p, f32 f); NN_FORCE_INLINE MTX44* MTX44MultScale(MTX44* pOut, const MTX44* pM, const VEC3* pS); NN_FORCE_INLINE MTX44* MTX44MultScale(MTX44* pOut, const VEC3* pS, const MTX44* pM); NN_FORCE_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const VEC3* pT, const MTX44* pM); NN_FORCE_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const MTX44* pM, const VEC3* pT); NN_FORCE_INLINE MTX44* MTX44Ortho(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f); NN_FORCE_INLINE MTX44* MTX44PerspectiveRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f); NN_FORCE_INLINE MTX44* MTX44RotAxisRad_( MTX44* pOut, const VEC3 *pAxis, f32 fRad ); NN_FORCE_INLINE MTX44* MTX44RotXYZFIdx(MTX44* pOut, f32 fIdxX, f32 fIdxY, f32 fIdxZ); NN_FORCE_INLINE MTX44* MTX44Scale(MTX44* pOut, const VEC3* pS); NN_FORCE_INLINE MTX44* MTX44Translate(MTX44* pOut, const VEC3* pT); NN_FORCE_INLINE MTX44* MTX44Transpose(MTX44* pOut, const MTX44 *pSrc); NN_FORCE_INLINE VEC4* VEC3Transform(VEC4* pOut, const MTX44* pM, const VEC3* pV); NN_FORCE_INLINE MTX44* MTX44Pivot( MTX44* pOut, PivotDirection pivot ); /*! @name 行列 @{ */ /*!--------------------------------------------------------------------------* @brief 射影行列を視野角とアスペクト比から作成します。 @param[out] pOut 射影行列を格納する行列へのポインタ。 @param[in] fovy 縦方向の視野角(Degree) @param[in] aspect 視野のアスペクト比(幅/高さ) @param[in] n ニアクリッピング面までの距離。 @param[in] f ファークリッピング面までの距離。 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44PerspectiveDeg(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f) { return MTX44PerspectiveRad(pOut, NN_MATH_DEG_TO_RAD(fovy), aspect, n, f); } // MTX44PerspectiveDeg 関数の別名です。 // 互換性の為に接尾語の無い Perspective 関数を degree 版としています。 inline MTX44* MTX44Perspective(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f) { return MTX44PerspectiveDeg(pOut, fovy, aspect, n, f); } /*!--------------------------------------------------------------------------* @brief 射影行列を視野角とアスペクト比から作成します。 @param[out] pOut 射影行列を格納する行列へのポインタ。 @param[in] fovy 縦方向の視野角(Degree) @param[in] aspect 視野のアスペクト比(幅/高さ) @param[in] n ニアクリッピング面までの距離。 @param[in] f ファークリッピング面までの距離。 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44PerspectivePivotDeg(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE ) { return MTX44PerspectivePivotRad(pOut, NN_MATH_DEG_TO_RAD(fovy), aspect, n, f, pivot); } /*!--------------------------------------------------------------------------* @brief 回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] fRadX ラジアン単位での X 軸周りの角度 @param[in] fRadY ラジアン単位での Y 軸周りの角度 @param[in] fRadZ ラジアン単位での Z 軸周りの角度 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44RotXYZRad(MTX44* pOut, f32 fRadX, f32 fRadY, f32 fRadZ) { return MTX44RotXYZFIdx(pOut, NN_MATH_RAD_TO_FIDX(fRadX), NN_MATH_RAD_TO_FIDX(fRadY), NN_MATH_RAD_TO_FIDX(fRadZ)); } /*!--------------------------------------------------------------------------* @brief 回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] fDegX 1 円周を 360.0 とする単位での X 軸周りの角度 @param[in] fDegY 1 円周を 360.0 とする単位での Y 軸周りの角度 @param[in] fDegZ 1 円周を 360.0 とする単位での Z 軸周りの角度 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44RotXYZDeg(MTX44* pOut, f32 fDegX, f32 fDegY, f32 fDegZ) { return MTX44RotXYZFIdx(pOut, NN_MATH_DEG_TO_FIDX(fDegX), NN_MATH_DEG_TO_FIDX(fDegY), NN_MATH_DEG_TO_FIDX(fDegZ)); } /*!--------------------------------------------------------------------------* @brief 指定する軸の周りを回転させる回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] pAxis 回転軸を指定するベクトルへのポインタ。 @param[in] fRad ラジアン単位での回転量 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44RotAxisRad(MTX44* pOut, const VEC3* pAxis, f32 fRad) { return MTX44RotAxisFIdx(pOut, pAxis, NN_MATH_RAD_TO_FIDX(fRad)); } /*!--------------------------------------------------------------------------* @brief 指定する軸の周りを回転させる回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] pAxis 回転軸を指定するベクトルへのポインタ。 @param[in] fDeg 1 円周を 360.0 とする単位での回転量 @return pOut を返します。 *---------------------------------------------------------------------------*/ inline MTX44* MTX44RotAxisDeg(MTX44* pOut, const VEC3* pAxis, f32 fDeg) { return MTX44RotAxisFIdx(pOut, pAxis, NN_MATH_DEG_TO_FIDX(fDeg)); } /* ======================================================================= クラスの定義 ======================================================================== */ struct MTX34; struct MTX44_ { struct BaseData { f32 _00, _01, _02, _03; f32 _10, _11, _12, _13; f32 _20, _21, _22, _23; f32 _30, _31, _32, _33; }; union { #if defined(NN_MATH_USE_ANONYMOUS_STRUCT) struct { f32 _00, _01, _02, _03; f32 _10, _11, _12, _13; f32 _20, _21, _22, _23; f32 _30, _31, _32, _33; }; #endif BaseData f; f32 m[4][4]; f32 a[16]; VEC4_ v[4]; }; }; /*!--------------------------------------------------------------------------* @brief 4行4列の行列クラスです。 *---------------------------------------------------------------------------*/ struct MTX44 : public MTX44_ { public: static const int ROW_COUNT = 4; //!< 行数です。 static const int COLUMN_COUNT = 4; //!< 列数です。 //! @brief 単位行列です。 static const MTX44& Identity() { static const MTX44 identity( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); return identity; } typedef MTX44 self_type; //!< 自分の型です。 typedef f32 value_type; //!< 要素の型です。 public: //---------------------------------------- //! @name 作成 //@{ //! @brief コンストラクタです。 MTX44() {} //! @brief コンストラクタです。 MTX44(const f32* p) { (void)MTX44Copy(this, (MTX44*)p); } //! @brief コンストラクタです。 MTX44(const MTX34& rhs) { (void)MTX34Copy((MTX34*)this, (MTX34*)&rhs); f._30 = f._31 = f._32 = 0.f; f._33 = 1.f; } //! @brief コピーコンストラクタです。 MTX44(const MTX44& rhs) { (void)MTX44Copy(this, &rhs); } //! @brief コンストラクタです。 MTX44(f32 x00, f32 x01, f32 x02, f32 x03, f32 x10, f32 x11, f32 x12, f32 x13, f32 x20, f32 x21, f32 x22, f32 x23, f32 x30, f32 x31, f32 x32, f32 x33) { f._00 = x00; f._01 = x01; f._02 = x02; f._03 = x03; f._10 = x10; f._11 = x11; f._12 = x12; f._13 = x13; f._20 = x20; f._21 = x21; f._22 = x22; f._23 = x23; f._30 = x30; f._31 = x31; f._32 = x32; f._33 = x33; } //@} //---------------------------------------- //! @name 変換 //@{ //! @brief f32 型へのキャストです。 operator f32*() { return this->a; } //! @brief f32 型へのキャストです。 operator const f32*() const { return this->a; } //! @brief VEC4 型として行を取得します。 VEC4& GetRow(int index) { NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT); return *reinterpret_cast(&this->v[index]); } //! @brief VEC4 型として行を取得します。 const VEC4& GetRow(int index) const { NN_MATH_MINMAXLT_ASSERT(index, 0, ROW_COUNT); return *reinterpret_cast(&this->v[index]); } //! @brief VEC4 型として列を取得します。 VEC4 GetColumn(int index) const { NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT); VEC4 column; column.x = this->m[0][index]; column.y = this->m[1][index]; column.z = this->m[2][index]; column.w = this->m[3][index]; return column; } //! @brief VEC4 型で列を設定します。 void SetColumn(int index, const VEC4& column) { NN_MATH_MINMAXLT_ASSERT(index, 0, COLUMN_COUNT); this->m[0][index] = column.x; this->m[1][index] = column.y; this->m[2][index] = column.z; this->m[3][index] = column.w; } //@} //---------------------------------------- //! @name 演算 //@{ //! @brief 行列を右からかけた値を代入します。 self_type& operator *= (const self_type& rhs) { return *MTX44Mult(this, this, &rhs); } self_type& operator += (const self_type& rhs) { return *MTX44Add(this, this, &rhs); } self_type& operator -= (const self_type& rhs) { return *MTX44Sub(this, this, &rhs); } self_type& operator *= (f32 f) { return *MTX44Mult(this, this, f); } self_type& operator /= (f32 f) { return operator*=(1.f / f); } self_type operator + () const { return *this; } self_type operator - () const { return MTX44(-f._00, -f._01, -f._02, -f._03, -f._10, -f._11, -f._12, -f._13, -f._20, -f._21, -f._22, -f._23, -f._30, -f._31, -f._32, -f._33); } self_type operator + (const self_type& rhs) const { MTX44 tmp; return *MTX44Add(&tmp, this, &rhs); } self_type operator - (const self_type& rhs) const { MTX44 tmp; return *MTX44Sub(&tmp, this, &rhs); } self_type operator * (f32 f) const { MTX44 tmp; return *MTX44Mult(&tmp, this, f); } self_type operator / (f32 f) const { return *this * (1.f / f); } //! 転置を行います。 self_type& Transpose() { return *MTX44Transpose(this, this); } //@} //---------------------------------------- //! @name 設定 //@{ //! @brief 単位行列に設定します。 self_type& SetupIdentity() { return *MTX44Identity(this); } //! @brief スケール変換行列に設定します。 //! //! @param[in] scale スケール値です。 //! self_type& SetupScale(const VEC3& scale) { return *MTX44Scale(this, &scale); } //! @brief 平行移動行列に設定します。 //! //! @param[in] translate 平行移動値です。 //! self_type& SetupTranslate(const VEC3& translate) { return *MTX44Translate(this, &translate); } //! @brief XYZ 順の回転行列に設定します。 //! //! @param[in] rotateRad 回転値です。単位はラジアンです。 //! self_type& SetupRotateXyz(const VEC3& rotateRad) { return *MTX44RotXYZRad(this, rotateRad.x, rotateRad.y, rotateRad.z); } //! @brief 指定した軸周りの回転行列に設定します。 //! //! @param[in] axis 基準となる軸のベクトルです。 //! @param[in] theta 回転させる角度です。単位はラジアンです。 //! self_type& SetupRotate(const VEC3& axis, f32 thetaRad) { return *MTX44RotAxisRad(this, &axis, thetaRad); } //! @brief 射影行列をニアクリッピング面での視錐台を元に設定します。 //! 引数の順序が OpenGL 準拠になっているので注意してください。 //! //! @param[in] l ニアクリッピング面での視錐台左辺の X 座標です。 //! @param[in] r ニアクリッピング面での視錐台右辺の X 座標です。 //! @param[in] b ニアクリッピング面での視錐台下辺の Y 座標です。 //! @param[in] t ニアクリッピング面での視錐台上辺の Y 座標です。 //! @param[in] n ニアクリッピング面までの距離です。 //! @param[in] f ファークリッピング面までの距離です。 //! @param[in] pivot 画面の回転方向です。 //! self_type& SetupFrustum(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE) { return *MTX44FrustumPivot(this, l, r, b, t, n, f, pivot); } //! @brief 正射影行列を設定します。 //! 引数の順序が OpenGL 準拠になっているので注意してください。 //! //! @param[in] l ニアクリッピング面での視錐台左辺の X 座標です。 //! @param[in] r ニアクリッピング面での視錐台右辺の X 座標です。 //! @param[in] b ニアクリッピング面での視錐台下辺の Y 座標です。 //! @param[in] t ニアクリッピング面での視錐台上辺の Y 座標です。 //! @param[in] n ニアクリッピング面までの距離です。 //! @param[in] f ファークリッピング面までの距離です。 //! @param[in] pivot 画面の回転方向です。 //! self_type& SetupOrtho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE) { return *MTX44OrthoPivot(this, l, r, b, t, n, f, pivot); } //! @brief 射影行列を視野角とアスペクト比から設定します。 //! //! @param[in] fovyRad 縦方向の視野角(Radian)です。 //! @param[in] aspect 視野のアスペクト比(幅/高さ)です。 //! @param[in] n ニアクリッピング面までの距離です。 //! @param[in] f ファークリッピング面までの距離です。 //! @param[in] pivot 画面の回転方向です。 //! self_type& SetupPerspective(f32 fovyRad, f32 aspect, f32 n, f32 f, PivotDirection pivot = PIVOT_NONE) { return *MTX44PerspectivePivotRad(this, fovyRad, aspect, n, f, pivot); } //@} //---------------------------------------- //! @name 比較 //@{ //! @brief 同値であれば true を返します。 bool operator == (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX44)) == 0; } //! @brief 同値でなければ true を返します。 bool operator != (const self_type& rhs) const { return ::std::memcmp(this, &rhs, sizeof(MTX44)) != 0; } //! @brief 単位行列であれば true を返します。 bool IsIdentity() const { return MTX44IsIdentity(this); } //@} //! @brief 状態を出力します。 void Report(bool bNewline = true, const char* name = NULL) const; }; typedef struct MTX44 Matrix44; /*! @} */ } // namespace math } // namespace nn #include namespace nn { namespace math { /*! @name 行列 @{ */ /*!--------------------------------------------------------------------------* @brief 行列の和を計算します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。 @param[in] p1 左辺値へのポインタ。 @param[in] p2 右辺値へのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Add(MTX44* pOut, const MTX44* p1, const MTX44* p2) { #if defined( NN_HARDWARE_CTR ) #if (MTX44ADD_ASM_CONFIG == D_ORG) return ARMv6::MTX44AddC(pOut, p1, p2); #elif (MTX44ADD_ASM_CONFIG == D_FAST_C) #elif (MTX44ADD_ASM_CONFIG == D_FAST_ASM) return ARMv6::MTX44AddAsm(pOut, p1, p2); #elif (MTX44ADD_ASM_CONFIG == D_FAST_C_ALGO) #elif (MTX44ADD_ASM_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列をコピーします。 @param[out] pOut コピー先の行列へのポインタ。 @param[in] p コピー元の行列へのポインタ @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Copy(MTX44* pOut, const MTX44* p) { #if defined( NN_HARDWARE_CTR ) #if (MTX44COPY_CONFIG == D_ORG) return ARMv6::MTX44CopyC(pOut, p); #elif (MTX44COPY_CONFIG == D_FAST_C) #elif (MTX44COPY_CONFIG == D_FAST_ASM) return ARMv6::MTX44CopyAsm(pOut, p); #elif (MTX44COPY_CONFIG == D_FAST_C_ALGO) #elif (MTX44COPY_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 射影行列をニアクリッピング面での視錐台を元に作成します。 引数の順序が OpenGL 準拠になっているので注意。 @param[out] pOut 射影行列を格納する行列へのポインタ。 @param[in] l ニアクリッピング面での視錐台左辺の X 座標 @param[in] r ニアクリッピング面での視錐台右辺の X 座標 @param[in] b ニアクリッピング面での視錐台下辺の Y 座標 @param[in] t ニアクリッピング面での視錐台上辺の Y 座標 @param[in] n ニアクリッピング面までの距離。 @param[in] f ファークリッピング面までの距離。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Frustum(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f) { #if defined( NN_HARDWARE_CTR ) #if (MTX44FRUSTUM_CONFIG == D_ORG) return ARMv6::MTX44FrustumC(pOut, l, r, b, t, n, f); #elif (MTX44FRUSTUM_CONFIG == D_FAST_C) return ARMv6::MTX44FrustumC_FAST(pOut, l, r, b, t, n, f); #elif (MTX44FRUSTUM_CONFIG == D_FAST_ASM) #elif (MTX44FRUSTUM_CONFIG == D_FAST_C_ALGO) #elif (MTX44FRUSTUM_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列の逆行列を計算します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p と同じ行列を指していても構いません。 @param[in] p 元となる行列へのポインタ。 @return 逆行列が存在すれば 1 を、存在しなければ 0 を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE u32 MTX44Inverse(MTX44* pOut, const MTX44* p) { #if defined( NN_HARDWARE_CTR ) #if (MTX44INVERSE_CONFIG == D_ORG) return ARMv6::MTX44InverseC(pOut, p); #elif (MTX44INVERSE_CONFIG == D_FAST_C) #elif (MTX44INVERSE_CONFIG == D_FAST_ASM) #elif (MTX44INVERSE_CONFIG == D_FAST_C_ALGO) return ARMv6::MTX44InverseC_FAST_ALGO(pOut, p); #elif (MTX44INVERSE_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列の積を計算します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。 @param[in] p1 左辺値へのポインタ。 @param[in] p2 右辺値へのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* __restrict p1, const MTX44* __restrict p2) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULT_44_CONFIG == D_ORG) return ARMv6::MTX44MultC(pOut, p1, p2); #elif (MTX44MULT_44_CONFIG == D_FAST_C) #elif (MTX44MULT_44_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultAsm(pOut, p1, p2); #elif (MTX44MULT_44_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULT_44_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列のスカラー積を計算します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p と同じ行列を指していても構いません。 @param[in] p 元の行列のポインタ。 @param[in] f 掛ける数 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Mult(MTX44* pOut, const MTX44* p, f32 f) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULT_F32_CONFIG == D_ORG) return ARMv6::MTX44MultC(pOut, p, f); #elif (MTX44MULT_F32_CONFIG == D_FAST_C) #elif (MTX44MULT_F32_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultAsm(pOut, p, f); #elif (MTX44MULT_F32_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULT_F32_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列にスケール変換を適用します。スケール行列を右から掛けます。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pM 元となる行列へのポインタ。 @param[in] pS それぞれの軸方向のスケール値が格納されたベクトルへのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44MultScale(MTX44* pOut, const MTX44* pM, const VEC3* pS) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULTSCALE_RIGHT_CONFIG == D_ORG) return ARMv6::MTX44MultScaleC(pOut, pM, pS); #elif (MTX44MULTSCALE_RIGHT_CONFIG == D_FAST_C) #elif (MTX44MULTSCALE_RIGHT_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultScaleAsm(pOut, pM, pS); #elif (MTX44MULTSCALE_RIGHT_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULTSCALE_RIGHT_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列にスケール変換を適用します。スケール行列を左から掛けます。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pS それぞれの軸方向のスケール値が格納されたベクトルへのポインタ。 @param[in] pM 元となる行列へのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44MultScale(MTX44* pOut, const VEC3* pS, const MTX44* pM) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULTSCALE_LEFT_CONFIG == D_ORG) return ARMv6::MTX44MultScaleC(pOut, pS, pM); #elif (MTX44MULTSCALE_LEFT_CONFIG == D_FAST_C) #elif (MTX44MULTSCALE_LEFT_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultScaleAsm(pOut, pS, pM); #elif (MTX44MULTSCALE_LEFT_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULTSCALE_LEFT_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列に平行移動を適用します。移動行列を左から掛けます。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pT それぞれの軸方向の移動量が格納されたベクトルへのポインタ。 @param[in] pM 元となる行列へのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const VEC3* pT, const MTX44* pM) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULTTRANSLATE_LEFT_CONFIG == D_ORG) return ARMv6::MTX44MultTranslateC(pOut, pT, pM); #elif (MTX44MULTTRANSLATE_LEFT_CONFIG == D_FAST_C) #elif (MTX44MULTTRANSLATE_LEFT_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultTranslateAsm(pOut, pT, pM); #elif (MTX44MULTTRANSLATE_LEFT_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULTTRANSLATE_LEFT_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列に平行移動を適用します。移動行列を右から掛けます。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pM 元となる行列へのポインタ。 @param[in] pT それぞれの軸方向の移動量が格納されたベクトルへのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44MultTranslate(MTX44* pOut, const MTX44* pM, const VEC3* pT) { #if defined( NN_HARDWARE_CTR ) #if (MTX44MULTTRANSLATE_RIGHT_CONFIG == D_ORG) return ARMv6::MTX44MultTranslateC(pOut, pM, pT); #elif (MTX44MULTTRANSLATE_RIGHT_CONFIG == D_FAST_C) #elif (MTX44MULTTRANSLATE_RIGHT_CONFIG == D_FAST_ASM) return ARMv6::MTX44MultTranslateAsm(pOut, pM, pT); #elif (MTX44MULTTRANSLATE_RIGHT_CONFIG == D_FAST_C_ALGO) #elif (MTX44MULTTRANSLATE_RIGHT_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 正射影行列を作成します。 引数の順序が OpenGL 準拠になっているので注意。 @param[out] pOut 射影行列を格納する行列へのポインタ。 @param[in] l ニアクリッピング面での視錐台左辺の X 座標 @param[in] r ニアクリッピング面での視錐台右辺の X 座標 @param[in] b ニアクリッピング面での視錐台下辺の Y 座標 @param[in] t ニアクリッピング面での視錐台上辺の Y 座標 @param[in] n ニアクリッピング面までの距離。 @param[in] f ファークリッピング面までの距離。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Ortho(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f) { #if defined( NN_HARDWARE_CTR ) #if (MTX44ORTHO_CONFIG == D_ORG) return ARMv6::MTX44OrthoC(pOut, l, r, b, t, n, f); #elif (MTX44ORTHO_CONFIG == D_FAST_C) return ARMv6::MTX44OrthoC_FAST(pOut, l, r, b, t, n, f); #elif (MTX44ORTHO_CONFIG == D_FAST_ASM) #elif (MTX44ORTHO_CONFIG == D_FAST_C_ALGO) #elif (MTX44ORTHO_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 射影行列を視野角とアスペクト比から作成します。 @param[out] pOut 射影行列を格納する行列へのポインタ。 @param[in] fovy 縦方向の視野角(Radian) @param[in] aspect 視野のアスペクト比(幅/高さ) @param[in] n ニアクリッピング面までの距離。 @param[in] f ファークリッピング面までの距離。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44PerspectiveRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f) { #if defined( NN_HARDWARE_CTR ) #if (MTX44PERSPECTIVERAD_CONFIG == D_ORG) return ARMv6::MTX44PerspectiveRadC(pOut, fovy, aspect, n, f); #elif (MTX44PERSPECTIVERAD_CONFIG == D_FAST_C) return ARMv6::MTX44PerspectiveRadC_FAST(pOut, fovy, aspect, n, f); #elif (MTX44PERSPECTIVERAD_CONFIG == D_FAST_ASM) #elif (MTX44PERSPECTIVERAD_CONFIG == D_FAST_C_ALGO) return ARMv6::MTX44PerspectiveRadC_FAST(pOut, fovy, aspect, n, f); #elif (MTX44PERSPECTIVERAD_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 指定する軸の周りを回転させる回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] pAxis 回転軸を指定するベクトルへのポインタ。 @param[in] fRad ラジアン単位での回転量 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44RotAxisRad_( MTX44* pOut, const VEC3 *pAxis, f32 fRad ) { #if defined( NN_HARDWARE_CTR ) #if (MTX44ROTAXISRAD__CONFIG == D_ORG) return ARMv6::MTX44RotAxisRad_C(pOut, pAxis, fRad); #elif (MTX44ROTAXISRAD__CONFIG == D_FAST_C) return ARMv6::MTX44RotAxisRad_C_FAST(pOut, pAxis, fRad); #elif (MTX44ROTAXISRAD__CONFIG == D_FAST_ASM) #elif (MTX44ROTAXISRAD__CONFIG == D_FAST_C_ALGO) return ARMv6::MTX44RotAxisRad_C_FAST(pOut, pAxis, fRad); #elif (MTX44ROTAXISRAD__CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 回転行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 @param[in] fIdxX 1 円周を 256.0 とする単位での X 軸周りの角度 @param[in] fIdxY 1 円周を 256.0 とする単位での Y 軸周りの角度 @param[in] fIdxZ 1 円周を 256.0 とする単位での Z 軸周りの角度 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44RotXYZFIdx(MTX44* pOut, f32 fIdxX, f32 fIdxY, f32 fIdxZ) { #if defined( NN_HARDWARE_CTR ) #if (MTX44ROTXYZFIDX_CONFIG == D_ORG) return ARMv6::MTX44RotXYZFIdxC(pOut, fIdxX, fIdxY, fIdxZ); #elif (MTX44ROTXYZFIDX_CONFIG == D_FAST_C) return ARMv6::MTX44RotXYZFIdxC_FAST(pOut, fIdxX, fIdxY, fIdxZ); #elif (MTX44ROTXYZFIDX_CONFIG == D_FAST_ASM) #elif (MTX44ROTXYZFIDX_CONFIG == D_FAST_C_ALGO) #elif (MTX44ROTXYZFIDX_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief スケール変換用の行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pS それぞれの軸方向のスケール値が格納されたベクトルへのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Scale(MTX44* pOut, const VEC3* pS) { #if defined( NN_HARDWARE_CTR ) #if (MTX44SCALE_CONFIG == D_ORG) return ARMv6::MTX44ScaleC(pOut, pS); #elif (MTX44SCALE_CONFIG == D_FAST_C) return ARMv6::MTX44ScaleC_FAST(pOut, pS); #elif (MTX44SCALE_CONFIG == D_FAST_ASM) #elif (MTX44SCALE_CONFIG == D_FAST_C_ALGO) #elif (MTX44SCALE_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 平行移動用の行列を作成します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pM と同じ行列を指していても構いません。 @param[in] pT それぞれの軸方向の移動量が格納されたベクトルへのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Translate(MTX44* pOut, const VEC3* pT) { #if defined( NN_HARDWARE_CTR ) #if (MTX44TRANSLATE_CONFIG == D_ORG) return ARMv6::MTX44TranslateC(pOut, pT); #elif (MTX44TRANSLATE_CONFIG == D_FAST_C) return ARMv6::MTX44TranslateC_FAST(pOut, pT); #elif (MTX44TRANSLATE_CONFIG == D_FAST_ASM) #elif (MTX44TRANSLATE_CONFIG == D_FAST_C_ALGO) #elif (MTX44TRANSLATE_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*!--------------------------------------------------------------------------* @brief 行列の転置を取得します。 @param[in] pOut 計算結果を受け取るバッファへのポインタ。pSrcと同じ行列を指していても構いません。 @param[in] pSrc 元となる行列へのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Transpose(MTX44* pOut, const MTX44 *pSrc) { #if defined( NN_HARDWARE_CTR ) #if (MTX44TRANSPOSE_44_CONFIG == D_ORG) return ARMv6::MTX44TransposeC(pOut, pSrc); #elif (MTX44TRANSPOSE_44_CONFIG == D_FAST_C) #elif (MTX44TRANSPOSE_44_CONFIG == D_FAST_ASM) return ARMv6::MTX44TransposeAsm(pOut, pSrc); #elif (MTX44TRANSPOSE_44_CONFIG == D_FAST_C_ALGO) #elif (MTX44TRANSPOSE_44_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*! @} */ /*! @name ユーティリティ @{ */ /*!--------------------------------------------------------------------------* @brief ベクトルを行列で変換します。ベクトルの 4 要素目を 1 として計算します。 @param[out] pOut 計算結果を受け取るバッファへのポインタ。pV と同じベクトルを指していても構いません。 @param[in] pM 変換行列へのポインタ。 @param[in] pV 元となるベクトルへのポインタ。 @return pOut を返します。 *---------------------------------------------------------------------------*/ NN_FORCE_INLINE VEC4* VEC3Transform(VEC4* pOut, const MTX44* pM, const VEC3* pV) { #if defined( NN_HARDWARE_CTR ) #if (VEC3TRANSFORM_44XVEC3_CONFIG == D_ORG) return ARMv6::VEC3TransformC(pOut, pM, pV); #elif (VEC3TRANSFORM_44XVEC3_CONFIG == D_FAST_C) #elif (VEC3TRANSFORM_44XVEC3_CONFIG == D_FAST_ASM) return ARMv6::VEC3TransformAsm(pOut, pM, pV); #elif (VEC3TRANSFORM_44XVEC3_CONFIG == D_FAST_C_ALGO) #elif (VEC3TRANSFORM_44XVEC3_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*! @} */ /*! @name 行列 @{ */ /*---------------------------------------------------------------------------* Description: 画面方向に向けて射影行列を回転します。 Arguments: pOut 回転をおこなう行列へのポインタ pivot Returns: *---------------------------------------------------------------------------*/ NN_FORCE_INLINE MTX44* MTX44Pivot( MTX44* pOut, PivotDirection pivot ) { #if defined( NN_HARDWARE_CTR ) #if (MTX44PIVOT_CONFIG == D_ORG) return ARMv6::MTX44PivotC(pOut, pivot); #elif (MTX44PIVOT_CONFIG == D_FAST_C) return ARMv6::MTX44PivotC_FAST(pOut, pivot); #elif (MTX44PIVOT_CONFIG == D_FAST_ASM) #elif (MTX44PIVOT_CONFIG == D_FAST_C_ALGO) #elif (MTX44PIVOT_CONFIG == D_FAST_ASM_ALGO) #endif #else #endif // #if defined( NN_HARDWARE_CTR ) } /*! @} */ //-- const 引数を参照にしたオーバーロード inline MTX44* MTX44Copy(MTX44* pOut, const MTX44& m) { return MTX44Copy( pOut, &m ); } inline bool MTX44IsIdentity(const MTX44& m) { return MTX44IsIdentity( &m ); } inline MTX44* MTX44Add(MTX44* pOut, const MTX44& m1, const MTX44& m2) { return MTX44Add( pOut, &m1, &m2 ); } inline MTX44* MTX44Sub(MTX44* pOut, const MTX44& m1, const MTX44& m2) { return MTX44Sub( pOut, &m1, &m2 ); } inline MTX44* MTX44Mult(MTX44* pOut, const MTX44& m, f32 f) { return MTX44Mult( pOut, &m, f ); } inline MTX44* MTX44Mult(MTX44* pOut, const MTX44& m1, const MTX44& m2) { return MTX44Mult( pOut, &m1, &m2 ); } inline MTX44* MTX44Transpose(MTX44* pOut, const MTX44& m) { return MTX44Transpose( pOut, &m ); } inline MTX44* MTX44MultArray(MTX44* pOut, const MTX44& m1, const MTX44* pSrc, s32 count) { return MTX44MultArray( pOut, &m1, pSrc, count ); } inline u32 MTX44Inverse(MTX44* pOut, const MTX44& m) { return MTX44Inverse( pOut, &m ); } inline MTX44* MTX44RotAxisFIdx(MTX44* pOut, const VEC3& vAxis, f32 fIdx) { return MTX44RotAxisFIdx( pOut, &vAxis, fIdx ); } inline MTX44* MTX44RotAxisRad(MTX44* pOut, const VEC3& vAxis, f32 fRad) { return MTX44RotAxisRad( pOut, &vAxis, fRad ); } inline MTX44* MTX44RotAxisDeg(MTX44* pOut, const VEC3& vAxis, f32 fDeg) { return MTX44RotAxisDeg( pOut, &vAxis, fDeg ); } inline MTX44* MTX44Scale(MTX44* pOut, const VEC3& S) { return MTX44Scale(pOut, &S); } inline MTX44* MTX44MultScale(MTX44* pOut, const MTX44& M, const VEC3& S) { return MTX44MultScale(pOut, &M, &S); } inline MTX44* MTX44MultScale(MTX44* pOut, const VEC3& S, const MTX44& M) { return MTX44MultScale(pOut, &S, &M); } inline MTX44* MTX44Translate(MTX44* pOut, const VEC3& T) { return MTX44Translate(pOut, &T); } inline MTX44* MTX44MultTranslate(MTX44* pOut, const MTX44& M, const VEC3& T) { return MTX44MultTranslate(pOut, &M, &T); } inline MTX44* MTX44MultTranslate(MTX44* pOut, const VEC3& T, const MTX44& M) { return MTX44MultTranslate(pOut, &T, &M); } } // namespace math } // namespace nn #if defined(NN_MATH_AS_INLINE) #include #include #endif #pragma pop #endif