1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Vector2.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_VECTOR2_H_
17 #define NN_MATH_VECTOR2_H_
18 
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21 
22 #pragma push
23 #pragma Otime
24 
25 namespace nn {
26 namespace math {
27 
28 struct VEC2;
29 struct MTX23;
30 
31 NN_MATH_INLINE bool VEC2IsZero(const VEC2* p);
32 
33 NN_MATH_INLINE VEC2* VEC2Lerp(VEC2* pOut, const VEC2* p1, const VEC2* p2, f32 t);
34 NN_MATH_INLINE f32 VEC2Dot(const VEC2* p1, const VEC2* p2);
35 NN_MATH_INLINE VEC2* VEC2Maximize(VEC2* pOut, const VEC2* p1, const VEC2* p2);
36 NN_MATH_INLINE VEC2* VEC2Minimize(VEC2* pOut, const VEC2* p1, const VEC2* p2);
37 NN_MATH_INLINE VEC2* VEC2Normalize(VEC2* pOut, const VEC2* p);
38 NN_MATH_INLINE VEC2* VEC2SafeNormalize(VEC2* pOut, const VEC2* p, const VEC2& alt);
39 NN_MATH_INLINE f32 VEC2DistSq(const VEC2* p1, const VEC2* p2);
40 NN_MATH_INLINE VEC2* VEC2Transform(VEC2* pOut, const MTX23* pM, const VEC2* pV);
41 
42 /* =======================================================================
43         Class definitions
44    ======================================================================== */
45 struct VEC2_
46 {
47     f32 x;
48     f32 y;
49 };
50 
51 /*
52 
53    */
54 struct VEC2 : public VEC2_
55 {
56 public:
57     static const int DIMENSION = 2; //
58 
59     //
ZeroVEC260     static const VEC2& Zero()
61     {
62         static const VEC2 zero(0.0f, 0.0f);
63 
64         return zero;
65     }
66 
67     //
OneVEC268     static const VEC2& One()
69     {
70         static const VEC2 one(1.0f, 1.0f);
71 
72         return one;
73     }
74 
75     typedef VEC2 self_type; //
76     typedef f32  value_type; //
77 public:
78 
79     //----------------------------------------
80     //
81     //
82 
83     //
VEC2VEC284     VEC2() {}
85     //
VEC2VEC286     explicit VEC2(const f32* p) { x = p[0]; y = p[1]; }
87     //
VEC2VEC288     VEC2(const VEC2_& v) { x = v.x; y = v.y; }
89     //
VEC2VEC290     VEC2(f32 fx, f32 fy) { x = fx; y = fy; }
91 
92     //
93 
94     //----------------------------------------
95     //
96     //
97     //
98     operator f32*() { return &x; }
99 
100     //
101     operator const f32*() const { return &x; }
102     //
103 
104     //----------------------------------------
105     //
106     //
107     self_type& operator += (const self_type& rhs) { x += rhs.x; y += rhs.y; return *this; }
108     self_type& operator -= (const self_type& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
109     self_type& operator *= (const self_type& rhs) { x *= rhs.x; y *= rhs.y; return *this; }
110     self_type& operator *= (f32 f) { x *= f; y *= f; return *this; }
111     self_type& operator /= (f32 f) { f32 r = 1.f / f; x *= r; y *= r; return *this; }
112 
113     self_type operator + () const { return *this; }
114     self_type operator - () const { return self_type(-x, -y); }
115 
116     self_type operator + (const self_type& rhs) const { return self_type(x + rhs.x, y + rhs.y); }
117     self_type operator - (const self_type& rhs) const { return self_type(x - rhs.x, y - rhs.y); }
118     self_type operator * (f32 f) const { return self_type(f * x, f * y); }
119     self_type operator / (f32 f) const { f32 r = 1.f / f; return self_type(r * x, r * y); }
120 
121     //
122     //
123     //
124     //
125     //
126     //
LerpVEC2127     self_type& Lerp(const VEC2& lhs, const VEC2& rhs, f32 t)
128     {
129         return *VEC2Lerp(this, &lhs, &rhs, t);
130     }
131 
132     //
133     //
134     //
135     //
DotVEC2136     f32 Dot(const VEC2& vec) const
137     {
138         return VEC2Dot(this, &vec);
139     }
140 
141     //
LenSqVEC2142     f32 LenSq() const { return x * x + y * y; }
143 
144     //
LengthSquareVEC2145     f32 LengthSquare() const { return x * x + y * y; }
146 
147     //
LengthVEC2148     f32 Length() const { return FSqrt(this->x * this->x + this->y * this->y); }
149 
150     //
NormalizeVEC2151     self_type& Normalize()
152     {
153         return *VEC2Normalize(this, this);
154     }
155 
156     //
157     //
158     //
159     //
SafeNormalizeVEC2160     self_type& SafeNormalize(const VEC2& alt)
161     {
162         return *VEC2SafeNormalize(this, this, alt);
163     }
164 
165     //
166     //
167     //
DistanceSquareVEC2168     f32 DistanceSquare(const VEC2& vec)
169     {
170         return VEC2DistSq(this, &vec);
171     }
172 
173     //
174     //
175     //
176     //
MaximizeVEC2177     self_type& Maximize(const VEC2& lhs, const VEC2& rhs)
178     {
179         return *VEC2Maximize(this, &lhs, &rhs);
180     }
181 
182     //
183     //
184     //
185     //
MinimizeVEC2186     self_type& Minimize(const VEC2& lhs, const VEC2& rhs)
187     {
188         return *VEC2Minimize(this, &lhs, &rhs);
189     }
190 
191     //
192 
193     //----------------------------------------
194     //
195     //
196 
197     //
SetVEC2198     void Set(f32 fx, f32 fy) { x = fx; y = fy; }
199 
200     //
201 
202     //----------------------------------------
203     //
204     //
205 
206     //
207     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y; }
208 
209     //
210     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y; }
211 
212     //
IsZeroVEC2213     bool IsZero() const { return VEC2IsZero(this); }
214     //
215 
216     //
217     void Report(bool bNewline = true, const char* name = NULL) const;
218 };
219 
220 typedef struct VEC2 Vector2;
221 
222 /* ------------------------------------------------------------------------
223     Function for VEC2
224    ------------------------------------------------------------------------ */
225 
226 /* Please see man pages for details
227 
228 
229 */
230 
231 /*
232 
233 
234 
235 
236 
237 
238 
239  */
240 inline VEC2*
VEC2Add(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)241 VEC2Add(VEC2* pOut, const VEC2* p1, const VEC2* p2)
242 {
243     NN_NULL_ASSERT( pOut );
244     NN_NULL_ASSERT( p1 );
245     NN_NULL_ASSERT( p2 );
246 
247     pOut->x = p1->x + p2->x; pOut->y = p1->y + p2->y;
248     return pOut;
249 }
250 
251 /*
252 
253 
254 
255 
256 
257 
258 
259  */
260 inline VEC2*
VEC2Sub(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)261 VEC2Sub(VEC2* pOut, const VEC2* p1, const VEC2* p2)
262 {
263     NN_NULL_ASSERT( pOut );
264     NN_NULL_ASSERT( p1 );
265     NN_NULL_ASSERT( p2 );
266 
267     pOut->x = p1->x - p2->x; pOut->y = p1->y - p2->y;
268     return pOut;
269 }
270 
271 /*
272 
273 
274 
275 
276 
277 
278 
279  */
280 inline VEC2*
VEC2Mult(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2)281 VEC2Mult(VEC2* pOut, const VEC2* p1, const VEC2* p2)
282 {
283     pOut->x = p1->x * p2->x;
284     pOut->y = p1->y * p2->y;
285     return pOut;
286 }
287 
288 /*
289 
290 
291 
292 
293 
294 
295 
296  */
297 inline VEC2*
VEC2Scale(VEC2 * pOut,const VEC2 * p,f32 scale)298 VEC2Scale(VEC2* pOut, const VEC2* p, f32 scale)
299 {
300     NN_NULL_ASSERT( pOut );
301     NN_NULL_ASSERT( p );
302 
303     pOut->x = p->x * scale; pOut->y = p->y * scale;
304     return pOut;
305 }
306 
307 
308 /*
309 
310 
311 
312 
313 
314 
315 
316 
317  */
318 inline VEC2*
VEC2Lerp(VEC2 * pOut,const VEC2 * p1,const VEC2 * p2,f32 t)319 VEC2Lerp(VEC2* pOut, const VEC2* p1, const VEC2* p2, f32 t)
320 {
321     // (1-t)*p1 + t*p2
322     pOut->x = p1->x + t * (p2->x - p1->x);
323     pOut->y = p1->y + t * (p2->y - p1->y);
324     return pOut;
325 }
326 
327 
328 /*
329 
330 
331 
332 
333 
334 
335  */
336 inline f32
VEC2Dot(const VEC2 * p1,const VEC2 * p2)337 VEC2Dot(const VEC2* p1, const VEC2* p2)
338 {
339     NN_NULL_ASSERT( p1 );
340     NN_NULL_ASSERT( p2 );
341 
342     return p1->x * p2->x + p1->y * p2->y;
343 }
344 
345 /*
346 
347 
348 
349 
350 
351  */
352 inline f32
VEC2LenSq(const VEC2 * p)353 VEC2LenSq(const VEC2* p)
354 {
355     NN_NULL_ASSERT( p );
356     return p->x * p->x + p->y * p->y;
357 }
358 
359 /*
360 
361 
362 
363 
364 
365  */
366 inline f32
VEC2Len(const VEC2 * p)367 VEC2Len(const VEC2* p) { return FSqrt(p->x * p->x + p->y * p->y); }
368 
369 /*
370 
371 
372 
373 
374 
375 
376  */
377 inline f32
VEC2DistSq(const VEC2 * p1,const VEC2 * p2)378 VEC2DistSq(const VEC2* p1, const VEC2* p2) { VEC2 tmp; return VEC2LenSq(VEC2Sub(&tmp, p1, p2)); }
379 
380 inline VEC2
381 operator * (f32 f, const VEC2& rhs) { return VEC2(f * rhs.x, f * rhs.y); }
382 
383 /*
384 
385 */
386 
387 }  // namespace math
388 }  // namespace nn
389 
390 #if defined(NN_MATH_AS_INLINE)
391 #include <nn/math/inline/math_Vector2.ipp>
392 #endif
393 
394 namespace nn {
395 namespace math {
396 
397 //-- Overloads that reference const type arguments
VEC2IsZero(const VEC2 & v)398 inline bool VEC2IsZero(const VEC2& v){ return VEC2IsZero( &v ); }
VEC2Add(VEC2 * pOut,const VEC2 & p1,const VEC2 & p2)399 inline VEC2* VEC2Add(VEC2* pOut, const VEC2& p1, const VEC2& p2) { return VEC2Add(pOut, &p1, &p2); }
VEC2Sub(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)400 inline VEC2* VEC2Sub(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Sub(pOut, &v1, &v2); }
VEC2Mult(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)401 inline VEC2* VEC2Mult(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Mult(pOut, &v1, &v2); }
VEC2Scale(VEC2 * pOut,const VEC2 & v,f32 scale)402 inline VEC2* VEC2Scale(VEC2* pOut, const VEC2& v, f32 scale) { return VEC2Scale(pOut, &v, scale); }
VEC2Lerp(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2,f32 t)403 inline VEC2* VEC2Lerp(VEC2* pOut, const VEC2& v1, const VEC2& v2, f32 t) { return VEC2Lerp(pOut, &v1, &v2, t); }
VEC2Dot(const VEC2 & v1,const VEC2 & v2)404 inline f32 VEC2Dot(const VEC2& v1, const VEC2& v2) { return VEC2Dot(&v1, &v2); }
VEC2LenSq(const VEC2 & v)405 inline f32 VEC2LenSq(const VEC2& v) { return VEC2LenSq( &v ); }
VEC2Len(const VEC2 & v)406 inline f32 VEC2Len(const VEC2& v) { return VEC2Len( &v ); }
VEC2DistSq(const VEC2 & v1,const VEC2 & v2)407 inline f32 VEC2DistSq(const VEC2& v1, const VEC2& v2) { return VEC2DistSq( &v1, &v2 ); }
408 
VEC2Maximize(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)409 inline VEC2* VEC2Maximize(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Maximize( pOut, &v1, &v2 ); }
VEC2Minimize(VEC2 * pOut,const VEC2 & v1,const VEC2 & v2)410 inline VEC2* VEC2Minimize(VEC2* pOut, const VEC2& v1, const VEC2& v2) { return VEC2Minimize( pOut, &v1, &v2 ); }
VEC2Normalize(VEC2 * pOut,const VEC2 & v)411 inline VEC2* VEC2Normalize(VEC2* pOut, const VEC2& v) { return VEC2Normalize( pOut, &v ); }
VEC2SafeNormalize(VEC2 * pOut,const VEC2 & v,const VEC2 & alt)412 inline VEC2* VEC2SafeNormalize(VEC2* pOut, const VEC2& v, const VEC2& alt) { return VEC2SafeNormalize( pOut, &v, alt ); }
VEC2Transform(VEC2 * pOut,const MTX23 & m,const VEC2 & v)413 inline VEC2* VEC2Transform(VEC2* pOut, const MTX23& m, const VEC2& v) { return VEC2Transform( pOut, &m, &v ); }
414 
415 }  // namespace math
416 }  // namespace nn
417 
418 #pragma pop
419 
420 #endif
421