1/*---------------------------------------------------------------------------*
2  Project:  Horizon
3  File:     math_Vector3.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: 17995 $
14 *---------------------------------------------------------------------------*/
15
16#include <cmath>
17
18namespace nn {
19namespace math {
20
21/* ------------------------------------------------------------------------
22        VEC3
23   ------------------------------------------------------------------------ */
24
25/*!
26    @name    ベクトル
27    @{
28*/
29
30/*!--------------------------------------------------------------------------*
31  @brief        ベクトルがゼロベクトルかどうか判定します。
32
33  @param[in]    p    判定対象のベクトルへのポインタ。
34
35  @return       p がゼロベクトルであれば true そうでなければ false を返します。
36 *---------------------------------------------------------------------------*/
37NN_MATH_INLINE bool
38VEC3IsZero(const VEC3* p)
39{
40    return p->x == 0.f && p->y == 0.f && p->z == 0.f;
41}
42
43/*!--------------------------------------------------------------------------*
44  @brief        2つのベクトルのそれぞれの成分の最大値から構成されるベクトルを作成します。
45
46  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
47  @param[in]    p1    対象のベクトル1へのポインタ。
48  @param[in]    p2    対象のベクトル2へのポインタ。
49
50  @return       pOut を返します。
51 *---------------------------------------------------------------------------*/
52NN_MATH_INLINE VEC3*
53VEC3Maximize(VEC3* pOut, const VEC3* p1, const VEC3* p2)
54{
55    pOut->x = (p1->x > p2->x) ? p1->x : p2->x;
56    pOut->y = (p1->y > p2->y) ? p1->y : p2->y;
57    pOut->z = (p1->z > p2->z) ? p1->z : p2->z;
58
59    return pOut;
60}
61
62
63
64/*!--------------------------------------------------------------------------*
65  @brief        2つのベクトルのそれぞれの成分の最小値から構成されるベクトルを作成します。
66
67  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
68  @param[in]    p1    対象のベクトル1へのポインタ。
69  @param[in]    p2    対象のベクトル2へのポインタ。
70
71  @return       pOut を返します。
72 *---------------------------------------------------------------------------*/
73NN_MATH_INLINE VEC3*
74VEC3Minimize(VEC3* pOut, const VEC3* p1, const VEC3* p2)
75{
76    pOut->x = (p1->x < p2->x) ? p1->x : p2->x;
77    pOut->y = (p1->y < p2->y) ? p1->y : p2->y;
78    pOut->z = (p1->z < p2->z) ? p1->z : p2->z;
79
80    return pOut;
81}
82
83
84/*!--------------------------------------------------------------------------*
85  @brief        ベクトルの外積を計算します。
86
87  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。
88                      p1, p2 と同じベクトルを指していても構いません。
89  @param[in]    p1    左辺値へのポインタ
90  @param[in]    p2    右辺値へのポインタ
91
92  @return       pOut を返します。
93 *---------------------------------------------------------------------------*/
94NN_MATH_INLINE VEC3*
95VEC3Cross(VEC3* pOut, const VEC3* p1, const VEC3* p2)
96{
97    NN_NULL_ASSERT(pOut);
98    NN_NULL_ASSERT(p1);
99    NN_NULL_ASSERT(p2);
100
101    VEC3 tmpVec;
102
103    tmpVec.x = ( p1->y * p2->z ) - ( p1->z * p2->y );
104    tmpVec.y = ( p1->z * p2->x ) - ( p1->x * p2->z );
105    tmpVec.z = ( p1->x * p2->y ) - ( p1->y * p2->x );
106
107    pOut->x = tmpVec.x;
108    pOut->y = tmpVec.y;
109    pOut->z = tmpVec.z;
110
111    return pOut;
112}
113
114
115/*!--------------------------------------------------------------------------*
116  @brief        ベクトルを正規化します。
117                正規化に失敗した場合は指定されたベクトルを設定します。
118
119  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
120  @param[in]    p     対象のベクトルへのポインタ
121  @param[in]    alt   正規化に失敗した場合に設定するベクトル
122
123  @return       pOut を返します。
124 *---------------------------------------------------------------------------*/
125NN_MATH_INLINE VEC3*
126VEC3SafeNormalize(VEC3* pOut, const VEC3* p, const VEC3& alt)
127{
128    NN_NULL_ASSERT(pOut);
129    NN_NULL_ASSERT(p);
130
131    register f32 x, y, z, mag;
132
133    x = p->x;
134    y = p->y;
135    z = p->z;
136
137    mag = (x * x) + (y * y) + (z * z);
138
139    if (mag == 0)
140    {
141        *pOut = alt;
142
143        return pOut;
144    }
145
146    mag = 1.0f / ::std::sqrtf(mag);
147
148    x *= mag;
149    y *= mag;
150    z *= mag;
151
152    pOut->x = x;
153    pOut->y = y;
154    pOut->z = z;
155
156    return pOut;
157}
158
159
160/*!--------------------------------------------------------------------------*
161  @brief        2つのベクトル間の距離の2乗を計算します。
162
163  @param[in]    p1    左辺値へのポインタ
164  @param[in]    p2    右辺値へのポインタ
165
166  @return       p1 と p2 の距離の2乗を返します。
167 *---------------------------------------------------------------------------*/
168NN_MATH_INLINE f32
169VEC3SquareDist(const VEC3* p1, const VEC3* p2)
170{
171    NN_NULL_ASSERT( p1 );
172    NN_NULL_ASSERT( p2 );
173
174    VEC3 diff;
175
176    diff.x = p1->x - p2->x;
177    diff.y = p1->y - p2->y;
178    diff.z = p1->z - p2->z;
179
180    return (diff.x * diff.x) + (diff.y * diff.y) + (diff.z * diff.z);
181}
182
183/*!
184    @}
185*/
186
187}  // namespace math
188}  // namespace nn
189