1 /*---------------------------------------------------------------------------*
2 Project: Horizon
3 File: math_Vector3.h
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: 25718 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NN_MATH_VECTOR3_H_
17 #define NN_MATH_VECTOR3_H_
18
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21 #include <nn/math/math_Constant.h>
22
23 #pragma push
24 #pragma Otime
25
26 namespace nn {
27 namespace math {
28
29 struct VEC3;
30 struct MTX33;
31 struct MTX34;
32
33 // (x, y, z, 0)として変換
34 NN_MATH_INLINE bool VEC3IsZero(const VEC3* p);
35 NN_MATH_INLINE VEC3* VEC3Maximize(VEC3* pOut, const VEC3* p1, const VEC3* p2);
36 NN_MATH_INLINE VEC3* VEC3Minimize(VEC3* pOut, const VEC3* p1, const VEC3* p2);
37 NN_MATH_INLINE VEC3* VEC3Cross(VEC3* pOut, const VEC3* p1, const VEC3* p2);
38 NN_MATH_INLINE VEC3* VEC3Normalize(VEC3* pOut, const VEC3* p);
39 NN_MATH_INLINE VEC3* VEC3SafeNormalize(VEC3* pOut, const VEC3* p, const VEC3& alt);
40 NN_MATH_INLINE f32 VEC3SquareDist(const VEC3* p1, const VEC3* p2);
41
42 inline VEC3* VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2);
43 inline VEC3* VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2);
44 inline VEC3* VEC3Mult(VEC3* pOut, const VEC3* p1, const VEC3* p2);
45 inline VEC3* VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale);
46 inline VEC3* VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t);
47 inline f32 VEC3Dot(const VEC3* p1, const VEC3* p2);
48 inline f32 VEC3Len(const VEC3* p);
49 inline f32 VEC3SquareLen(const VEC3* p);
50 inline f32 VEC3Dist(const VEC3* p1, const VEC3* p2);
51
52
53 NN_FORCE_INLINE VEC3* VEC3Normalize(VEC3* pOut, const VEC3* p);
54
55 /* =======================================================================
56 クラスの定義
57 ======================================================================== */
58 struct VEC3_
59 {
60 f32 x;
61 f32 y;
62 f32 z;
63 };
64
65 /*!------------------------------------------------------------------------
66 @brief 3次のベクトルクラスです。
67 ------------------------------------------------------------------------ */
68 struct VEC3 : public VEC3_
69 {
70 public:
71 static const int DIMENSION = 3; //!< 次元数です。
72
73 //!< @brief ゼロベクトルです。
ZeroVEC374 static const VEC3& Zero()
75 {
76 static const VEC3 zero(0.0f, 0.0f, 0.0f);
77
78 return zero;
79 }
80
81 typedef VEC3 self_type; //!< 自分の型です
82 typedef f32 value_type; //!< 要素の型です。
83 public:
84 //----------------------------------------
85 //! @name 作成
86 //@{
87
88 //! @brief コンストラクタです。
VEC3VEC389 VEC3() {}
VEC3VEC390 VEC3(const f32* p) { x = p[0]; y = p[1]; z = p[2]; }
91 //! @brief コピーコンストラクタです。
VEC3VEC392 VEC3(const VEC3_& v) { x = v.x; y = v.y; z = v.z; }
93 //! @brief コンストラクタです。
VEC3VEC394 VEC3(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
95
96 //@}
97
98 //----------------------------------------
99 //! @name 変換
100 //@{
101 //! @brief f32 型へのキャストです。
102 operator f32*() { return &x; }
103 //! @brief f32 型へのキャストです。
104 operator const f32*() const { return &x; }
105 //@}
106
107 //----------------------------------------
108 //! @name 演算
109 //@{
110
111 self_type& operator += (const self_type& rhs) { (void)VEC3Add(this, this, &rhs); return *this; }
112 self_type& operator -= (const self_type& rhs) { (void)VEC3Sub(this, this, &rhs); return *this; }
113 self_type& operator *= (const self_type& rhs) { (void)VEC3Mult(this, this, &rhs); return *this; }
114 self_type& operator *= (f32 f) { (void)VEC3Scale(this, this, f); return *this; }
115 self_type& operator /= (f32 f) { return operator*=(1.f / f); }
116
117 self_type operator + () const { return *this; }
118 self_type operator - () const { return self_type(-x, -y, -z); }
119
120 // 2項演算子は戻り値最適化が行われるかどうかで最適な実装が異なる
121 self_type operator + (const self_type& rhs) const { VEC3 tmp; (void)VEC3Add(&tmp, this, &rhs); return tmp; }
122 self_type operator - (const self_type& rhs) const { VEC3 tmp; (void)VEC3Sub(&tmp, this, &rhs); return tmp; }
123 self_type operator * (f32 f) const { VEC3 tmp; (void)VEC3Scale(&tmp, this, f); return tmp; }
124 self_type operator / (f32 f) const { f32 r = 1.f / f; return operator*(r); }
125
126 //! @brief 2つのベクトル間の線形補間を計算し設定します。
127 //!
128 //! @param[in] lhs 線形補間の始点となるベクトルです。
129 //! @param[in] rhs 線形補間の終点となるベクトルです。
130 //! @param[in] t 線形補間のパラメータ。0.0 であれば lhs が 1.0 であれば rhs が結果となります。
131 //!
LerpVEC3132 self_type& Lerp(const VEC3& lhs, const VEC3& rhs, f32 t)
133 {
134 return *VEC3Lerp(this, &lhs, &rhs, t);
135 }
136
137 //! @brief 指定したベクトルとの内積を計算します。
138 //!
139 //! @param[in] vec 内積を行うベクトルです。
140 //!
DotVEC3141 f32 Dot(const VEC3& vec) const
142 {
143 return VEC3Dot(this, &vec);
144 }
145
146 //! @brief ベクトルの長さの2乗を計算します。
147 //! 将来削除される可能性がありますので非推奨です。
148 //! LengthSquareを推奨します。
LenSqVEC3149 f32 LenSq() const { return VEC3SquareLen(this); }
150
151 //! @brief ベクトルの長さの2乗を計算します。
LengthSquareVEC3152 f32 LengthSquare() const { return VEC3SquareLen(this); }
153
154 //! @brief ベクトルの長さを計算します。
LengthVEC3155 f32 Length() const { return VEC3Len(this); }
156
157 //! @brief ベクトルを正規化します。
NormalizeVEC3158 self_type& Normalize()
159 {
160 return *VEC3Normalize(this, this);
161 }
162
163 //! @brief ベクトルを正規化します。
164 //! 正規化に失敗した場合は指定されたベクトルを設定します。
165 //!
166 //! @param[in] alt 正規化に失敗した場合に設定するベクトルです。
SafeNormalizeVEC3167 self_type& SafeNormalize(const VEC3& alt)
168 {
169 return *VEC3SafeNormalize(this, this, alt);
170 }
171
172 //! @brief 指定したベクトルとの距離の二乗を計算します。
173 //!
174 //! @param[in] vec 距離を計算するベクトルです。
DistanceSquareVEC3175 f32 DistanceSquare(const VEC3& vec) const
176 {
177 return VEC3SquareDist(this, &vec);
178 }
179
180 //! @brief 2つのベクトルのそれぞれの成分の最大値から構成されるベクトルを作成し設定します。
181 //!
182 //! @brief lhs 最大値を計算する左辺ベクトルです。
183 //! @brief rhs 最大値を計算する右辺ベクトルです。
MaximizeVEC3184 self_type& Maximize(const VEC3& lhs, const VEC3& rhs)
185 {
186 return *VEC3Maximize(this, &lhs, &rhs);
187 }
188
189 //! @brief 2つのベクトルのそれぞれの成分の最小値から構成されるベクトルを作成し設定します。
190 //!
191 //! @brief lhs 最小値を計算する左辺ベクトルです。
192 //! @brief rhs 最小値を計算する右辺ベクトルです。
MinimizeVEC3193 self_type& Minimize(const VEC3& lhs, const VEC3& rhs)
194 {
195 return *VEC3Minimize(this, &lhs, &rhs);
196 }
197
198 //! @brief ベクトルの外積を計算し設定します。
199 //!
200 //! @brief lhs 外積を計算する左辺ベクトルです。
201 //! @brief rhs 外積を計算する右辺ベクトルです。
CrossVEC3202 self_type& Cross(const VEC3& lhs, const VEC3& rhs)
203 {
204 return *VEC3Cross(this, &lhs, &rhs);
205 }
206
207 //@}
208
209 //----------------------------------------
210 //! @name 設定
211 //@{
212
213 //! @brief 値を個別に設定します。
SetVEC3214 void Set(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
215
216 //! @brief 値を設定します。
SetVEC3217 void Set(const self_type& value) { x = value.x; y = value.y; z = value.z; }
218
219 //@}
220
221 //----------------------------------------
222 //! @name 比較
223 //@{
224 //! @brief 同値であれば true を返します。
225 bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
226
227 //! @brief 同値でなければ true を返します。
228 bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; }
229
230 //! @brief ゼロベクトルであれば true を返します。
IsZeroVEC3231 bool IsZero() const { return VEC3IsZero(this); }
232
233 //@}
234
235 //! @brief 状態を出力します。
236 void Report(bool bNewline = true, const char* name = NULL) const;
237 };
238
239 typedef struct VEC3 Vector3;
240
241 /* ------------------------------------------------------------------------
242 VEC3用の関数
243 ------------------------------------------------------------------------ */
244
245 /*!
246 @name ベクトル
247 @{
248 */
249
250 /*!--------------------------------------------------------------------------*
251 @brief ベクトルの和を計算します。
252
253 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
254 @param[in] p1 左辺値へのポインタ
255 @param[in] p2 右辺値へのポインタ
256
257 @return pOut を返します。
258 *---------------------------------------------------------------------------*/
259 inline VEC3*
VEC3Add(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)260 VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2)
261 {
262 pOut->x = p1->x + p2->x;
263 pOut->y = p1->y + p2->y;
264 pOut->z = p1->z + p2->z;
265 return pOut;
266 }
267
268
269 /*!--------------------------------------------------------------------------*
270 @brief ベクトルの差を計算します。
271
272 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
273 @param[in] p1 左辺値へのポインタ
274 @param[in] p2 右辺値へのポインタ
275
276 @return pOut を返します。
277 *---------------------------------------------------------------------------*/
278 inline VEC3*
VEC3Sub(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)279 VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2)
280 {
281 pOut->x = p1->x - p2->x;
282 pOut->y = p1->y - p2->y;
283 pOut->z = p1->z - p2->z;
284 return pOut;
285 }
286
287 /*!--------------------------------------------------------------------------*
288 @brief ベクトルの積を計算します。
289
290 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
291 @param[in] p1 左辺値へのポインタ
292 @param[in] p2 右辺値へのポインタ
293
294 @return pOut を返します。
295 *---------------------------------------------------------------------------*/
296 inline VEC3*
VEC3Mult(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)297 VEC3Mult(VEC3* pOut, const VEC3* p1, const VEC3* p2)
298 {
299 pOut->x = p1->x * p2->x;
300 pOut->y = p1->y * p2->y;
301 pOut->z = p1->z * p2->z;
302 return pOut;
303 }
304
305 /*!--------------------------------------------------------------------------*
306 @brief ベクトルのスカラー倍を計算します。
307
308 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
309 @param[in] p 左辺値へのポインタ
310 @param[in] scale 掛ける数
311
312 @return pOut を返します。
313 *---------------------------------------------------------------------------*/
314 inline VEC3*
VEC3Scale(VEC3 * pOut,const VEC3 * p,f32 scale)315 VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale)
316 {
317 pOut->x = scale * p->x;
318 pOut->y = scale * p->y;
319 pOut->z = scale * p->z;
320 return pOut;
321 }
322
323 /*!--------------------------------------------------------------------------*
324 @brief 2つのベクトル間の線形補間を計算します。
325
326 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p1, p2 と同じベクトルを指していても構いません。
327 @param[in] p1 線形補間の始点となるベクトルへのポインタ
328 @param[in] p2 線形補間の終点となるベクトルへのポインタ
329 @param[in] t 線形補間のパラメータ。0.0 であれば p1 が 1.0 であれば p2 が結果となります。
330
331 @return pOut を返します。
332 *---------------------------------------------------------------------------*/
333 inline VEC3*
VEC3Lerp(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2,f32 t)334 VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t)
335 {
336 pOut->x = p1->x + t * (p2->x - p1->x);
337 pOut->y = p1->y + t * (p2->y - p1->y);
338 pOut->z = p1->z + t * (p2->z - p1->z);
339 return pOut;
340 }
341
342 /*!--------------------------------------------------------------------------*
343 @brief ベクトルの内積を計算します。
344
345 @param[in] p1 左辺値へのポインタ
346 @param[in] p2 右辺値へのポインタ
347
348 @return p1 と p2 の内積を返します。
349 *---------------------------------------------------------------------------*/
350 inline f32
VEC3Dot(const VEC3 * p1,const VEC3 * p2)351 VEC3Dot(const VEC3* p1, const VEC3* p2)
352 {
353 return p1->x * p2->x + p1->y * p2->y + p1->z * p2->z;
354 }
355
356
357 /*!--------------------------------------------------------------------------*
358 @brief ベクトルの長さの2乗を計算します。
359
360 @param[in] p 対象のベクトルへのポインタ。
361
362 @return p の長さの2乗を返します。
363 *---------------------------------------------------------------------------*/
364 inline f32
VEC3SquareLen(const VEC3 * p)365 VEC3SquareLen(const VEC3* p)
366 {
367 return p->x * p->x + p->y * p->y + p->z * p->z;
368 }
369
370 /*!--------------------------------------------------------------------------*
371 @brief ベクトルの長さを計算します。
372
373 @param[in] p 対象のベクトルへのポインタ。
374
375 @return p の長さを返します。
376 *---------------------------------------------------------------------------*/
377 inline f32
VEC3Len(const VEC3 * p)378 VEC3Len(const VEC3* p)
379 {
380 NN_NULL_ASSERT( p );
381
382 return ::std::sqrtf( VEC3SquareLen( p ) );
383 }
384
385
386 /*!--------------------------------------------------------------------------*
387 @brief 2つのベクトル間の距離を計算します。
388
389 @param[in] p1 左辺値へのポインタ
390 @param[in] p2 右辺値へのポインタ
391
392 @return p1 と p2 の距離を返します。
393 *---------------------------------------------------------------------------*/
394 inline f32
VEC3Dist(const VEC3 * p1,const VEC3 * p2)395 VEC3Dist( const VEC3* p1, const VEC3* p2 )
396 {
397 NN_NULL_ASSERT( p1 );
398 NN_NULL_ASSERT( p2 );
399
400 return ::std::sqrtf( VEC3SquareDist( p1, p2 ) );
401 }
402
403
404 inline VEC3
405 operator * (f32 f, const VEC3& rhs) { VEC3 tmp; (void)VEC3Scale(&tmp, &rhs, f); return tmp; }
406
407 } // namespace math
408 } // namespace nn
409
410 #include <nn/math/ARMv6/math_Vector3.h>
411
412 namespace nn {
413 namespace math {
414
415 /*!
416 @name ベクトル
417 @{
418 */
419
420 /*!--------------------------------------------------------------------------*
421 @brief ベクトルを正規化します。
422
423 @param[out] pOut 計算結果を受け取るバッファへのポインタ。p と同じベクトルを指していても構いません。
424 @param[in] p 対象のベクトルへのポインタ
425
426 @return pOut を返します。
427 *---------------------------------------------------------------------------*/
428 NN_FORCE_INLINE VEC3*
VEC3Normalize(VEC3 * pOut,const VEC3 * p)429 VEC3Normalize(VEC3* pOut, const VEC3* p)
430 {
431 #if defined( NN_HARDWARE_CTR )
432 #if (VEC3NORMALIZE__CONFIG == D_ORG)
433 return ARMv6::VEC3NormalizeC(pOut, p);
434 #elif (VEC3NORMALIZE__CONFIG == D_FAST_C)
435 return ARMv6::VEC3NormalizeC_FAST(pOut, p);
436 #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM)
437 #elif (VEC3NORMALIZE__CONFIG == D_FAST_C_ALGO)
438 #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM_ALGO)
439 #endif
440 #else
441 #endif // #if defined( NN_HARDWARE_CTR )
442 }
443
444 /*!
445 @}
446 */
447
448 } // namespace math
449 } // namespace nn
450
451
452
453 #if defined(NN_MATH_AS_INLINE)
454 #include <nn/math/inline/math_Vector3.ipp>
455 #include <nn/math/ARMv6/inline/math_Vector3.ipp>
456 #endif
457
458 namespace nn {
459 namespace math {
460
461 //-- const 引数を参照にしたオーバーロード
VEC3IsZero(const VEC3 & v)462 inline bool VEC3IsZero(const VEC3& v){ return VEC3IsZero( &v ); }
VEC3Maximize(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)463 inline VEC3* VEC3Maximize(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Maximize( pOut, &v1, &v2 ); }
VEC3Minimize(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)464 inline VEC3* VEC3Minimize(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Minimize( pOut, &v1, &v2 ); }
VEC3Cross(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)465 inline VEC3* VEC3Cross(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Cross( pOut, &v1, &v2 ); }
VEC3Normalize(VEC3 * pOut,const VEC3 & v)466 inline VEC3* VEC3Normalize(VEC3* pOut, const VEC3& v) { return VEC3Normalize( pOut, &v ); }
VEC3SafeNormalize(VEC3 * pOut,const VEC3 & v,const VEC3 & alt)467 inline VEC3* VEC3SafeNormalize(VEC3* pOut, const VEC3& v, const VEC3& alt) { return VEC3SafeNormalize( pOut, &v, alt ); }
VEC3SquareDist(const VEC3 & v1,const VEC3 & v2)468 inline f32 VEC3SquareDist(const VEC3& v1, const VEC3& v2) { return VEC3SquareDist( &v1, &v2 ); }
469
VEC3Add(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)470 inline VEC3* VEC3Add(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Add( pOut, &v1, &v2 ); }
VEC3Sub(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)471 inline VEC3* VEC3Sub(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Sub( pOut, &v1, &v2 ); }
VEC3Mult(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)472 inline VEC3* VEC3Mult(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Mult( pOut, &v1, &v2 ); }
VEC3Scale(VEC3 * pOut,const VEC3 & v,f32 scale)473 inline VEC3* VEC3Scale(VEC3* pOut, const VEC3& v, f32 scale) { return VEC3Scale( pOut, &v, scale ); }
VEC3Lerp(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2,f32 t)474 inline VEC3* VEC3Lerp(VEC3* pOut, const VEC3& v1, const VEC3& v2, f32 t) { return VEC3Lerp( pOut, &v1, &v2, t ); }
VEC3Dot(const VEC3 & v1,const VEC3 & v2)475 inline f32 VEC3Dot(const VEC3& v1, const VEC3& v2) { return VEC3Dot( &v1, &v2 ); }
VEC3Len(const VEC3 & v)476 inline f32 VEC3Len(const VEC3& v) { return VEC3Len( &v ); }
VEC3SquareLen(const VEC3 & v)477 inline f32 VEC3SquareLen(const VEC3& v) { return VEC3SquareLen( &v ); }
VEC3Dist(const VEC3 & v1,const VEC3 & v2)478 inline f32 VEC3Dist(const VEC3& v1, const VEC3& v2) { return VEC3Dist( &v1, &v2 ); }
479
480 } // namespace math
481 } // namespace nn
482
483 #pragma pop
484
485 #endif
486