Twilight Princess
Decompilation of The Legend of Zelda: Twilight Princess
Loading...
Searching...
No Matches
JGeometry.h
Go to the documentation of this file.
1#ifndef JGEOMETRY_H
2#define JGEOMETRY_H
3
4#include <dolphin/mtx.h>
5#include <cmath>
7
8#ifndef __MWERKS__
9#include <limits>
10#define FLT_EPSILON std::numeric_limits<float>::epsilon()
11#endif
12
13namespace JGeometry {
14
15template<typename T>
16struct TUtil {
17 static inline T clamp(T v, T min, T max) {
18 if (v < min) {
19 return min;
20 }
21 if (v > max) {
22 return max;
23 }
24 return v;
25 }
26};
27
28template<>
29struct TUtil<f32> {
30 static inline f32 clamp(f32 v, f32 min, f32 max) {
31 if (v < min) {
32 return min;
33 }
34 if (v > max) {
35 return max;
36 }
37 return v;
38 }
39 static inline f32 epsilon() { return 32.0f * FLT_EPSILON; }
40 static inline f32 PI() { return 3.1415927f; }
41 static inline f32 inv_sqrt(f32 x) {
42 #ifdef __MWERKS__
43 if (x <= 0.0f) {
44 return x;
45 }
46 f32 root = __frsqrte(x);
47 root = 0.5f * root * (3.0f - x * (root * root));
48 return root;
49 #endif
50 }
51
52 static inline f32 sqrt(f32 x) {
53 #ifdef __MWERKS__
54 if (x <= 0.0f) {
55 return x;
56 }
57
58 f32 root = __frsqrte(x);
59 root = 0.5f * root * (3.0f - x * (root * root));
60 return x * root;
61 #endif
62 }
63};
64
65template<>
66struct TUtil<double> {
67 static inline double epsilon() { return 32.0f * FLT_EPSILON; }
68 static inline double one() { return 1.0; }
69 static inline double atan2(double x, double y) { return ::atan2(x, y); }
70 static inline double asin(double x) { return ::asin(x); }
71 static inline double halfPI() { return 1.5707963267948966; }
72};
73
74template <typename T>
75struct TVec3 {
76 T x;
77 T y;
78 T z;
79
80 void set(const TVec3& other) {
81 x = other.x;
82 y = other.y;
83 z = other.z;
84 }
85};
86
87template <>
88struct TVec3<double> {
89 double x, y, z;
90
91 void set(double x_, double y_, double z_) {
92 x = x_;
93 y = y_;
94 z = z_;
95 }
96
97 inline TVec3<double>& operator*=(double b) {
98 scale(b);
99 return *this;
100 }
101
102 void scale(double b) {
103 x *= b;
104 y *= b;
105 z *= b;
106 }
107};
108
109template <>
110struct TVec3<s16> {
111 s16 x, y, z;
112
113 TVec3() {}
114
116 set(x, y, z);
117 }
118
119 TVec3& operator=(const TVec3& b) {
120 // Force copies to use lwz/lha
121 *((s32*)this) = *((s32*)&b);
122 z = b.z;
123 return *this;
124 }
125
126 void set(s16 x_, s16 y_, s16 z_) {
127 x = (s16)x_;
128 y = (s16)y_;
129 z = (s16)z_;
130 }
131};
132
133inline void setTVec3f(const __REGISTER f32* vec_a, __REGISTER f32* vec_b) {
134#ifdef __MWERKS__
135 __REGISTER f32 a_x;
136 __REGISTER f32 b_x;
137
138 asm {
139 psq_l a_x, 0(vec_a), 0, 0
140 lfs b_x, 8(vec_a)
141 psq_st a_x, 0(vec_b), 0, 0
142 stfs b_x, 8(vec_b)
143 };
144#endif
145}
146
147// Until we figure out TVec3 ctors
148inline void setTVec3f(const Vec& vec_a, Vec& vec_b) {
149 setTVec3f(&vec_a.x, &vec_b.x);
150}
151
152inline float fsqrt_step(float mag) {
153 #ifdef __MWERKS__
154 f32 root = __frsqrte(mag);
155 return 0.5f * root * (3.0f - mag * (root * root));
156 #endif
157}
158
159inline void mulInternal(__REGISTER const f32* a, __REGISTER const f32* b, __REGISTER float* dst) {
160#ifdef __MWERKS__
161 __REGISTER f32 a_x_y;
162 __REGISTER f32 b_x_y;
163 __REGISTER f32 x_y;
164 __REGISTER f32 za;
165 __REGISTER f32 zb;
166 __REGISTER f32 z;
167
168 asm {
169 psq_l a_x_y, 0(a), 0, 0
170 psq_l b_x_y, 0(b), 0, 0
171 ps_mul x_y, a_x_y, b_x_y
172 psq_st x_y, 0(dst), 0, 0
173 };
174 dst[2] = a[2] * b[2];
175#endif
176}
177
178template <>
179struct TVec3<f32> : public Vec {
180 TVec3(const Vec& i_vec) {
181 setTVec3f(&i_vec.x, &x);
182 }
183
184 TVec3(const TVec3<f32>& i_vec) {
185 setTVec3f(&i_vec.x, &x);
186 }
187
188 template<class U>
189 TVec3(U x, U y, U z) {
190 set((U)x, (U)y, (U)z);
191 }
192
193 TVec3() {}
194
195 operator Vec*() { return (Vec*)&x; }
196 operator const Vec*() const { return (Vec*)&x; }
197
198 template<class U>
199 void set(const TVec3<U>& other) {
200 x = (U)other.x;
201 y = (U)other.y;
202 z = (U)other.z;
203 }
204
205 void set(const Vec& other) {
206 x = other.x;
207 y = other.y;
208 z = other.z;
209 }
210
211 template<class U>
212 void set(U x_, U y_, U z_) {
213 x = (U)x_;
214 y = (U)y_;
215 z = (U)z_;
216 }
217
218 inline void add(const TVec3<f32>& b) {
219 JMathInlineVEC::C_VECAdd((Vec*)&x, (Vec*)&b.x, (Vec*)&x);
220 }
221
222 void zero() { x = y = z = 0.0f; }
223
224 void mul(const TVec3<f32>& a, const TVec3<f32>& b) {
225 mulInternal(&a.x, &b.x, &this->x);
226 }
227
228 inline void mul(const TVec3<f32>& a) {
229 mul(*this, a);
230 }
231
232 inline TVec3<f32>& operator=(const Vec& b) {
233 setTVec3f(&b.x, &this->x);
234 return *this;
235 }
236
237 inline TVec3<f32>& operator=(const TVec3<f32>& b) {
238 setTVec3f(&b.x, &this->x);
239 return *this;
240 }
241
242 inline TVec3<f32>& operator+=(const TVec3<f32>& b) {
243 add(b);
244 return *this;
245 }
246
247 inline TVec3<f32> operator+(const TVec3<f32>& b) const {
248 TVec3<f32> a = *this;
249 a += b;
250 return a;
251 }
252
253 // inline TVec3<f32> operator+(const TVec3<f32>& b) {
254 // TVec3<f32> res(*(Vec*)this);
255 // res += b;
256 // return res;
257 // }
258
259 f32 squared() const {
261 }
262
264 f32 sq = squared();
265 if (sq <= TUtil<f32>::epsilon()) {
266 return 0.0f;
267 }
268 f32 inv_norm = TUtil<f32>::inv_sqrt(sq);
269 scale(inv_norm);
270 return inv_norm * sq;
271 }
272
273 f32 normalize(const TVec3<f32>& other) {
274 f32 sq = other.squared();
275 if (sq <= TUtil<f32>::epsilon()) {
276 zero();
277 return 0.0f;
278 }
279 f32 norm = TUtil<f32>::inv_sqrt(sq);
280 scale(norm, other);
281 return norm * sq;
282 }
283
284 f32 length() const {
285 return VECMag((Vec*)this);
286 }
287
288 void scale(__REGISTER f32 sc) {
289#if PLATFORM_GCN && defined(__MWERKS__)
290 __REGISTER f32 z;
291 __REGISTER f32 x_y;
292 __REGISTER f32* dst = &x;
293 __REGISTER f32 zres;
294
295 asm {
296 psq_l x_y, 0(dst), 0, 0
297 psq_l z, 8(dst), 1, 0
298 ps_muls0 x_y, x_y, sc
299 psq_st x_y, 0(dst), 0, 0
300 ps_muls0 zres, z, sc
301 psq_st zres, 8(dst), 1, 0
302 };
303#else
304 x *= sc;
305 y *= sc;
306 z *= sc;
307#endif
308 }
309
310 void scale(__REGISTER f32 sc, const TVec3<f32>& other) {
311#if PLATFORM_GCN && defined(__MWERKS__)
312 __REGISTER const f32* src = &other.x;
313 __REGISTER f32 z;
314 __REGISTER f32 x_y;
315 __REGISTER f32* dst = &x;
316 __REGISTER f32 zres;
317
318 asm {
319 psq_l x_y, 0(src), 0, 0
320 psq_l z, 8(src), 1, 0
321 ps_muls0 x_y, x_y, sc
322 psq_st x_y, 0(dst), 0, 0
323 ps_muls0 zres, z, sc
324 psq_st zres, 8(dst), 1, 0
325 };
326#else
327 x = other.x * sc;
328 y = other.y * sc;
329 z = other.z * sc;
330#endif
331 }
332
333 void scaleAdd(__REGISTER f32 sc, const TVec3<f32>& a, const TVec3<f32>& b) {
334 JMAVECScaleAdd(&a, &b, this, sc);
335 }
336
338#ifdef __MWERKS__
339 __REGISTER f32* rdst = &dst->x;
340 const __REGISTER f32* src = &x;
341 __REGISTER f32 x_y;
342 __REGISTER f32 z;
343
344 asm {
345 psq_l x_y, 0(src), 0, 0
346 ps_neg x_y, x_y
347 psq_st x_y, 0(rdst), 0, 0
348 lfs z, 8(src)
349 fneg z, z
350 stfs z, 8(rdst)
351 };
352#endif
353 }
354
355 void negate() {
356 negateInternal(this);
357 }
358
359 void sub(const TVec3<f32>& b) {
361 }
362
363 void sub(const TVec3<f32>& a, const TVec3<f32>& b) {
364 JMathInlineVEC::C_VECSubtract((Vec*)&a.x, (Vec*)&b.x, (Vec*)&x);
365 }
366
367 bool isZero() const {
368 return squared() <= TUtil<f32>::epsilon();
369 }
370
371 void cross(const TVec3<f32>& a, const TVec3<f32>& b) {
372 PSVECCrossProduct(&a, &b, this);
373 }
374
376 f32 sq = squared();
377 if (sq <= TUtil<f32>::epsilon()) {
378 return 0.0f;
379 }
380 f32 inv_norm = TUtil<f32>::inv_sqrt(sq);
381 scale(inv_norm * len);
382 return inv_norm * sq;
383 }
384
385 f32 setLength(const TVec3<f32>& other, f32 len) {
386 f32 sq = other.squared();
387 if (sq <= TUtil<f32>::epsilon()) {
388 zero();
389 return 0.0f;
390 }
391 f32 inv_norm = TUtil<f32>::inv_sqrt(sq);
392 scale(inv_norm * len, other);
393 return inv_norm * sq;
394 }
395
396 f32 dot(const TVec3<f32>& other) const {
397 return JMathInlineVEC::C_VECDotProduct(this, &other);
398 }
399
400 void cubic(const TVec3<f32>& param_1, const TVec3<f32>& param_2, const TVec3<f32>& param_3,
401 const TVec3<f32>& param_4, f32 param_5) {
402 f32 fVar5 = param_5 * param_5;
403 f32 fVar6 = fVar5 * param_5;
404 f32 fVar8 = 1.0f + (2.0f * fVar6 - 3.0f * fVar5);
405 f32 fVar9 = -2.0f * fVar6 + 3.0f * fVar5;
406 f32 fVar7 = param_5 + (fVar6 - 2.0f * fVar5);
407 f32 fVar4 = fVar6 - fVar5;
408 x = fVar8 * param_1.x + fVar9 * param_4.x + fVar7 * param_2.x + fVar4 * param_3.x;
409 y = fVar8 * param_1.y + fVar9 * param_4.y + fVar7 * param_2.y + fVar4 * param_3.y;
410 z = fVar8 * param_1.z + fVar9 * param_4.z + fVar7 * param_2.z + fVar4 * param_3.z;
411 }
412};
413
414template <typename T>
415struct TVec2 {
416 TVec2() {}
417 TVec2(T v) { set(v); }
418
419 template <typename U>
420 TVec2(const U x, const U y) { set(x, y); }
421
422 void set(T v) { y = x = v; }
423
424 template <typename U>
425 void set(const U x, const U y) {
426 this->x = x;
427 this->y = y;
428 }
429
430 template <typename U>
431 void set(const TVec2<U>& other) {
432 x = other.x;
433 y = other.y;
434 }
435
436 void setMin(const TVec2<f32>& min) {
437 if (x >= min.x)
438 x = min.x;
439 if (y >= min.y)
440 y = min.y;
441 }
442
443 void setMax(const TVec2<f32>& max) {
444 if (x <= max.x)
445 x = max.x;
446 if (y <= max.y)
447 y = max.y;
448 }
449
450 void add(const TVec2<T>& other) {
451 x += other.x;
452 y += other.y;
453 }
454
455 bool equals(const TVec2<T>& other) const {
456 bool result = false;
457 if (this->x == other.x && this->y == other.y) {
458 result = true;
459 }
460 return result;
461 }
462
463 bool isAbove(const TVec2<T>& other) const {
464 return (x >= other.x) && (y >= other.y) ? true : false;
465 }
466
467 f32 dot(const TVec2<T>& other) const {
468 return x * other.x + y * other.y;
469 }
470
471 f32 squared() const {
472 return dot(*this);
473 }
474
475 f32 length() const {
476 return TUtil<f32>::sqrt(squared());
477 }
478
479 bool operator==(const TVec2<T>& other) const {
480 return equals(other);
481 }
482
483 T x;
484 T y;
485};
486
487template <class T>
488struct TBox {
489 TBox() : i(), f() {}
490 TBox(const TBox& other) : i(other.i), f(other.f) {}
491
492 T i, f;
493};
494
495// clang-format off
496template<> struct TBox<TVec2<f32> > {
497 f32 getWidth() const { return f.x - i.x; }
498 f32 getHeight() const { return f.y - i.y; }
499
500 bool isValid() const { return f.isAbove(i); }
501
502 void addPos(f32 x, f32 y) {
503 addPos(TVec2<f32>(x, y));
504 }
505
506 void addPos(const TVec2<f32>& pos) {
507 i.add(pos);
508 f.add(pos);
509 }
510
511 bool intersect(const TBox<TVec2<f32> >& other) {
512 i.setMax(other.i);
513 f.setMin(other.f);
514 return isValid();
515 }
516
517 void absolute() {
518 if (this->isValid()) {
519 return;
520 }
521
522 TBox<TVec2<f32> > box(*this);
523 this->i.setMin(box.i);
524 this->i.setMin(box.f);
525 this->f.setMax(box.i);
526 this->f.setMax(box.f);
527 }
528
530};
531
532template <typename T>
533struct TBox2 : public TBox<TVec2<T> > {
534 TBox2() {}
535 TBox2(const TVec2<f32>& _i, const TVec2<f32>& _f) {
536 TBox<TVec2<T> >::i.set(_i);
537 TBox<TVec2<T> >::f.set(_f);
538 }
539 TBox2(f32 x0, f32 y0, f32 x1, f32 y1) { set(x0, y0, x1, y1); }
540
541 void set(const TBox<TVec2<T> >& other) { set(other.i, other.f); }
542 void set(const TVec2<f32>& i, const TVec2<f32>& f) { this->i.set(i), this->f.set(f); }
543 void set(f32 x0, f32 y0, f32 x1, f32 y1) { this->i.set(x0, y0); this->f.set(x1, y1); }
544};
545
546// clang-format on
547
548} // namespace JGeometry
549
550#endif
static int min(int a, int b)
Definition JHIComm.cpp:155
void JMAVECScaleAdd(__REGISTER const Vec *vec1, __REGISTER const Vec *vec2, __REGISTER Vec *dst, __REGISTER f32 scale)
Definition JMath.cpp:74
asm void PSVECCrossProduct(const __REGISTER Vec *a, const __REGISTER Vec *b, __REGISTER Vec *axb)
Definition vec.c:206
const void * src
Definition __os.h:116
double x double x
Definition e_atan2.c:58
static const static double double zero
Definition e_atan2.c:50
double x double y
Definition e_atan2.c:58
z
Definition e_log.c:139
double y1
Definition e_pow.c:114
double v
Definition e_pow.c:114
signed short int s16
Definition types.h:9
float f32
Definition types.h:25
signed long s32
Definition types.h:11
a
Definition k_cos.c:89
Definition JGeometry.h:13
float fsqrt_step(float mag)
Definition JGeometry.h:152
void mulInternal(__REGISTER const f32 *a, __REGISTER const f32 *b, __REGISTER float *dst)
Definition JGeometry.h:159
void setTVec3f(const __REGISTER f32 *vec_a, __REGISTER f32 *vec_b)
Definition JGeometry.h:133
void C_VECSubtract(__REGISTER const Vec *a, __REGISTER const Vec *b, __REGISTER Vec *ab)
Definition JMath.h:217
f32 C_VECDotProduct(__REGISTER const Vec *a, __REGISTER const Vec *b)
Definition JMath.h:254
f32 C_VECSquareMag(__REGISTER const Vec *v)
Definition JMath.h:237
void C_VECAdd(__REGISTER const Vec *a, __REGISTER const Vec *b, __REGISTER Vec *ab)
Definition JMath.h:196
Definition JGeometry.h:533
void set(const TVec2< f32 > &i, const TVec2< f32 > &f)
Definition JGeometry.h:542
void set(const TBox< TVec2< T > > &other)
Definition JGeometry.h:541
TBox2(f32 x0, f32 y0, f32 x1, f32 y1)
Definition JGeometry.h:539
void set(f32 x0, f32 y0, f32 x1, f32 y1)
Definition JGeometry.h:543
TBox2()
Definition JGeometry.h:534
TBox2(const TVec2< f32 > &_i, const TVec2< f32 > &_f)
Definition JGeometry.h:535
void absolute()
Definition JGeometry.h:517
TVec2< f32 > f
Definition JGeometry.h:529
void addPos(const TVec2< f32 > &pos)
Definition JGeometry.h:506
bool intersect(const TBox< TVec2< f32 > > &other)
Definition JGeometry.h:511
f32 getHeight() const
Definition JGeometry.h:498
bool isValid() const
Definition JGeometry.h:500
f32 getWidth() const
Definition JGeometry.h:497
void addPos(f32 x, f32 y)
Definition JGeometry.h:502
Definition JGeometry.h:488
TBox(const TBox &other)
Definition JGeometry.h:490
TBox()
Definition JGeometry.h:489
T i
Definition JGeometry.h:492
T f
Definition JGeometry.h:492
static double one()
Definition JGeometry.h:68
static double halfPI()
Definition JGeometry.h:71
static double epsilon()
Definition JGeometry.h:67
static double atan2(double x, double y)
Definition JGeometry.h:69
static double asin(double x)
Definition JGeometry.h:70
static f32 inv_sqrt(f32 x)
Definition JGeometry.h:41
static f32 clamp(f32 v, f32 min, f32 max)
Definition JGeometry.h:30
static f32 PI()
Definition JGeometry.h:40
static f32 epsilon()
Definition JGeometry.h:39
static f32 sqrt(f32 x)
Definition JGeometry.h:52
Definition JGeometry.h:16
static T clamp(T v, T min, T max)
Definition JGeometry.h:17
Definition JGeometry.h:415
void set(const U x, const U y)
Definition JGeometry.h:425
bool isAbove(const TVec2< T > &other) const
Definition JGeometry.h:463
void setMax(const TVec2< f32 > &max)
Definition JGeometry.h:443
void add(const TVec2< T > &other)
Definition JGeometry.h:450
void set(T v)
Definition JGeometry.h:422
f32 squared() const
Definition JGeometry.h:471
f32 dot(const TVec2< T > &other) const
Definition JGeometry.h:467
bool operator==(const TVec2< T > &other) const
Definition JGeometry.h:479
TVec2(const U x, const U y)
Definition JGeometry.h:420
TVec2()
Definition JGeometry.h:416
void setMin(const TVec2< f32 > &min)
Definition JGeometry.h:436
TVec2(T v)
Definition JGeometry.h:417
void set(const TVec2< U > &other)
Definition JGeometry.h:431
T x
Definition JGeometry.h:483
T y
Definition JGeometry.h:484
bool equals(const TVec2< T > &other) const
Definition JGeometry.h:455
f32 length() const
Definition JGeometry.h:475
void scale(double b)
Definition JGeometry.h:102
void set(double x_, double y_, double z_)
Definition JGeometry.h:91
double x
Definition JGeometry.h:89
TVec3< double > & operator*=(double b)
Definition JGeometry.h:97
void mul(const TVec3< f32 > &a)
Definition JGeometry.h:228
f32 squared() const
Definition JGeometry.h:259
void cross(const TVec3< f32 > &a, const TVec3< f32 > &b)
Definition JGeometry.h:371
TVec3< f32 > & operator+=(const TVec3< f32 > &b)
Definition JGeometry.h:242
void mul(const TVec3< f32 > &a, const TVec3< f32 > &b)
Definition JGeometry.h:224
TVec3(const TVec3< f32 > &i_vec)
Definition JGeometry.h:184
f32 normalize(const TVec3< f32 > &other)
Definition JGeometry.h:273
TVec3()
Definition JGeometry.h:193
void scale(__REGISTER f32 sc, const TVec3< f32 > &other)
Definition JGeometry.h:310
f32 length() const
Definition JGeometry.h:284
TVec3< f32 > operator+(const TVec3< f32 > &b) const
Definition JGeometry.h:247
void negate()
Definition JGeometry.h:355
TVec3(const Vec &i_vec)
Definition JGeometry.h:180
TVec3(U x, U y, U z)
Definition JGeometry.h:189
bool isZero() const
Definition JGeometry.h:367
f32 setLength(f32 len)
Definition JGeometry.h:375
f32 setLength(const TVec3< f32 > &other, f32 len)
Definition JGeometry.h:385
TVec3< f32 > & operator=(const Vec &b)
Definition JGeometry.h:232
f32 normalize()
Definition JGeometry.h:263
void sub(const TVec3< f32 > &a, const TVec3< f32 > &b)
Definition JGeometry.h:363
void scaleAdd(__REGISTER f32 sc, const TVec3< f32 > &a, const TVec3< f32 > &b)
Definition JGeometry.h:333
void sub(const TVec3< f32 > &b)
Definition JGeometry.h:359
void zero()
Definition JGeometry.h:222
void scale(__REGISTER f32 sc)
Definition JGeometry.h:288
void set(const TVec3< U > &other)
Definition JGeometry.h:199
TVec3< f32 > & operator=(const TVec3< f32 > &b)
Definition JGeometry.h:237
void negateInternal(TVec3< f32 > *dst)
Definition JGeometry.h:337
void cubic(const TVec3< f32 > &param_1, const TVec3< f32 > &param_2, const TVec3< f32 > &param_3, const TVec3< f32 > &param_4, f32 param_5)
Definition JGeometry.h:400
void set(U x_, U y_, U z_)
Definition JGeometry.h:212
void set(const Vec &other)
Definition JGeometry.h:205
f32 dot(const TVec3< f32 > &other) const
Definition JGeometry.h:396
void add(const TVec3< f32 > &b)
Definition JGeometry.h:218
TVec3()
Definition JGeometry.h:113
s16 x
Definition JGeometry.h:111
void set(s16 x_, s16 y_, s16 z_)
Definition JGeometry.h:126
TVec3 & operator=(const TVec3 &b)
Definition JGeometry.h:119
TVec3(s16 x, s16 y, s16 z)
Definition JGeometry.h:115
Definition JGeometry.h:75
T x
Definition JGeometry.h:76
void set(const TVec3 &other)
Definition JGeometry.h:80
T z
Definition JGeometry.h:78
T y
Definition JGeometry.h:77
Definition mtx.h:13
f32 z
Definition mtx.h:14
f32 x
Definition mtx.h:14
f32 y
Definition mtx.h:14