1/*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: math_Matrix34.ipp 4 5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain proprietary 8 information of Nintendo and/or its licensed developers and are protected by 9 national and international copyright laws. They may not be disclosed to third 10 parties or copied or duplicated in any form, in whole or in part, without the 11 prior written consent of Nintendo. 12 13 The content herein is highly confidential and should be handled accordingly. 14 15 $Revision: 31311 $ 16 *---------------------------------------------------------------------------*/ 17#include <cmath> 18#include <nw/math/math_Vector3.h> 19 20namespace nw { 21namespace math { 22using namespace nn::math; 23 24/*!--------------------------------------------------------------------------* 25 @brief カメラ行列を設定します。 26 27 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 28 @param[in] pCamPos カメラの位置を指定するベクトルへのポインタ。 29 @param[in] twist カメラの視線方向に対する1 円周を 256.0 とする単位での回転角度。 30 @param[in] pTarget カメラの注視点を指定するベクトルへのポインタ。 31 32 @return pOut を返します。 33 *---------------------------------------------------------------------------*/ 34NW_MATH_INLINE MTX34* 35MTX34LookAtFIdx( 36 nw::math::MTX34* pOut, const nw::math::VEC3* pCamPos, f32 twist, const nw::math::VEC3* pTarget) 37{ 38 using namespace nw::math; 39 40 NW_NULL_ASSERT(pOut); 41 NW_NULL_ASSERT(pCamPos); 42 NW_NULL_ASSERT(pTarget); 43 44 f32 (*const m)[4] = pOut->m; 45 46 // カメラ座標系のZ方向 47 VEC3 lookReverse(pCamPos->x - pTarget->x, pCamPos->y - pTarget->y, pCamPos->z - pTarget->z); 48 49 if ((lookReverse.x == 0.0f) && (lookReverse.z == 0.0f)) 50 { 51 // カメラとターゲットのXZ座標が同じ場合ツイストは定義されない 52 m[0][0] = 1.0f; 53 m[0][1] = 0.0f; 54 m[0][2] = 0.0f; 55 m[0][3] = -pCamPos->x; 56 57 m[1][0] = 0.0f; 58 m[1][1] = 0.0f; 59 60 m[2][0] = 0.0f; 61 m[2][2] = 0.0f; 62 63 if (lookReverse.y <= 0.0f) 64 { 65 // 真上を見るとき 66 m[1][2] = 1.0f; 67 m[1][3] = -pCamPos->z; 68 69 m[2][1] = -1.0f; 70 m[2][3] = pCamPos->y; 71 } 72 else 73 { 74 // 真下を見るとき 75 m[1][2] = -1.0f; 76 m[1][3] = pCamPos->z; 77 78 m[2][1] = 1.0f; 79 m[2][3] = -pCamPos->y; 80 } 81 } 82 else 83 { 84 // カメラ座標系のX方向 85 VEC3 r(lookReverse.z, 0.0f, -lookReverse.x); 86 87 VEC3Normalize(&lookReverse, &lookReverse); 88 VEC3Normalize(&r, &r); 89 90 // カメラ座標系のY方向 91 VEC3 u; 92 VEC3Cross(&u, &lookReverse, &r); 93 94 f32 st, ct; 95 SinCosFIdx(&st, &ct, twist); 96 VEC3 right, up; 97 98 // r軸, u軸をru平面上でcameraTwistだけ半時計回りに回転させてrightを求める 99 // r.y == 0であることに注意 100 right.x = st * u.x + ct * r.x; 101 right.y = st * u.y; 102 right.z = st * u.z + ct * r.z; 103 104 up.x = ct * u.x - st * r.x; 105 up.y = ct * u.y; 106 up.z = ct * u.z - st * r.z; 107 108 // right 109 m[0][0] = right.x; 110 m[0][1] = right.y; 111 m[0][2] = right.z; 112 m[0][3] = -VEC3Dot(pCamPos, &right); 113 114 // up 115 m[1][0] = up.x; 116 m[1][1] = up.y; 117 m[1][2] = up.z; 118 m[1][3] = -VEC3Dot(pCamPos, &up); 119 120 // look 121 m[2][0] = lookReverse.x; 122 m[2][1] = lookReverse.y; 123 m[2][2] = lookReverse.z; 124 m[2][3] = -VEC3Dot(pCamPos, &lookReverse); 125 } 126 127 return pOut; 128} 129 130/*!--------------------------------------------------------------------------* 131 @brief カメラ行列を設定します。 132 133 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 134 @param[in] pCamPos カメラの位置を指定するベクトルへのポインタ。 135 @param[in] pCamRotate 1 円周を 256.0 とする単位でのカメラの回転量を指定するベクトルへのポインタ。 136 137 @return pOut を返します。 138 *---------------------------------------------------------------------------*/ 139NW_MATH_INLINE MTX34* 140MTX34CameraRotateFIdx( 141 nw::math::MTX34* pOut, const nw::math::VEC3* pCamPos, const nw::math::VEC3* pCamRotate) 142{ 143 using namespace nw::math; 144 145 NW_NULL_ASSERT(pOut); 146 NW_NULL_ASSERT(pCamPos); 147 NW_NULL_ASSERT(pCamRotate); 148 149 f32 (*const m)[4] = pOut->m; 150 151 f32 sx, sy, sz, cx, cy, cz; 152 SinCosFIdx(&sx, &cx, pCamRotate->x); 153 SinCosFIdx(&sy, &cy, pCamRotate->y); 154 SinCosFIdx(&sz, &cz, pCamRotate->z); 155 156 // Z軸, X軸, Y軸の順番で回転させている 157 VEC3 right, up, back; 158 159 right.x = sx * sy * sz + cy * cz; 160 right.y = cx * sz; 161 right.z = sx * cy * sz - sy * cz; 162 163 up.x = sx * sy * cz - cy * sz; 164 up.y = cx * cz; 165 up.z = sx * cy * cz + sy * sz; 166 167 back.x = cx * sy; 168 back.y = - sx; 169 back.z = cx * cy; 170 171 m[0][0] = right.x; 172 m[0][1] = right.y; 173 m[0][2] = right.z; 174 m[0][3] = -VEC3Dot(pCamPos, &right); 175 176 m[1][0] = up.x; 177 m[1][1] = up.y; 178 m[1][2] = up.z; 179 m[1][3] = -VEC3Dot(pCamPos, &up); 180 181 m[2][0] = back.x; 182 m[2][1] = back.y; 183 m[2][2] = back.z; 184 m[2][3] = -VEC3Dot(pCamPos, &back); 185 186 return pOut; 187} 188 189/*!--------------------------------------------------------------------------* 190 @brief カメラ行列を設定します。 191 192 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 193 @param[in] pCamPos カメラの位置を指定するベクトルへのポインタ。 194 @param[in] pCamRotate ラジアン単位でのカメラの回転量を指定するベクトルへのポインタ。 195 196 @return pOut を返します。 197 *---------------------------------------------------------------------------*/ 198NW_MATH_INLINE MTX34* 199MTX34CameraRotateRad(MTX34* pOut, const VEC3* pCamPos, const VEC3* pCamRotate) 200{ 201 VEC3 rotateFIdx; 202 rotateFIdx.x = NW_MATH_RAD_TO_FIDX(pCamRotate->x); 203 rotateFIdx.y = NW_MATH_RAD_TO_FIDX(pCamRotate->y); 204 rotateFIdx.z = NW_MATH_RAD_TO_FIDX(pCamRotate->z); 205 206 return MTX34CameraRotateFIdx(pOut, pCamPos, &rotateFIdx); 207} 208 209/*!--------------------------------------------------------------------------* 210 @brief カメラ行列を設定します。 211 212 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 213 @param[in] pCamPos カメラの位置を指定するベクトルへのポインタ。 214 @param[in] twist カメラの視線方向に対するラジアン単位での回転角度。 215 @param[in] pTarget カメラの注視点を指定するベクトルへのポインタ。 216 217 @return pOut を返します。 218 *---------------------------------------------------------------------------*/ 219NW_MATH_INLINE MTX34* 220MTX34LookAtRad(MTX34* pOut, const VEC3* pCamPos, f32 twist, const VEC3* pTarget) 221{ 222 f32 twistFIdx = NW_MATH_RAD_TO_FIDX(twist); 223 return MTX34LookAtFIdx(pOut, pCamPos, twistFIdx, pTarget); 224} 225 226/*!--------------------------------------------------------------------------* 227 @brief 行列からスケール値を取得します。 228 右からかけたスケールを取り出します。 229 230 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 231 @param[in] pM スケールを取り出す行列へのポインタ。 232 233 @return pOut を返します。 234 *---------------------------------------------------------------------------*/ 235NW_MATH_INLINE VEC3* 236MTX34DecomposeToColumnScale(VEC3* pOut, const MTX34* pM) 237{ 238 pOut->x = FSqrt((pM->f._00 * pM->f._00) + (pM->f._10 * pM->f._10) + (pM->f._20 * pM->f._20)); 239 pOut->y = FSqrt((pM->f._01 * pM->f._01) + (pM->f._11 * pM->f._11) + (pM->f._21 * pM->f._21)); 240 pOut->z = FSqrt((pM->f._02 * pM->f._02) + (pM->f._12 * pM->f._12) + (pM->f._22 * pM->f._22)); 241 242 return pOut; 243} 244 245/*!--------------------------------------------------------------------------* 246 @brief 行列からスケール値を取得します。 247 左からかけたスケールを取り出します。 248 249 @param[out] pOut 計算結果を受け取るバッファへのポインタ。 250 @param[in] pM スケールを取り出す行列へのポインタ。 251 252 @return pOut を返します。 253 *---------------------------------------------------------------------------*/ 254NW_MATH_INLINE VEC3* 255MTX34DecomposeToRowScale(VEC3* pOut, const MTX34* pM) 256{ 257 pOut->x = FSqrt((pM->f._00 * pM->f._00) + (pM->f._01 * pM->f._01) + (pM->f._02 * pM->f._02)); 258 pOut->y = FSqrt((pM->f._10 * pM->f._10) + (pM->f._11 * pM->f._11) + (pM->f._12 * pM->f._12)); 259 pOut->z = FSqrt((pM->f._20 * pM->f._20) + (pM->f._21 * pM->f._21) + (pM->f._22 * pM->f._22)); 260 261 return pOut; 262} 263 264} // namespace math 265} // namespace nw 266