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