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: 34617 $
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 // Transformed as (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         Class definitions
57    ======================================================================== */
58 struct VEC3_
59 {
60     f32 x;
61     f32 y;
62     f32 z;
63 };
64 
65 /*
66 
67    */
68 struct VEC3 : public VEC3_
69 {
70 public:
71     static const int DIMENSION = 3; //
72 
73     //
ZeroVEC374     static const VEC3& Zero()
75     {
76         static const VEC3 zero(0.0f, 0.0f, 0.0f);
77 
78         return zero;
79     }
80 
81     //
OneVEC382     static const VEC3& One()
83     {
84         static const VEC3 one(1.0f, 1.0f, 1.0f);
85 
86         return one;
87     }
88 
89     typedef VEC3 self_type; //
90     typedef f32  value_type; //
91 public:
92     //----------------------------------------
93     //
94     //
95 
96     //
VEC3VEC397     VEC3() {}
VEC3VEC398     explicit VEC3(const f32* p) { x = p[0]; y = p[1]; z = p[2]; }
99     //
VEC3VEC3100     VEC3(const VEC3_& v) { x = v.x; y = v.y; z = v.z; }
101     //
VEC3VEC3102     VEC3(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
103 
104     //
105 
106     //----------------------------------------
107     //
108     //
109     //
110     operator f32*() { return &x; }
111     //
112     operator const f32*() const { return &x; }
113     //
114 
115     //----------------------------------------
116     //
117     //
118 
119     self_type& operator += (const self_type& rhs) { (void)VEC3Add(this, this, &rhs); return *this; }
120     self_type& operator -= (const self_type& rhs) { (void)VEC3Sub(this, this, &rhs); return *this; }
121     self_type& operator *= (const self_type& rhs) { (void)VEC3Mult(this, this, &rhs); return *this; }
122     self_type& operator *= (f32 f) { (void)VEC3Scale(this, this, f); return *this; }
123     self_type& operator /= (f32 f) { return operator*=(1.f / f); }
124 
125     self_type operator + () const { return *this; }
126     self_type operator - () const { return self_type(-x, -y, -z); }
127 
128     // The best implementation for binary operators differs depending on whether return values are optimized.
129     self_type operator + (const self_type& rhs) const { VEC3 tmp; (void)VEC3Add(&tmp, this, &rhs); return tmp; }
130     self_type operator - (const self_type& rhs) const { VEC3 tmp; (void)VEC3Sub(&tmp, this, &rhs); return tmp; }
131     self_type operator * (f32 f) const { VEC3 tmp; (void)VEC3Scale(&tmp, this, f); return tmp; }
132     self_type operator / (f32 f) const { f32 r = 1.f / f; return operator*(r); }
133 
134     //
135     //
136     //
137     //
138     //
139     //
LerpVEC3140     self_type& Lerp(const VEC3& lhs, const VEC3& rhs, f32 t)
141     {
142         return *VEC3Lerp(this, &lhs, &rhs, t);
143     }
144 
145     //
146     //
147     //
148     //
DotVEC3149     f32 Dot(const VEC3& vec) const
150     {
151         return VEC3Dot(this, &vec);
152     }
153 
154     //
155     //
156     //
LenSqVEC3157     f32 LenSq() const { return VEC3SquareLen(this); }
158 
159     //
LengthSquareVEC3160     f32 LengthSquare() const { return VEC3SquareLen(this); }
161 
162     //
LengthVEC3163     f32 Length() const { return VEC3Len(this); }
164 
165     //
NormalizeVEC3166     self_type& Normalize()
167     {
168         return *VEC3Normalize(this, this);
169     }
170 
171     //
172     //
173     //
174     //
SafeNormalizeVEC3175     self_type& SafeNormalize(const VEC3& alt)
176     {
177         return *VEC3SafeNormalize(this, this, alt);
178     }
179 
180     //
181     //
182     //
DistanceSquareVEC3183     f32 DistanceSquare(const VEC3& vec) const
184     {
185         return VEC3SquareDist(this, &vec);
186     }
187 
188     //
189     //
190     //
191     //
MaximizeVEC3192     self_type& Maximize(const VEC3& lhs, const VEC3& rhs)
193     {
194         return *VEC3Maximize(this, &lhs, &rhs);
195     }
196 
197     //
198     //
199     //
200     //
MinimizeVEC3201     self_type& Minimize(const VEC3& lhs, const VEC3& rhs)
202     {
203         return *VEC3Minimize(this, &lhs, &rhs);
204     }
205 
206     //
207     //
208     //
209     //
CrossVEC3210     self_type& Cross(const VEC3& lhs, const VEC3& rhs)
211     {
212         return *VEC3Cross(this, &lhs, &rhs);
213     }
214 
215     //
216 
217     //----------------------------------------
218     //
219     //
220 
221     //
SetVEC3222     void Set(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
223 
224     //
SetVEC3225     void Set(const self_type& value) { x = value.x; y = value.y; z = value.z; }
226 
227     //
228 
229     //----------------------------------------
230     //
231     //
232     //
233     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
234 
235     //
236     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; }
237 
238     //
IsZeroVEC3239     bool IsZero() const { return VEC3IsZero(this); }
240 
241     //
242 
243     //
244     void Report(bool bNewline = true, const char* name = NULL) const;
245 };
246 
247 typedef struct VEC3 Vector3;
248 
249 /* ------------------------------------------------------------------------
250     Function for VEC3
251    ------------------------------------------------------------------------ */
252 
253 /* Please see man pages for details
254 
255 
256 */
257 
258 /*
259 
260 
261 
262 
263 
264 
265 
266  */
267 inline VEC3*
VEC3Add(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)268 VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2)
269 {
270     pOut->x = p1->x + p2->x;
271     pOut->y = p1->y + p2->y;
272     pOut->z = p1->z + p2->z;
273     return pOut;
274 }
275 
276 
277 /*
278 
279 
280 
281 
282 
283 
284 
285  */
286 inline VEC3*
VEC3Sub(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)287 VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2)
288 {
289     pOut->x = p1->x - p2->x;
290     pOut->y = p1->y - p2->y;
291     pOut->z = p1->z - p2->z;
292     return pOut;
293 }
294 
295 /*
296 
297 
298 
299 
300 
301 
302 
303  */
304 inline VEC3*
VEC3Mult(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)305 VEC3Mult(VEC3* pOut, const VEC3* p1, const VEC3* p2)
306 {
307     pOut->x = p1->x * p2->x;
308     pOut->y = p1->y * p2->y;
309     pOut->z = p1->z * p2->z;
310     return pOut;
311 }
312 
313 /*
314 
315 
316 
317 
318 
319 
320 
321  */
322 inline VEC3*
VEC3Scale(VEC3 * pOut,const VEC3 * p,f32 scale)323 VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale)
324 {
325     pOut->x = scale * p->x;
326     pOut->y = scale * p->y;
327     pOut->z = scale * p->z;
328     return pOut;
329 }
330 
331 /*
332 
333 
334 
335 
336 
337 
338 
339 
340  */
341 inline VEC3*
VEC3Lerp(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2,f32 t)342 VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t)
343 {
344     pOut->x = p1->x + t * (p2->x - p1->x);
345     pOut->y = p1->y + t * (p2->y - p1->y);
346     pOut->z = p1->z + t * (p2->z - p1->z);
347     return pOut;
348 }
349 
350 /*
351 
352 
353 
354 
355 
356 
357  */
358 inline f32
VEC3Dot(const VEC3 * p1,const VEC3 * p2)359 VEC3Dot(const VEC3* p1, const VEC3* p2)
360 {
361     return p1->x * p2->x + p1->y * p2->y + p1->z * p2->z;
362 }
363 
364 
365 /*
366 
367 
368 
369 
370 
371  */
372 inline f32
VEC3SquareLen(const VEC3 * p)373 VEC3SquareLen(const VEC3* p)
374 {
375     return p->x * p->x + p->y * p->y + p->z * p->z;
376 }
377 
378 /*
379 
380 
381 
382 
383 
384  */
385 inline f32
VEC3Len(const VEC3 * p)386 VEC3Len(const VEC3* p)
387 {
388     NN_NULL_ASSERT( p );
389 
390     return ::std::sqrtf( VEC3SquareLen( p ) );
391 }
392 
393 
394 /*
395 
396 
397 
398 
399 
400 
401  */
402 inline f32
VEC3Dist(const VEC3 * p1,const VEC3 * p2)403 VEC3Dist( const VEC3* p1, const VEC3* p2 )
404 {
405     NN_NULL_ASSERT( p1 );
406     NN_NULL_ASSERT( p2 );
407 
408     return ::std::sqrtf( VEC3SquareDist( p1, p2 ) );
409 }
410 
411 
412 inline VEC3
413 operator * (f32 f, const VEC3& rhs) { VEC3 tmp; (void)VEC3Scale(&tmp, &rhs, f); return tmp; }
414 
415 }  // namespace math
416 }  // namespace nn
417 
418 #include <nn/math/ARMv6/math_Vector3.h>
419 
420 namespace nn {
421 namespace math {
422 
423 /* Please see man pages for details
424 
425 
426 */
427 
428 /*
429 
430 
431 
432 
433 
434 
435  */
436 NN_FORCE_INLINE VEC3*
VEC3Normalize(VEC3 * pOut,const VEC3 * p)437 VEC3Normalize(VEC3* pOut, const VEC3* p)
438 {
439 #if defined( NN_HARDWARE_CTR )
440     #if (VEC3NORMALIZE__CONFIG == D_ORG)
441         return ARMv6::VEC3NormalizeC(pOut, p);
442     #elif (VEC3NORMALIZE__CONFIG == D_FAST_C)
443         return ARMv6::VEC3NormalizeC_FAST(pOut, p);
444     #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM)
445     #elif (VEC3NORMALIZE__CONFIG == D_FAST_C_ALGO)
446     #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM_ALGO)
447     #endif
448 #else
449 #endif // #if defined( NN_HARDWARE_CTR )
450 }
451 
452 /*
453 
454 */
455 
456 }  // namespace math
457 }  // namespace nn
458 
459 
460 
461 #if defined(NN_MATH_AS_INLINE)
462 #include <nn/math/inline/math_Vector3.ipp>
463 #include <nn/math/ARMv6/inline/math_Vector3.ipp>
464 #endif
465 
466 namespace nn {
467 namespace math {
468 
469 //-- Overloads that reference const type arguments
VEC3IsZero(const VEC3 & v)470 inline bool VEC3IsZero(const VEC3& v){ return VEC3IsZero( &v ); }
VEC3Maximize(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)471 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)472 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)473 inline VEC3* VEC3Cross(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Cross( pOut, &v1, &v2 ); }
VEC3Normalize(VEC3 * pOut,const VEC3 & v)474 inline VEC3* VEC3Normalize(VEC3* pOut, const VEC3& v) { return VEC3Normalize( pOut, &v ); }
VEC3SafeNormalize(VEC3 * pOut,const VEC3 & v,const VEC3 & alt)475 inline VEC3* VEC3SafeNormalize(VEC3* pOut, const VEC3& v, const VEC3& alt) { return VEC3SafeNormalize( pOut, &v, alt ); }
VEC3SquareDist(const VEC3 & v1,const VEC3 & v2)476 inline f32   VEC3SquareDist(const VEC3& v1, const VEC3& v2) { return VEC3SquareDist( &v1, &v2 ); }
477 
VEC3Add(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)478 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)479 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)480 inline VEC3* VEC3Mult(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Mult( pOut, &v1, &v2 ); }
VEC3Scale(VEC3 * pOut,const VEC3 & v,f32 scale)481 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)482 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)483 inline f32   VEC3Dot(const VEC3& v1, const VEC3& v2) { return VEC3Dot( &v1, &v2 ); }
VEC3Len(const VEC3 & v)484 inline f32   VEC3Len(const VEC3& v) { return VEC3Len( &v ); }
VEC3SquareLen(const VEC3 & v)485 inline f32   VEC3SquareLen(const VEC3& v) { return VEC3SquareLen( &v ); }
VEC3Dist(const VEC3 & v1,const VEC3 & v2)486 inline f32   VEC3Dist(const VEC3& v1, const VEC3& v2) { return VEC3Dist( &v1, &v2 ); }
487 
488 }  // namespace math
489 }  // namespace nn
490 
491 #pragma pop
492 
493 #endif
494