1/*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: math_Matrix34.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: 24035 $ 14 *---------------------------------------------------------------------------*/ 15#include <cmath> 16#include <nn/math/math_Vector3.h> 17 18namespace nn { 19namespace math { 20 21 22/* ------------------------------------------------------------------------ 23 MTX34 24 ------------------------------------------------------------------------ */ 25 26/*! 27 @name 行列 28 @{ 29*/ 30 31/*!--------------------------------------------------------------------------* 32 @brief 零行列を作成します。 33 34 @param[out] pOut 零行列を格納するバッファへのポインタ。 35 36 @return pOut を返します。 37 *---------------------------------------------------------------------------*/ 38NN_MATH_INLINE MTX34* 39MTX34Zero(MTX34* 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 = 0.f; 44 45 return pOut; 46} 47 48/*!--------------------------------------------------------------------------* 49 @brief 単位行列を作成します。 50 51 @param[out] pOut 単位行列を格納するバッファへのポインタ。 52 53 @return pOut を返します。 54 *---------------------------------------------------------------------------*/ 55NN_MATH_INLINE MTX34* 56MTX34Identity(MTX34* pOut) 57{ 58 NN_NULL_ASSERT( pOut ); 59 60 MTX34Copy(pOut, MTX34::Identity()); 61 62 return pOut; 63} 64 65 66/*!--------------------------------------------------------------------------* 67 @brief 行列が単位行列かどうか判定します。 68 69 @param[in] p 判定対象の行列へのポインタ。 70 71 @return p が単位行列であれば true そうでなければ false を返します。 72 *---------------------------------------------------------------------------*/ 73NN_MATH_INLINE bool 74MTX34IsIdentity(const MTX34* p) 75{ 76 return p->f._00 == 1.f && p->f._01 == 0.f && p->f._02 == 0.f && p->f._03 == 0.f && 77 p->f._10 == 0.f && p->f._11 == 1.f && p->f._12 == 0.f && p->f._13 == 0.f && 78 p->f._20 == 0.f && p->f._21 == 0.f && p->f._22 == 1.f && p->f._23 == 0.f; 79} 80 81/*!--------------------------------------------------------------------------* 82 @brief 行列の差を計算します。 83 84 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じ行列を指していても構いません。 85 @param[in] p1 左辺値へのポインタ。 86 @param[in] p2 右辺値へのポインタ。 87 88 @return pOut を返します。 89 *---------------------------------------------------------------------------*/ 90NN_MATH_INLINE MTX34* 91MTX34Sub(MTX34* pOut, const MTX34* p1, const MTX34* p2) 92{ 93 pOut->f._00 = p1->f._00 - p2->f._00; 94 pOut->f._01 = p1->f._01 - p2->f._01; 95 pOut->f._02 = p1->f._02 - p2->f._02; 96 pOut->f._03 = p1->f._03 - p2->f._03; 97 98 pOut->f._10 = p1->f._10 - p2->f._10; 99 pOut->f._11 = p1->f._11 - p2->f._11; 100 pOut->f._12 = p1->f._12 - p2->f._12; 101 pOut->f._13 = p1->f._13 - p2->f._13; 102 103 pOut->f._20 = p1->f._20 - p2->f._20; 104 pOut->f._21 = p1->f._21 - p2->f._21; 105 pOut->f._22 = p1->f._22 - p2->f._22; 106 pOut->f._23 = p1->f._23 - p2->f._23; 107 108 return pOut; 109} 110 111 112/*!--------------------------------------------------------------------------* 113 @brief 指定する軸の周りを回転させる回転行列を作成します。 114 115 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 116 @param[in] pAxis 回転軸を指定するベクトルへのポインタ。 117 @param[in] fIdx 1 円周を 256.0 とする単位での回転量 118 119 @return pOut を返します。 120 *---------------------------------------------------------------------------*/ 121NN_MATH_INLINE MTX34* 122MTX34RotAxisFIdx(MTX34* pOut, const VEC3* pAxis, f32 fIdx) 123{ 124 // とりあえずは遅くてもいい 125 MTX34RotAxisRad_(pOut, pAxis, NN_MATH_FIDX_TO_RAD(fIdx)); 126 127 return pOut; 128} 129 130 131/*!--------------------------------------------------------------------------* 132 @brief 回転行列に平行移動行列を左から掛けた行列を作成します。 133 134 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 135 @param[in] fIdxX 1 円周を 256.0 とする単位での X 軸周りの角度 136 @param[in] fIdxY 1 円周を 256.0 とする単位での Y 軸周りの角度 137 @param[in] fIdxZ 1 円周を 256.0 とする単位での Z 軸周りの角度 138 @param[in] pT それぞれの軸方向の移動量が格納されたベクトルへのポインタ。 139 140 @return pOut を返します。 141 *---------------------------------------------------------------------------*/ 142NN_MATH_INLINE MTX34* 143MTX34RotXYZTranslateFIdx(MTX34* pOut, f32 fIdxX, f32 fIdxY, f32 fIdxZ, const VEC3* pT) 144{ 145 (void)MTX34RotXYZFIdx(pOut, fIdxX, fIdxY, fIdxZ); 146 pOut->f._03 = pT->x; 147 pOut->f._13 = pT->y; 148 pOut->f._23 = pT->z; 149 return pOut; 150} 151 152/*!--------------------------------------------------------------------------* 153 @brief 3x4行列の逆転置行列を計算して3x3行列に格納します。 154 155 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 156 @param[in] p 元となる行列へのポインタ。 157 158 @return 逆行列が存在すれば 1 を、存在しなければ 0 を返します。 159 *---------------------------------------------------------------------------*/ 160NN_MATH_INLINE u32 161MTX34InvTranspose(MTX33* pOut, const MTX34* __restrict p) 162{ 163 MTX34 tmp; 164 u32 rval = MTX34InvTranspose(&tmp, p); 165 (void)MTX34ToMTX33(pOut, &tmp); 166 return rval; 167} 168 169 170/*!--------------------------------------------------------------------------* 171 @brief 行列の配列に左から行列を掛けます。 172 173 @param[out] pOut 計算結果を受け取る配列の先頭へのポインタ。 174 @param[in] p1 左辺値となる行列へのポインタ。 175 @param[in] pSrc 右辺値となる行列の配列の先頭へのポインタ 176 @param[in] count 右辺値なる行列の配列の要素数 177 178 @return pOut を返します。 179 *---------------------------------------------------------------------------*/ 180NN_MATH_INLINE MTX34* 181MTX34MultArray(MTX34* pOut, const MTX34* __restrict p1, const MTX34* __restrict pSrc, s32 count) 182{ 183 MTX34* pOutBase = pOut; 184 185 NN_NULL_ASSERT( pOut ); 186 NN_NULL_ASSERT( p1 ); 187 NN_NULL_ASSERT( pSrc ); 188 NN_ASSERT( count > 1 ); 189 190 for ( s32 i = 0 ; i < count ; i++ ) 191 { 192 MTX34Mult(pOut, p1, pSrc); 193 194 pSrc++; 195 pOut++; 196 } 197 198 return pOutBase; 199} 200 201/*!--------------------------------------------------------------------------* 202 @brief テクスチャマトリクス用射影行列を視錐体を元に作成します。 203 204 @param[out] pOut 計算結果を受け取るバッファへのポインタです。 205 @param[in] l ニアクリップの左辺です。 206 @param[in] r ニアクリップの右辺です。 207 @param[in] b ニアクリップの下辺です。 208 @param[in] t ニアクリップの上辺です。 209 @param[in] n カメラからニアクリップまでの距離です。 210 @param[in] scaleS S軸方向のスケール値です。 211 @param[in] scaleT T軸方向のスケール値です。 212 @param[in] translateS S軸方向の移動値です。 213 @param[in] translateT T軸方向の移動値です。 214 215 @return pOut を返します。 216 *---------------------------------------------------------------------------*/ 217NN_MATH_INLINE MTX34* 218MTX34TextureProjectionFrustum(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT) 219{ 220 NN_ASSERT(t != b); 221 NN_ASSERT(l != r); 222 NN_NULL_ASSERT(pOut); 223 224 f32 reverseWidth = 1.0f / (r - l); 225 226 f32 (*const mtx)[4] = pOut->m; 227 228 mtx[0][0] = ((2.0f * n) * reverseWidth) * scaleS; 229 mtx[0][1] = 0.0f; 230 mtx[0][2] = (((r + l) * reverseWidth) * scaleS) - translateS; 231 mtx[0][3] = 0.0f; 232 233 f32 reverseHeight = 1.0f / (t - b); 234 mtx[1][0] = 0.0f; 235 mtx[1][1] = ((2.0f * n) * reverseHeight) * scaleT; 236 mtx[1][2] = (((t+ b) * reverseHeight) * scaleT) - translateT; 237 mtx[1][3] = 0.0f; 238 239 mtx[2][0] = 0.0f; 240 mtx[2][1] = 0.0f; 241 mtx[2][2] = -1.0f; 242 mtx[2][3] = 0.0f; 243 return pOut; 244} 245 246/*!--------------------------------------------------------------------------* 247 @brief テクスチャマトリクス用射影行列を作成します。 248 249 @param[out] pOut 計算結果を受け取るバッファへのポインタです。 250 @param[in] fovy 垂直視野角です。単位はラジアンです。 251 @param[in] aspect クリップ面のアスペクト比です。 252 @param[in] scaleS S軸方向のスケール値です。 253 @param[in] scaleT T軸方向のスケール値です。 254 @param[in] translateS S軸方向の移動値です。 255 @param[in] translateT T軸方向の移動値です。 256 257 @return pOut を返します。 258 *---------------------------------------------------------------------------*/ 259NN_MATH_INLINE MTX34* 260MTX34TextureProjectionPerspective(MTX34* pOut, f32 fovy, f32 aspect, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT) 261{ 262 NN_ASSERT((fovy > 0.0f) && (fovy < math::F_PI)); 263 NN_ASSERT(aspect != 0.0f); 264 NN_NULL_ASSERT(pOut); 265 266 float angle = fovy * 0.5f; 267 float cot = 1.0f / math::TanRad(angle); 268 269 f32 (*const mtx)[4] = pOut->m; 270 271 mtx[0][0] = (cot / aspect) * scaleS; 272 mtx[0][1] = 0.0f; 273 mtx[0][2] = -translateS; 274 mtx[0][3] = 0.0f; 275 276 mtx[1][0] = 0.0f; 277 mtx[1][1] = cot * scaleT; 278 mtx[1][2] = -translateT; 279 mtx[1][3] = 0.0f; 280 281 mtx[2][0] = 0.0f; 282 mtx[2][1] = 0.0f; 283 mtx[2][2] = -1.0f; 284 mtx[2][3] = 0.0f; 285 286 return pOut; 287} 288 289/*!--------------------------------------------------------------------------* 290 @brief テクスチャマトリクス用平行射影行列を作成します。 291 292 @param[out] pOut 計算結果を受け取るバッファへのポインタです。 293 @param[in] l ニアクリップの左辺です。 294 @param[in] r ニアクリップの右辺です。 295 @param[in] b ニアクリップの下辺です。 296 @param[in] t ニアクリップの上辺です。 297 @param[in] scaleS S軸方向のスケール値です。 298 @param[in] scaleT T軸方向のスケール値です。 299 @param[in] translateS S軸方向の移動値です。 300 @param[in] translateT T軸方向の移動値です。 301 302 @return pOut を返します。 303 *---------------------------------------------------------------------------*/ 304NN_MATH_INLINE MTX34* 305MTX34TextureProjectionOrtho(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT) 306{ 307 NN_ASSERT(t != b); 308 NN_ASSERT(l != r); 309 NN_NULL_ASSERT(pOut); 310 311 float reverseWidth = 1.0f / (r - l); 312 313 f32 (*const mtx)[4] = pOut->m; 314 315 mtx[0][0] = 2.0f * reverseWidth * scaleS; 316 mtx[0][1] = 0.0f; 317 mtx[0][2] = 0.0f; 318 mtx[0][3] = ((-(r + l) * reverseWidth) * scaleS) + translateS; 319 320 float reverseHeight = 1.0f / (t - b); 321 mtx[1][0] = 0.0f; 322 mtx[1][1] = (2.0f * reverseHeight) * scaleT; 323 mtx[1][2] = 0.0f; 324 mtx[1][3] = ((-(t + b) * reverseHeight) * scaleT) + translateT; 325 326 mtx[2][0] = 0.0f; 327 mtx[2][1] = 0.0f; 328 mtx[2][2] = 0.0f; 329 mtx[2][3] = 1.0f; 330 return pOut; 331} 332 333/*! 334 @} 335*/ 336 337 338} // namespace math 339} // namespace nn 340