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_MATH_VECTOR3_H_
17 #define NN_MATH_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