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