1/*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: math_Matrix44.ipp 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: 24529 $ 14 *---------------------------------------------------------------------------*/ 15 16#include <cmath> 17#include <nn/math/math_Vector3.h> 18 19namespace nn { 20namespace math { 21 22/* ------------------------------------------------------------------------ 23 MTX44 24 ------------------------------------------------------------------------ */ 25 26/*! 27 @name 行列 28 @{ 29*/ 30 31/*!--------------------------------------------------------------------------* 32 @brief 零行列を作成します。 33 34 @param[out] pOut 零行列を格納するバッファへのポインタ。 35 36 @return pOut を返します。 37 *---------------------------------------------------------------------------*/ 38NN_MATH_INLINE MTX44* 39MTX44Zero(MTX44* pOut) 40{ 41 pOut->f._00 = pOut->f._01 = pOut->f._02 = pOut->f._03 = 42 pOut->f._10 = pOut->f._11 = pOut->f._12 = pOut->f._13 = 43 pOut->f._20 = pOut->f._21 = pOut->f._22 = pOut->f._23 = 44 pOut->f._30 = pOut->f._31 = pOut->f._32 = pOut->f._33 = 0.f; 45 46 return pOut; 47} 48 49 50/*!--------------------------------------------------------------------------* 51 @brief 単位行列を作成します。 52 53 @param[out] pOut 単位行列を格納するバッファへのポインタ。 54 55 @return pOut を返します。 56 *---------------------------------------------------------------------------*/ 57NN_MATH_INLINE MTX44* 58MTX44Identity(MTX44* pOut) 59{ 60 NN_NULL_ASSERT( pOut ); 61 62 MTX44Copy(pOut, MTX44::Identity()); 63 64 return pOut; 65} 66 67/*!--------------------------------------------------------------------------* 68 @brief 行列の差を計算します。 69 70 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。 71 @param[in] p1 左辺値へのポインタ。 72 @param[in] p2 右辺値へのポインタ。 73 74 @return pOut を返します。 75 *---------------------------------------------------------------------------*/ 76NN_MATH_INLINE MTX44* 77MTX44Sub(MTX44* pOut, const MTX44* p1, const MTX44* p2) 78{ 79 pOut->f._00 = p1->f._00 - p2->f._00; 80 pOut->f._01 = p1->f._01 - p2->f._01; 81 pOut->f._02 = p1->f._02 - p2->f._02; 82 pOut->f._03 = p1->f._03 - p2->f._03; 83 84 pOut->f._10 = p1->f._10 - p2->f._10; 85 pOut->f._11 = p1->f._11 - p2->f._11; 86 pOut->f._12 = p1->f._12 - p2->f._12; 87 pOut->f._13 = p1->f._13 - p2->f._13; 88 89 pOut->f._20 = p1->f._20 - p2->f._20; 90 pOut->f._21 = p1->f._21 - p2->f._21; 91 pOut->f._22 = p1->f._22 - p2->f._22; 92 pOut->f._23 = p1->f._23 - p2->f._23; 93 94 pOut->f._30 = p1->f._30 - p2->f._30; 95 pOut->f._31 = p1->f._31 - p2->f._31; 96 pOut->f._32 = p1->f._32 - p2->f._32; 97 pOut->f._33 = p1->f._33 - p2->f._33; 98 99 return pOut; 100} 101 102/*!--------------------------------------------------------------------------* 103 @brief 行列が単位行列かどうか判定します。 104 105 @param[in] p 判定対象の行列へのポインタ。 106 107 @return p が単位行列であれば true そうでなければ false を返します。 108 *---------------------------------------------------------------------------*/ 109NN_MATH_INLINE bool 110MTX44IsIdentity(const MTX44* p) 111{ 112 return p->f._00 == 1.f && p->f._01 == 0.f && p->f._02 == 0.f && p->f._03 == 0.f && 113 p->f._10 == 0.f && p->f._11 == 1.f && p->f._12 == 0.f && p->f._13 == 0.f && 114 p->f._20 == 0.f && p->f._21 == 0.f && p->f._22 == 1.f && p->f._23 == 0.f && 115 p->f._30 == 0.f && p->f._31 == 0.f && p->f._32 == 0.f && p->f._33 == 1.f; 116} 117#if 0 118namespace { 119 /*---------------------------------------------------------------------------* 120 Description: 画面方向に向けて射影行列を回転します。 121 122 Arguments: pOut 回転をおこなう行列へのポインタ 123 pivot 124 125 Returns: 126 *---------------------------------------------------------------------------*/ 127 inline MTX44* 128 MTX44Pivot( MTX44* pOut, PivotDirection pivot ) 129 { 130 // TODO: 処理の最適化が必要。 131 132 const f32 PIVOT_ROTATION_SIN_COS[ PIVOT_NUM ][ 2 ] = 133 { 134 #ifdef NN_PLATFORM_CTR 135 { 0.0f, 1.0f }, // NONE 136 { -1.0f, 0.0f }, // TO_UP 137 { 0.0f, -1.0f }, // TO_RIGHT 138 { 1.0f, 0.0f }, // TO_BOTTOM 139 { 0.0f, 1.0f }, // TO_LEFT 140 #else 141 { 0.0f, 1.0f }, // NONE 142 { 0.0f, 1.0f }, // TO_UP 143 { -1.0f, 0.0f }, // TO_RIGHT 144 { 0.0f, -1.0f }, // TO_BOTTOM 145 { 1.0f, 0.0f }, // TO_LEFT 146 #endif 147 }; 148 149 if ( pivot == PIVOT_NONE ) 150 { 151 return pOut; 152 } 153 154 f32 sin = PIVOT_ROTATION_SIN_COS[ pivot ][ 0 ]; 155 f32 cos = PIVOT_ROTATION_SIN_COS[ pivot ][ 1 ]; 156 157 f32 (*const m)[4] = pOut->m; 158 159 if ( sin == 0.0f ) 160 { 161 m[0][0] = cos * m[0][0]; 162 m[0][1] = cos * m[0][1]; 163 m[0][2] = cos * m[0][2]; 164 m[0][3] = cos * m[0][3]; 165 166 m[1][0] = cos * m[1][0]; 167 m[1][1] = cos * m[1][1]; 168 m[1][2] = cos * m[1][2]; 169 m[1][3] = cos * m[1][3]; 170 } 171 else // if ( cos == 0.0f ) 172 { 173 f32 tmp = m[0][0]; 174 m[0][0] = -sin * m[1][0]; 175 m[1][0] = sin * tmp; 176 177 tmp = m[0][1]; 178 m[0][1] = -sin * m[1][1]; 179 m[1][1] = sin * tmp; 180 181 tmp = m[0][2]; 182 m[0][2] = -sin * m[1][2]; 183 m[1][2] = sin * tmp; 184 185 tmp = m[0][3]; 186 m[0][3] = -sin * m[1][3]; 187 m[1][3] = sin * tmp; 188 } 189 190 return pOut; 191 } 192 193} // namespace 194#endif 195 196/*!--------------------------------------------------------------------------* 197 @brief 画面の回転を掛けた射影行列を作成します。 198 射影行列をニアクリッピング面での視錐台を元に作成します。 199 200 @param[out] pOut 射影行列を格納する行列へのポインタ。 201 @param[in] l ニアクリッピング面での視錐台左辺の X 座標 202 @param[in] r ニアクリッピング面での視錐台右辺の X 座標 203 @param[in] b ニアクリッピング面での視錐台下辺の Y 座標 204 @param[in] t ニアクリッピング面での視錐台上辺の Y 座標 205 @param[in] n ニアクリッピング面までの距離。 206 @param[in] f ファークリッピング面までの距離。 207 @param[in] pivot 画面の回転方向 208 209 @return pOut を返します。 210 *---------------------------------------------------------------------------*/ 211NN_MATH_INLINE MTX44* 212MTX44FrustumPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot) 213{ 214 MTX44Frustum( pOut, l, r, b, t, n, f ); 215 MTX44Pivot( pOut, pivot ); 216 217 return pOut; 218} 219 220/*!--------------------------------------------------------------------------* 221 @brief 画面の回転を掛けた射影行列を作成します。 222 正射影行列を作成します。 223 224 @param[out] pOut 射影行列を格納する行列へのポインタ。 225 @param[in] l ニアクリッピング面での視錐台左辺の X 座標 226 @param[in] r ニアクリッピング面での視錐台右辺の X 座標 227 @param[in] b ニアクリッピング面での視錐台下辺の Y 座標 228 @param[in] t ニアクリッピング面での視錐台上辺の Y 座標 229 @param[in] n ニアクリッピング面までの距離。 230 @param[in] f ファークリッピング面までの距離。 231 @param[in] pivot 画面の回転方向 232 233 @return pOut を返します。 234 *---------------------------------------------------------------------------*/ 235NN_MATH_INLINE MTX44* 236MTX44OrthoPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot) 237{ 238 MTX44Ortho( pOut, l, r, b, t, n, f ); 239 MTX44Pivot( pOut, pivot ); 240 241 return pOut; 242} 243 244/*!--------------------------------------------------------------------------* 245 @brief 画面の回転を掛けた射影行列を作成します。 246 射影行列を視野角とアスペクト比から作成します。 247 248 @param[out] pOut 射影行列を格納する行列へのポインタ。 249 @param[in] fovy 縦方向の視野角(Radian) 250 @param[in] aspect 視野のアスペクト比(幅/高さ) 251 @param[in] n ニアクリッピング面までの距離。 252 @param[in] f ファークリッピング面までの距離。 253 @param[in] pivot 画面の回転方向 254 255 @return pOut を返します。 256 *---------------------------------------------------------------------------*/ 257NN_MATH_INLINE MTX44* 258MTX44PerspectivePivotRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f, PivotDirection pivot) 259{ 260 MTX44PerspectiveRad( pOut, fovy, aspect, n, f ); 261 MTX44Pivot( pOut, pivot ); 262 263 return pOut; 264} 265 266 267 268 269 270/*!--------------------------------------------------------------------------* 271 @brief 行列の配列に左から行列を掛けます。 272 273 @param[out] pOut 計算結果を受け取る配列の先頭へのポインタ。 274 @param[in] p1 左辺値となる行列へのポインタ。 275 @param[in] pSrc 右辺値となる行列の配列の先頭へのポインタ 276 @param[in] count 右辺値なる行列の配列の要素数 277 278 @return pOut を返します。 279 *---------------------------------------------------------------------------*/ 280NN_MATH_INLINE MTX44* 281MTX44MultArray(MTX44* pOut, const MTX44* __restrict p1, const MTX44* __restrict pSrc, s32 count) 282{ 283 MTX44* pOutBase = pOut; 284 285 NN_NULL_ASSERT( pOut ); 286 NN_NULL_ASSERT( p1 ); 287 NN_NULL_ASSERT( pSrc ); 288 NN_ASSERT( count > 1 ); 289 290 for ( s32 i = 0 ; i < count ; i++ ) 291 { 292 MTX44Mult(pOut, p1, pSrc); 293 294 pSrc++; 295 pOut++; 296 } 297 298 return pOutBase; 299} 300 301namespace { 302 inline void SwapF(f32 &a, f32 &b) 303 { 304 f32 tmp; 305 tmp = a; 306 a = b; 307 b = tmp; 308 } 309} // namespace (unnamed) 310 311 312/*!--------------------------------------------------------------------------* 313 @brief 指定する軸の周りを回転させる回転行列を作成します。 314 315 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 316 @param[in] pAxis 回転軸を指定するベクトルへのポインタ。 317 @param[in] fIdx 1 円周を 256.0 とする単位での回転量 318 319 @return pOut を返します。 320 *---------------------------------------------------------------------------*/ 321NN_MATH_INLINE MTX44* 322MTX44RotAxisFIdx(MTX44* pOut, const VEC3* pAxis, f32 fIdx) 323{ 324 // とりあえずは遅くてもいい 325 MTX44RotAxisRad_(pOut, pAxis, NN_MATH_FIDX_TO_RAD(fIdx)); 326 327 return pOut; 328} 329 330 331 332/*! 333 @} 334*/ 335 336} // namespace math 337} // namespace nn 338