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