1/*---------------------------------------------------------------------------*
2  Project:  Horizon
3  File:     math_Vector4.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: 18015 $
14 *---------------------------------------------------------------------------*/
15
16namespace nn {
17namespace math {
18
19/* ------------------------------------------------------------------------
20        VEC4
21   ------------------------------------------------------------------------ */
22/*!
23    @name    ベクトル
24    @{
25*/
26
27/*!--------------------------------------------------------------------------*
28  @brief        ベクトルがゼロベクトルかどうか判定します。
29
30  @param[in]    p    判定対象のベクトルへのポインタ。
31
32  @return       p がゼロベクトルであれば true そうでなければ false を返します。
33 *---------------------------------------------------------------------------*/
34NN_MATH_INLINE bool
35VEC4IsZero(const VEC4* p)
36{
37    return p->x == 0.f && p->y == 0.f && p->z == 0.f && p->w == 0.f;
38}
39
40/*!--------------------------------------------------------------------------*
41  @brief        同次座標でベクトルがゼロベクトルかどうか判定します。
42
43  @param[in]    p    判定対象のベクトルへのポインタ。
44
45  @return       p がゼロベクトルであれば true そうでなければ false を返します。
46 *---------------------------------------------------------------------------*/
47NN_MATH_INLINE bool
48VEC4IsZeroWOne(const VEC4* p)
49{
50    return p->x == 0.f && p->y == 0.f && p->z == 0.f && p->w == 1.f;
51}
52
53/*!--------------------------------------------------------------------------*
54  @brief        ベクトルの和を計算します。
55
56  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
57  @param[in]    p1    左辺値へのポインタ
58  @param[in]    p2    右辺値へのポインタ
59
60  @return       pOut を返します。
61 *---------------------------------------------------------------------------*/
62NN_MATH_INLINE VEC4*
63VEC4Add(VEC4* pOut, const VEC4* p1, const VEC4* p2)
64{
65    pOut->x = p1->x + p2->x;
66    pOut->y = p1->y + p2->y;
67    pOut->z = p1->z + p2->z;
68    pOut->w = p1->w + p2->w;
69
70    return pOut;
71}
72
73/*!--------------------------------------------------------------------------*
74  @brief        ベクトルの差を計算します。
75
76  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
77  @param[in]    p1    左辺値へのポインタ
78  @param[in]    p2    右辺値へのポインタ
79
80  @return       pOut を返します。
81 *---------------------------------------------------------------------------*/
82NN_MATH_INLINE VEC4*
83VEC4Sub(VEC4* pOut, const VEC4* p1, const VEC4* p2)
84{
85    pOut->x = p1->x - p2->x;
86    pOut->y = p1->y - p2->y;
87    pOut->z = p1->z - p2->z;
88    pOut->w = p1->w - p2->w;
89
90    return pOut;
91}
92
93/*!--------------------------------------------------------------------------*
94  @brief        ベクトルの積を計算します。
95
96  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
97  @param[in]    p1    左辺値へのポインタ
98  @param[in]    p2    右辺値へのポインタ
99
100  @return       pOut を返します。
101 *---------------------------------------------------------------------------*/
102NN_MATH_INLINE VEC4*
103VEC4Mult(VEC4* pOut, const VEC4* p1, const VEC4* p2)
104{
105    pOut->x = p1->x * p2->x;
106    pOut->y = p1->y * p2->y;
107    pOut->z = p1->z * p2->z;
108    pOut->w = p1->w * p2->w;
109    return pOut;
110}
111
112/*!--------------------------------------------------------------------------*
113  @brief        ベクトルのスカラー倍を計算します。
114
115  @param[out]   pOut   計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
116  @param[in]    p      左辺値へのポインタ
117  @param[in]    scale  掛ける数
118
119  @return       pOut を返します。
120 *---------------------------------------------------------------------------*/
121NN_MATH_INLINE VEC4*
122VEC4Scale(VEC4* pOut, const VEC4* p, f32 scale)
123{
124    pOut->x = scale * p->x;
125    pOut->y = scale * p->y;
126    pOut->z = scale * p->z;
127    pOut->w = scale * p->w;
128
129    return pOut;
130}
131
132/*!--------------------------------------------------------------------------*
133  @brief        2つのベクトル間の線形補間を計算します。
134
135  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
136  @param[in]    p1    線形補間の始点となるベクトルへのポインタ
137  @param[in]    p2    線形補間の終点となるベクトルへのポインタ
138  @param[in]    t     線形補間のパラメータ。0.0 であれば p1 が 1.0 であれば p2 が結果となります。
139
140  @return       pOut を返します。
141 *---------------------------------------------------------------------------*/
142NN_MATH_INLINE VEC4*
143VEC4Lerp(VEC4* pOut, const VEC4* __restrict p1, const VEC4* __restrict p2, f32 t)
144{
145    // (1-t)*p1 + t*p2
146    pOut->x = p1->x + t * (p2->x - p1->x);
147    pOut->y = p1->y + t * (p2->y - p1->y);
148    pOut->z = p1->z + t * (p2->z - p1->z);
149    pOut->w = p1->w + t * (p2->w - p1->w);
150
151    return pOut;
152}
153
154/*!--------------------------------------------------------------------------*
155  @brief        ベクトルの内積を計算します。
156
157  @param[in]    p1    左辺値へのポインタ
158  @param[in]    p2    右辺値へのポインタ
159
160  @return       p1 と p2 の内積を返します。
161 *---------------------------------------------------------------------------*/
162NN_MATH_INLINE f32
163VEC4Dot(const VEC4* p1, const VEC4* p2)
164{
165    return p1->x * p2->x + p1->y * p2->y + p1->z * p2->z + p1->w * p2->w;
166
167}
168
169/*!--------------------------------------------------------------------------*
170  @brief        ベクトルの長さの2乗を計算します。
171
172  @param[in]    p  対象のベクトルへのポインタ。
173
174  @return       p の長さの2乗を返します。
175 *---------------------------------------------------------------------------*/
176NN_MATH_INLINE f32
177VEC4LenSq(const VEC4* __restrict p)
178{
179    return p->x * p->x + p->y * p->y + p->z * p->z + p->w * p->w;
180
181}
182
183/*!--------------------------------------------------------------------------*
184  @brief        ベクトルの長さを計算します。
185
186  @param[in]    p  対象のベクトルへのポインタ。
187
188  @return       p の長さを返します。
189 *---------------------------------------------------------------------------*/
190f32 VEC4Len(const VEC4* p)
191{
192    return FSqrt(VEC4LenSq(p));
193
194}
195
196/*!--------------------------------------------------------------------------*
197  @brief        ベクトルを正規化します。
198
199  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
200  @param[in]    p     対象のベクトルへのポインタ
201
202  @return       pOut を返します。
203 *---------------------------------------------------------------------------*/
204NN_MATH_INLINE VEC4*
205VEC4Normalize(VEC4* pOut, const VEC4* p)
206{
207    (void)VEC4Scale(pOut, p, FrSqrt(VEC4LenSq(p)));
208
209    return pOut;
210}
211
212/*!--------------------------------------------------------------------------*
213  @brief        ベクトルを正規化します。
214                正規化に失敗した場合は指定されたベクトルを設定します。
215
216  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
217  @param[in]    p     対象のベクトルへのポインタ
218  @param[in]    alt   正規化に失敗した場合に設定するベクトル
219
220  @return       pOut を返します。
221 *---------------------------------------------------------------------------*/
222NN_MATH_INLINE VEC4*
223VEC4SafeNormalize(VEC4* pOut, const VEC4* p, const VEC4& alt)
224{
225    NN_NULL_ASSERT(pOut);
226    NN_NULL_ASSERT(p);
227
228    f32 mag = VEC4LenSq(p);
229
230    if (mag == 0)
231    {
232        *pOut = alt;
233
234        return pOut;
235    }
236
237    (void)VEC4Scale(pOut, p, FrSqrt(mag));
238
239    return pOut;
240}
241
242/*!--------------------------------------------------------------------------*
243  @brief        2つのベクトル間の距離の2乗を計算します。
244
245  @param[in]    p1    左辺値へのポインタ
246  @param[in]    p2    右辺値へのポインタ
247
248  @return       p1 と p2 の距離の2乗を返します。
249 *---------------------------------------------------------------------------*/
250NN_MATH_INLINE f32
251VEC4DistSq(const VEC4* p1, const VEC4* p2)
252{
253    VEC4 tmp;
254    return VEC4LenSq(VEC4Sub(&tmp, p1, p2));
255
256}
257
258/*!--------------------------------------------------------------------------*
259  @brief        2つのベクトルのそれぞれの成分の最大値から構成されるベクトルを作成します。
260
261  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
262  @param[in]    p1    対象のベクトル1へのポインタ。
263  @param[in]    p2    対象のベクトル2へのポインタ。
264
265  @return       pOut を返します。
266 *---------------------------------------------------------------------------*/
267NN_MATH_INLINE VEC4*
268VEC4Maximize(VEC4* pOut, const VEC4* p1, const VEC4* p2)
269{
270    pOut->x = (p1->x > p2->x) ? p1->x : p2->x;
271    pOut->y = (p1->y > p2->y) ? p1->y : p2->y;
272    pOut->z = (p1->z > p2->z) ? p1->z : p2->z;
273    pOut->w = (p1->w > p2->w) ? p1->w : p2->w;
274
275    return pOut;
276}
277
278/*!--------------------------------------------------------------------------*
279  @brief        2つのベクトルのそれぞれの成分の最小値から構成されるベクトルを作成します。
280
281  @param[out]   pOut  計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
282  @param[in]    p1    対象のベクトル1へのポインタ。
283  @param[in]    p2    対象のベクトル2へのポインタ。
284
285  @return       pOut を返します。
286 *---------------------------------------------------------------------------*/
287NN_MATH_INLINE VEC4*
288VEC4Minimize(VEC4* pOut, const VEC4* p1, const VEC4* p2)
289{
290    pOut->x = (p1->x < p2->x) ? p1->x : p2->x;
291    pOut->y = (p1->y < p2->y) ? p1->y : p2->y;
292    pOut->z = (p1->z < p2->z) ? p1->z : p2->z;
293    pOut->w = (p1->w < p2->w) ? p1->w : p2->w;
294
295    return pOut;
296}
297
298/*!
299    @}
300*/
301
302}  // namespace math
303}  // namespace nn
304