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