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