1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Vector3.h
4 
5   Copyright (C)2009-2012 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   $Rev: 48334 $
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 /* Please see man pages for details
34 
35 
36 */
37 // Transformed as (x, y, z, 0)
38 /*
39 
40 
41 
42 
43 
44 
45 
46  */
47 inline VEC3* VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2);
48 
49 /*
50 
51 
52 
53 
54 
55 
56 
57 
58  */
59 NN_MATH_INLINE VEC3* VEC3Cross(VEC3* pOut, const VEC3* p1, const VEC3* p2);
60 
61 /*
62 
63 
64 
65 
66 
67 
68  */
69 inline f32   VEC3Dist(const VEC3* p1, const VEC3* p2);
70 
71 /*
72 
73 
74 
75 
76 
77 
78  */
79 inline f32   VEC3Dot(const VEC3* p1, const VEC3* p2);
80 
81 /*
82 
83 
84 
85 
86 
87  */
88 NN_MATH_INLINE bool VEC3IsZero(const VEC3* p);
89 
90 /*
91 
92 
93 
94 
95 
96  */
97 inline f32   VEC3Len(const VEC3* p);
98 
99 /*
100 
101 
102 
103 
104 
105 
106 
107 
108  */
109 inline VEC3* VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t);
110 
111 /*
112 
113 
114 
115 
116 
117 
118 
119  */
120 NN_MATH_INLINE VEC3* VEC3Maximize(VEC3* pOut, const VEC3* p1, const VEC3* p2);
121 
122 /*
123 
124 
125 
126 
127 
128 
129 
130  */
131 NN_MATH_INLINE VEC3* VEC3Minimize(VEC3* pOut, const VEC3* p1, const VEC3* p2);
132 
133 /*
134 
135 
136 
137 
138 
139 
140 
141  */
142 inline VEC3* VEC3Mult(VEC3* pOut, const VEC3* p1, const VEC3* p2);
143 
144 /*
145 
146 
147 
148 
149 
150 
151  */
152 NN_MATH_INLINE VEC3* VEC3Normalize(VEC3* pOut, const VEC3* p);
153 
154 /*
155 
156 
157 
158 
159 
160 
161 
162 
163  */
164 NN_MATH_INLINE VEC3* VEC3SafeNormalize(VEC3* pOut, const VEC3* p, const VEC3& alt);
165 
166 /*
167 
168 
169 
170 
171 
172 
173 
174  */
175 inline VEC3* VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale);
176 
177 /*
178 
179 
180 
181 
182 
183 
184  */
185 NN_MATH_INLINE f32   VEC3SquareDist(const VEC3* p1, const VEC3* p2);
186 
187 /*
188 
189 
190 
191 
192 
193  */
194 inline f32   VEC3SquareLen(const VEC3* p);
195 
196 /*
197 
198 
199 
200 
201 
202 
203 
204  */
205 inline VEC3* VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2);
206 
207 /*
208 
209 */
210 
211 NN_FORCE_INLINE VEC3* VEC3Normalize(VEC3* pOut, const VEC3* p);
212 
213 /* =======================================================================
214         Class definitions
215    ======================================================================== */
216 /*
217 
218 
219  */
220 struct VEC3_
221 {
222     f32 x;  //
223     f32 y;  //
224     f32 z;  //
225 };
226 
227 /*
228 
229 
230    */
231 class VEC3 : public VEC3_
232 {
233 public:
234     static const int DIMENSION = 3; //
235 
236     //
Zero()237     static const VEC3& Zero()
238     {
239         static const VEC3 zero(0.0f, 0.0f, 0.0f);
240 
241         return zero;
242     }
243 
244     //
One()245     static const VEC3& One()
246     {
247         static const VEC3 one(1.0f, 1.0f, 1.0f);
248 
249         return one;
250     }
251 
252     typedef VEC3 self_type; //
253     typedef f32  value_type; //
254 public:
255     //----------------------------------------
256     //
257     //
258 
259     //
VEC3()260     VEC3() {}
VEC3(const f32 * p)261     explicit VEC3(const f32* p) { x = p[0]; y = p[1]; z = p[2]; }
262     //
VEC3(const VEC3_ & v)263     VEC3(const VEC3_& v) { x = v.x; y = v.y; z = v.z; }
264     //
VEC3(f32 fx,f32 fy,f32 fz)265     VEC3(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
266 
267     //
268 
269     //----------------------------------------
270     //
271     //
272     //
273     operator f32*() { return &x; }
274     //
275     operator const f32*() const { return &x; }
276     //
277 
278     //----------------------------------------
279     //
280     //
281 
282     //
283     self_type& operator += (const self_type& rhs) { (void)VEC3Add(this, this, &rhs); return *this; }
284 
285     //
286     self_type& operator -= (const self_type& rhs) { (void)VEC3Sub(this, this, &rhs); return *this; }
287 
288     //
289     self_type& operator *= (f32 f) { (void)VEC3Scale(this, this, f); return *this; }
290 
291     //
292     self_type& operator *= (const self_type& rhs) { (void)VEC3Mult(this, this, &rhs); return *this; }
293 
294     //
295     self_type& operator /= (f32 f) { return operator*=(1.f / f); }
296 
297     //
298     self_type operator + () const { return *this; }
299 
300     //
301     self_type operator - () const { return self_type(-x, -y, -z); }
302 
303     // The best implementation for binary operators differs depending on whether return values are optimized.
304     //
305     self_type operator + (const self_type& rhs) const { VEC3 tmp; (void)VEC3Add(&tmp, this, &rhs); return tmp; }
306 
307     //
308     self_type operator - (const self_type& rhs) const { VEC3 tmp; (void)VEC3Sub(&tmp, this, &rhs); return tmp; }
309 
310     //
311     self_type operator * (f32 f) const { VEC3 tmp; (void)VEC3Scale(&tmp, this, f); return tmp; }
312 
313     //
314     self_type operator / (f32 f) const { f32 r = 1.f / f; return operator*(r); }
315 
316     //
317     //
318     //
319     //
320     //
321     //
Lerp(const VEC3 & lhs,const VEC3 & rhs,f32 t)322     self_type& Lerp(const VEC3& lhs, const VEC3& rhs, f32 t)
323     {
324         return *VEC3Lerp(this, &lhs, &rhs, t);
325     }
326 
327     //
328     //
329     //
330     //
Dot(const VEC3 & vec)331     f32 Dot(const VEC3& vec) const
332     {
333         return VEC3Dot(this, &vec);
334     }
335 
336     //
337     //
338     //
LenSq()339     f32 LenSq() const { return VEC3SquareLen(this); }
340 
341     //
LengthSquare()342     f32 LengthSquare() const { return VEC3SquareLen(this); }
343 
344     //
Length()345     f32 Length() const { return VEC3Len(this); }
346 
347     //
Normalize()348     self_type& Normalize()
349     {
350         return *VEC3Normalize(this, this);
351     }
352 
353     //
354     //
355     //
356     //
SafeNormalize(const VEC3 & alt)357     self_type& SafeNormalize(const VEC3& alt)
358     {
359         return *VEC3SafeNormalize(this, this, alt);
360     }
361 
362     //
363     //
364     //
DistanceSquare(const VEC3 & vec)365     f32 DistanceSquare(const VEC3& vec) const
366     {
367         return VEC3SquareDist(this, &vec);
368     }
369 
370     //
371     //
372     //
373     //
Maximize(const VEC3 & lhs,const VEC3 & rhs)374     self_type& Maximize(const VEC3& lhs, const VEC3& rhs)
375     {
376         return *VEC3Maximize(this, &lhs, &rhs);
377     }
378 
379     //
380     //
381     //
382     //
Minimize(const VEC3 & lhs,const VEC3 & rhs)383     self_type& Minimize(const VEC3& lhs, const VEC3& rhs)
384     {
385         return *VEC3Minimize(this, &lhs, &rhs);
386     }
387 
388     //
389     //
390     //
391     //
Cross(const VEC3 & lhs,const VEC3 & rhs)392     self_type& Cross(const VEC3& lhs, const VEC3& rhs)
393     {
394         return *VEC3Cross(this, &lhs, &rhs);
395     }
396 
397     //
398 
399     //----------------------------------------
400     //
401     //
402 
403     //
Set(f32 fx,f32 fy,f32 fz)404     void Set(f32 fx, f32 fy, f32 fz) { x = fx; y = fy; z = fz; }
405 
406     //
Set(const self_type & value)407     void Set(const self_type& value) { x = value.x; y = value.y; z = value.z; }
408 
409     //
410 
411     //----------------------------------------
412     //
413     //
414     //
415     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z; }
416 
417     //
418     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z; }
419 
420     //
IsZero()421     bool IsZero() const { return VEC3IsZero(this); }
422 
423     //
424 
425     //
426     void Report(bool bNewline = true, const char* name = NULL) const;
427 
428 private:
429     typedef void (self_type::*UnspecifiedBoolType)() const;
430     operator UnspecifiedBoolType() const;
431     operator UnspecifiedBoolType();
432 };
433 
434 //
435 //
436 
437 //
438 typedef class VEC3 Vector3;
439 
440 //
441 
442 /* ------------------------------------------------------------------------
443     Function for VEC3
444    ------------------------------------------------------------------------ */
445 inline VEC3*
VEC3Add(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)446 VEC3Add(VEC3* pOut, const VEC3* p1, const VEC3* p2)
447 {
448     pOut->x = p1->x + p2->x;
449     pOut->y = p1->y + p2->y;
450     pOut->z = p1->z + p2->z;
451     return pOut;
452 }
453 
454 inline VEC3*
VEC3Sub(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)455 VEC3Sub(VEC3* pOut, const VEC3* p1, const VEC3* p2)
456 {
457     pOut->x = p1->x - p2->x;
458     pOut->y = p1->y - p2->y;
459     pOut->z = p1->z - p2->z;
460     return pOut;
461 }
462 
463 inline VEC3*
VEC3Mult(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2)464 VEC3Mult(VEC3* pOut, const VEC3* p1, const VEC3* p2)
465 {
466     pOut->x = p1->x * p2->x;
467     pOut->y = p1->y * p2->y;
468     pOut->z = p1->z * p2->z;
469     return pOut;
470 }
471 
472 inline VEC3*
VEC3Scale(VEC3 * pOut,const VEC3 * p,f32 scale)473 VEC3Scale(VEC3* pOut, const VEC3* p, f32 scale)
474 {
475     pOut->x = scale * p->x;
476     pOut->y = scale * p->y;
477     pOut->z = scale * p->z;
478     return pOut;
479 }
480 
481 inline VEC3*
VEC3Lerp(VEC3 * pOut,const VEC3 * p1,const VEC3 * p2,f32 t)482 VEC3Lerp(VEC3* pOut, const VEC3* p1, const VEC3* p2, f32 t)
483 {
484     pOut->x = p1->x + t * (p2->x - p1->x);
485     pOut->y = p1->y + t * (p2->y - p1->y);
486     pOut->z = p1->z + t * (p2->z - p1->z);
487     return pOut;
488 }
489 
490 inline f32
VEC3Dot(const VEC3 * p1,const VEC3 * p2)491 VEC3Dot(const VEC3* p1, const VEC3* p2)
492 {
493     return p1->x * p2->x + p1->y * p2->y + p1->z * p2->z;
494 }
495 
496 inline f32
VEC3Len(const VEC3 * p)497 VEC3Len(const VEC3* p)
498 {
499     NN_NULL_ASSERT( p );
500 
501     return ::std::sqrtf( VEC3SquareLen( p ) );
502 }
503 
504 inline f32
VEC3SquareLen(const VEC3 * p)505 VEC3SquareLen(const VEC3* p)
506 {
507     return p->x * p->x + p->y * p->y + p->z * p->z;
508 }
509 
510 inline f32
VEC3Dist(const VEC3 * p1,const VEC3 * p2)511 VEC3Dist( const VEC3* p1, const VEC3* p2 )
512 {
513     NN_NULL_ASSERT( p1 );
514     NN_NULL_ASSERT( p2 );
515 
516     return ::std::sqrtf( VEC3SquareDist( p1, p2 ) );
517 }
518 
519 
520 inline VEC3
521 operator * (f32 f, const VEC3& rhs) { VEC3 tmp; (void)VEC3Scale(&tmp, &rhs, f); return tmp; }
522 
523 }  // namespace math
524 }  // namespace nn
525 
526 #include <nn/math/ARMv6/math_Vector3.h>
527 
528 namespace nn {
529 namespace math {
530 
531 NN_FORCE_INLINE VEC3*
VEC3Normalize(VEC3 * pOut,const VEC3 * p)532 VEC3Normalize(VEC3* pOut, const VEC3* p)
533 {
534 #if defined( NN_HARDWARE_CTR )
535     #if (VEC3NORMALIZE__CONFIG == D_ORG)
536         return ARMv6::VEC3NormalizeC(pOut, p);
537     #elif (VEC3NORMALIZE__CONFIG == D_FAST_C)
538         return ARMv6::VEC3NormalizeC_FAST(pOut, p);
539     #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM)
540     #elif (VEC3NORMALIZE__CONFIG == D_FAST_C_ALGO)
541     #elif (VEC3NORMALIZE__CONFIG == D_FAST_ASM_ALGO)
542     #endif
543 #else
544 #endif // #if defined( NN_HARDWARE_CTR )
545 }
546 
547 }  // namespace math
548 }  // namespace nn
549 
550 
551 
552 #if defined(NN_MATH_AS_INLINE)
553 #include <nn/math/inline/math_Vector3.ipp>
554 #include <nn/math/ARMv6/inline/math_Vector3.ipp>
555 #endif
556 
557 namespace nn {
558 namespace math {
559 
560 //Overload referencing the -- const argument
VEC3IsZero(const VEC3 & v)561 inline bool VEC3IsZero(const VEC3& v){ return VEC3IsZero( &v ); }
VEC3Maximize(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)562 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)563 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)564 inline VEC3* VEC3Cross(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Cross( pOut, &v1, &v2 ); }
VEC3Normalize(VEC3 * pOut,const VEC3 & v)565 inline VEC3* VEC3Normalize(VEC3* pOut, const VEC3& v) { return VEC3Normalize( pOut, &v ); }
VEC3SafeNormalize(VEC3 * pOut,const VEC3 & v,const VEC3 & alt)566 inline VEC3* VEC3SafeNormalize(VEC3* pOut, const VEC3& v, const VEC3& alt) { return VEC3SafeNormalize( pOut, &v, alt ); }
VEC3SquareDist(const VEC3 & v1,const VEC3 & v2)567 inline f32   VEC3SquareDist(const VEC3& v1, const VEC3& v2) { return VEC3SquareDist( &v1, &v2 ); }
568 
VEC3Add(VEC3 * pOut,const VEC3 & v1,const VEC3 & v2)569 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)570 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)571 inline VEC3* VEC3Mult(VEC3* pOut, const VEC3& v1, const VEC3& v2) { return VEC3Mult( pOut, &v1, &v2 ); }
VEC3Scale(VEC3 * pOut,const VEC3 & v,f32 scale)572 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)573 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)574 inline f32   VEC3Dot(const VEC3& v1, const VEC3& v2) { return VEC3Dot( &v1, &v2 ); }
VEC3Len(const VEC3 & v)575 inline f32   VEC3Len(const VEC3& v) { return VEC3Len( &v ); }
VEC3SquareLen(const VEC3 & v)576 inline f32   VEC3SquareLen(const VEC3& v) { return VEC3SquareLen( &v ); }
VEC3Dist(const VEC3 & v1,const VEC3 & v2)577 inline f32   VEC3Dist(const VEC3& v1, const VEC3& v2) { return VEC3Dist( &v1, &v2 ); }
578 
579 }  // namespace math
580 }  // namespace nn
581 
582 #pragma pop
583 
584 #endif
585