summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/sys_math.c48
-rwxr-xr-xsrc/code/sys_math3d.c1716
-rw-r--r--src/code/sys_math_atan.c134
-rw-r--r--src/code/z_play.c4
4 files changed, 1900 insertions, 2 deletions
diff --git a/src/code/sys_math.c b/src/code/sys_math.c
new file mode 100644
index 000000000..25af276ec
--- /dev/null
+++ b/src/code/sys_math.c
@@ -0,0 +1,48 @@
+#include <global.h>
+#include <math.h>
+f32 sFactorialTbl[] = { 1.0f, 1.0f, 2.0f, 6.0f, 24.0f, 120.0f, 720.0f,
+ 5040.0f, 40320.0f, 362880.0f, 3628800.0f, 39916800.0f, 479001600.0f };
+
+f32 func_800CA540(f32 arg0) {
+ f32 ret = 1.0f;
+ s32 i;
+ for (i = arg0; i > 1; i--) {
+ ret *= i;
+ }
+ return ret;
+}
+
+#ifdef NON_MATCHING
+f32 func_800CA63C(u32 arg0) {
+ f32 ret;
+ s32 i;
+ if (arg0 > 12) {
+ ret = sFactorialTbl[12];
+ for (i = 13; i < (s32)arg0; i++) {
+ ret *= i;
+ }
+ } else {
+ ret = sFactorialTbl[arg0];
+ }
+ return ret;
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math/func_800CA63C.s")
+#endif
+
+f32 func_800CA6FC(f32 arg0, s32 arg1) {
+ f32 ret = 1.0f;
+ while (arg1 > 0) {
+ arg1--;
+ ret *= arg0;
+ }
+ return ret;
+}
+
+f32 func_800CA720(f32 arg0) {
+ return sins((s16)(arg0 * (32767.0f / M_PI))) * SHT_MINV;
+}
+
+f32 func_800CA774(f32 arg0) {
+ return coss((s16)(arg0 * (32767.0f / M_PI))) * SHT_MINV;
+}
diff --git a/src/code/sys_math3d.c b/src/code/sys_math3d.c
new file mode 100755
index 000000000..7a2aa4331
--- /dev/null
+++ b/src/code/sys_math3d.c
@@ -0,0 +1,1716 @@
+#include <ultra64.h>
+#include <global.h>
+#include <vt.h>
+
+s32 func_800CA8E8(Vec3f*, Vec3f*, Vec3f*, Vec3f*, Vec3f*, Vec3f*);
+s32 Math3D_TriLineIntersect(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, Vec3f* arg7,
+ Vec3f* arg8, Vec3f* arg9, s32 argA);
+s32 func_800CAD08(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, Linef* arg8);
+s32 func_800CB1F8(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8);
+s32 func_800CB338(Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* center, f32 radius);
+
+s32 func_800CA7D0(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, Vec3f* arg8,
+ Vec3f* arg9, Vec3f* argA) {
+ static Linef D_8016A5A0;
+ static Linef D_8016A5B8;
+
+ Vec3f sp34;
+
+ if (func_800CAD08(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &D_8016A5A0) == 0) {
+ return 0;
+ }
+ Math_Vec3f_Copy(&D_8016A5B8.a, &D_8016A5A0.a);
+
+ D_8016A5B8.b.x = (D_8016A5A0.b.x * 100.0f) + D_8016A5A0.a.x;
+ D_8016A5B8.b.y = (D_8016A5A0.b.y * 100.0f) + D_8016A5A0.a.y;
+ D_8016A5B8.b.z = (D_8016A5A0.b.z * 100.0f) + D_8016A5A0.a.z;
+
+ if (!func_800CA8E8(&D_8016A5B8.a, &D_8016A5B8.b, arg8, arg9, argA, &sp34)) {
+ return 0;
+ }
+ return 1;
+}
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_800CA8E8.s")
+
+void Math3D_LineVsPos(Linef* line, Vec3f* pos, Vec3f* ret) {
+ f32 temp_ret;
+ f32 temp_f0;
+
+ temp_ret = func_800CB600(&line->b);
+ if (fabsf(temp_ret) < 0.008f) {
+ osSyncPrintf(VT_COL(YELLOW, BLACK));
+ // Math3D_lineVsPosSuisenCross(): No straight line length
+ osSyncPrintf("Math3D_lineVsPosSuisenCross():直線の長さがありません\n");
+ // Returns cross = pos.
+ osSyncPrintf("cross = pos を返します。\n");
+ osSyncPrintf(VT_RST);
+ Math_Vec3f_Copy(ret, pos);
+ }
+ temp_f0 =
+ (((pos->x - line->a.x) * line->b.x) + ((pos->y - line->a.y) * line->b.y) + ((pos->z - line->a.z) * line->b.z)) /
+ temp_ret;
+ ret->x = (line->b.x * temp_f0) + line->a.x;
+ ret->y = (line->b.y * temp_f0) + line->a.y;
+ ret->z = (line->b.z * temp_f0) + line->a.z;
+}
+
+void func_800CACAC(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32* arg7, f32* arg8) {
+ *arg7 = ((arg1 * arg6) - (arg3 * arg5)) / arg4;
+ *arg8 = ((arg2 * arg5) - (arg0 * arg6)) / arg4;
+}
+
+s32 func_800CAD08(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, Linef* arg8) {
+ char pad[4];
+ Vec3f sp60;
+ Vec3f sp54;
+ f32 ax;
+ f32 ay;
+ f32 az;
+
+ VEC_SET(sp60, arg0, arg1, arg2);
+ VEC_SET(sp54, arg4, arg5, arg6);
+
+ Math3D_Vec3f_Cross(&sp60, &sp54, &arg8->b);
+
+ if (fabsf(arg8->b.x) < 0.008f && fabsf(arg8->b.y) < 0.008f && fabsf(arg8->b.z) < 0.008f) {
+ return 0;
+ }
+
+ ax = fabsf(arg8->b.x);
+ ay = fabsf(arg8->b.y);
+ az = fabsf(arg8->b.z);
+
+ if ((ay <= ax) && (az <= ax)) {
+ func_800CACAC(arg1, arg2, arg5, arg6, arg8->b.x, arg3, arg7, &arg8->a.y, &arg8->a.z);
+ arg8->a.x = 0.0f;
+ } else if ((ax <= ay) && (az <= ay)) {
+ func_800CACAC(arg2, arg0, arg6, arg4, arg8->b.y, arg3, arg7, &arg8->a.z, &arg8->a.x);
+ arg8->a.y = 0.0f;
+ } else {
+ func_800CACAC(arg0, arg1, arg4, arg5, arg8->b.z, arg3, arg7, &arg8->a.x, &arg8->a.y);
+ arg8->a.z = 0.0f;
+ }
+ return 1;
+}
+
+s32 func_800CAEE8(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, Vec3f* arg8,
+ Vec3f* arg9) {
+ static Linef D_8016A5D0;
+
+ if (func_800CAD08(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, &D_8016A5D0) == 0) {
+ return 0;
+ }
+ Math3D_LineVsPos(&D_8016A5D0, arg8, arg9);
+ return 1;
+}
+
+void func_800CAF5C(Vec3f* arg0, Vec3f* arg1, f32 arg2, Vec3f* arg3) {
+ arg3->x = (arg1->x * arg2) + arg0->x;
+ arg3->y = (arg1->y * arg2) + arg0->y;
+ arg3->z = (arg1->z * arg2) + arg0->z;
+}
+
+void func_800CAFA0(Vec3f* v0, Vec3f* v1, f32 arg2, Vec3f* ret) {
+ Vec3f diff;
+
+ Math_Vec3f_Diff(v1, v0, &diff);
+ func_800CAF5C(v0, &diff, arg2, ret);
+}
+
+f32 Math3D_DotProduct(Vec3f* vec1, Vec3f* vec2) {
+ f32 ret;
+
+ func_800CB010(vec1, vec2, &ret);
+ return ret;
+}
+
+s32 func_800CB010(Vec3f* vec1, Vec3f* vec2, f32* dst) {
+ f32 magProduct;
+
+ magProduct = Math3D_Vec3fMagnitude(vec1) * Math3D_Vec3fMagnitude(vec2);
+ if (fabsf(magProduct) < 0.008f) {
+ *dst = 0.0f;
+ return 1;
+ }
+ *dst = ((vec1->x * vec2->x) + (vec1->y * vec2->y) + (vec1->z * vec2->z)) / magProduct;
+ return 0;
+}
+
+void func_800CB0C0(Vec3f* vec1, Vec3f* vec2, Vec3f* ret) {
+
+ f32 temp_f12;
+ Vec3f negVec1;
+ f32 temp_f14;
+ f32 temp_f2;
+ f32 dotProduct;
+
+ negVec1.x = vec1->x * -1.0f;
+ negVec1.y = vec1->y * -1.0f;
+ negVec1.z = vec1->z * -1.0f;
+
+ dotProduct = Math3D_DotProduct(&negVec1, vec2);
+
+ temp_f2 = vec2->x * dotProduct;
+ temp_f12 = vec2->y * dotProduct;
+ temp_f14 = vec2->z * dotProduct;
+
+ ret->x = ((temp_f2 + vec1->x) + (temp_f2 + vec1->x)) + negVec1.x;
+ ret->y = ((temp_f12 + vec1->y) + (temp_f12 + vec1->y)) + negVec1.y;
+ ret->z = ((temp_f14 + vec1->z) + (temp_f14 + vec1->z)) + negVec1.z;
+}
+
+s32 func_800CB198(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5) {
+ if (arg0 <= arg4 && arg4 <= arg1 && arg2 <= arg5 && arg5 <= arg3) {
+ return 1;
+ }
+ return 0;
+}
+
+/*************************************************************************/
+/* The next 2 functions have some interesting control flow */
+/*************************************************************************/
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_800CB1F8.s")
+
+#ifdef NON_MATCHING
+/*
+ * Math3D_TriInSphere
+ * Checks if a tringle defined by `v0`, `v1`, and `v2` lies within a spehere
+ * centered at `center` and has radius `radius`. Returns 1 if any vertex of the
+ * triangle lies within the sphere, or 0 otherwise.
+ */
+s32 func_800CB338(Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* center, f32 radius) {
+ f32 minX;
+ f32 maxX;
+ f32 minY;
+ f32 maxY;
+ f32 minZ;
+ f32 maxZ;
+
+ if (v1->x < v0->x) {
+ minX = v1->x;
+ maxX = v0->x;
+ } else if (v0->x < v1->x) {
+ minX = v0->x;
+ maxX = v1->x;
+ }
+
+ if (v1->y < v0->y) {
+ minY = v1->y;
+ maxY = v0->y;
+ } else if (v0->y < v1->y) {
+ minY = v0->y;
+ maxY = v1->y;
+ }
+
+ if (v1->z < v0->z) {
+ minZ = v1->z;
+ maxZ = v0->z;
+ } else if (v0->z < v1->z) {
+ minZ = v0->z;
+ maxZ = v1->z;
+ }
+
+ if (v2->x < minX) {
+ minX = v2->x;
+ } else if (maxX < v2->x) {
+ maxX = v2->x;
+ }
+
+ if (v2->y < minY) {
+ minY = v2->y;
+ } else if (maxY < v2->y) {
+ maxY = v2->y;
+ }
+
+ if (v2->z < minZ) {
+ minZ = v2->z;
+ } else if (maxZ < v2->z) {
+ maxZ = v2->z;
+ }
+
+ if (((minX - radius) <= center->x) && (center->x <= (maxX + radius)) && ((minY - radius) <= center->y) &&
+ (center->y <= (maxY + radius)) && ((minZ - radius) <= center->z) && (center->z <= (maxZ + radius))) {
+ return 1;
+ }
+
+ return 0;
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_800CB338.s")
+#endif
+/**********************************************************************/
+
+f32 func_800CB55C(f32 arg0, f32 arg1) {
+ return SQ(arg0) + SQ(arg1);
+}
+
+f32 func_800CB570(f32 arg0, f32 arg1) {
+ return sqrtf(func_800CB55C(arg0, arg1));
+}
+
+f32 func_800CB594(f32 arg0, f32 arg1, f32 arg2, f32 arg3) {
+ func_800CB55C(arg0 - arg2, arg1 - arg3);
+}
+
+f32 Math3D_Dist2D(f32 arg0, f32 arg1, f32 arg2, f32 arg3) {
+ return sqrtf(func_800CB594(arg0, arg1, arg2, arg3));
+}
+
+f32 func_800CB600(Vec3f* vec) {
+ return SQ(vec->x) + SQ(vec->y) + SQ(vec->z);
+}
+
+f32 Math3D_Vec3fMagnitude(Vec3f* vec) {
+ return sqrt(func_800CB600(vec));
+}
+
+f32 func_800CB650(Vec3f* a, Vec3f* b) {
+ Vec3f diff;
+
+ Math_Vec3f_Diff(a, b, &diff);
+ return func_800CB600(&diff);
+}
+
+/*
+ * Math3D_Vec3f_DistXYZ
+ * Calculates the distance between points `a` and `b`
+ */
+f32 Math3D_Vec3f_DistXYZ(Vec3f* a, Vec3f* b) {
+ return Math_Vec3f_DistXYZ(a, b);
+}
+
+/*
+ * Calculates the distance between `a` and `b`.
+ */
+f32 Math3D_DistXYZ16toF(Vec3s* a, Vec3f* b) {
+ Vec3f diff;
+
+ diff.x = a->x - b->x;
+ diff.y = a->y - b->y;
+ diff.z = a->z - b->z;
+ return Math3D_Vec3fMagnitude(&diff);
+}
+
+f32 func_800CB70C(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3) {
+ return ((arg0->x - arg2) * (arg1->y - arg3)) - ((arg0->y - arg3) * (arg1->x - arg2));
+}
+
+f32 func_800CB744(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3) {
+ return ((arg0->y - arg2) * (arg1->z - arg3)) - ((arg0->z - arg3) * (arg1->y - arg2));
+}
+
+f32 func_800CB77C(Vec3f* arg0, Vec3f* arg1, f32 arg2, f32 arg3) {
+ return ((arg0->z - arg2) * (arg1->x - arg3)) - ((arg0->x - arg3) * (arg1->z - arg2));
+}
+
+void Math3D_Vec3f_Cross(Vec3f* a, Vec3f* b, Vec3f* ret) {
+ ret->x = (a->y * b->z) - (a->z * b->y);
+ ret->y = (a->z * b->x) - (a->x * b->z);
+ ret->z = (a->x * b->y) - (a->y * b->x);
+}
+
+/*
+ * Calculates the normal vector to a surface with sides `vb` - `va` and `vc` - `va`
+ * outputs the normal to `normal`
+ */
+void Math3D_SurfaceNorm(Vec3f* va, Vec3f* vb, Vec3f* vc, Vec3f* normal) {
+ static Vec3f abDiff;
+ static Vec3f acDiff;
+
+ Math_Vec3f_Diff(vb, va, &abDiff);
+ Math_Vec3f_Diff(vc, va, &acDiff);
+ Math3D_Vec3f_Cross(&abDiff, &acDiff, normal);
+}
+
+s32 func_800CB88C(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2) {
+ s32 ret = 0;
+
+ if (arg2->x < arg0->x) {
+ ret = 1;
+ }
+
+ if (arg0->x < arg1->x) {
+ ret |= 2;
+ }
+
+ if (arg2->y < arg0->y) {
+ ret |= 4;
+ }
+
+ if (arg0->y < arg1->y) {
+ ret |= 8;
+ }
+
+ if (arg2->z < arg0->z) {
+ ret |= 0x10;
+ }
+
+ if (arg0->z < arg1->z) {
+ ret |= 0x20;
+ }
+ return ret;
+}
+
+#ifdef NON_MATCHING
+s32 func_800CB934(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2) {
+ s32 ret = 0;
+
+ if ((arg2->y - arg1->x) < (arg0->y - arg0->x)) {
+ ret = 1;
+ }
+
+ if ((arg0->y - arg0->x) < (arg1->y - arg2->x)) {
+ ret |= 2;
+ }
+
+ if ((arg2->x + arg2->y) < (arg0->x + arg0->y)) {
+ ret |= 4;
+ }
+
+ if ((arg0->x + arg0->y) < (arg1->x + arg1->y)) {
+ ret |= 8;
+ }
+
+ if ((-arg1->z + arg2->y) < (-arg0->z + arg0->y)) {
+ ret |= 0x10;
+ }
+
+ if ((-arg0->z + arg0->y) < (arg1->y - arg2->z)) {
+ ret |= 0x20;
+ }
+
+ if ((arg2->z + arg2->y) < (arg0->z + arg0->y)) {
+ ret |= 0x40;
+ }
+
+ if ((arg0->z + arg0->y) < (arg1->z + arg1->y)) {
+ ret |= 0x80;
+ }
+
+ if ((-arg1->z + arg2->x) < (-arg0->z + arg0->x)) {
+ ret |= 0x100;
+ }
+
+ if ((-arg0->z + arg0->x) < (-arg2->z + arg1->x)) {
+ ret |= 0x200;
+ }
+
+ if ((arg2->z + arg2->x) < (arg0->z + arg0->x)) {
+ ret |= 0x400;
+ }
+
+ if ((arg0->z + arg0->x) < (arg1->z + arg1->x)) {
+ ret |= 0x800;
+ }
+ return ret;
+}
+#else
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_800CB934.s")
+#endif
+
+s32 func_800CBAE4(Vec3f* v0, Vec3f* v1, Vec3f* v2) {
+ s32 ret = 0;
+
+ if ((v2->x + v2->y + v2->z) < (v0->x + v0->y + v0->z)) {
+ ret = 0x01;
+ }
+
+ if ((-v1->x + v2->y + v2->z) < (-v0->x + v0->y + v0->z)) {
+ ret |= 0x02;
+ }
+
+ if ((-v1->x + v2->y - v1->z) < (-v0->x + v0->y - v0->z)) {
+ ret |= 0x04;
+ }
+
+ if ((v2->x + v2->y - v1->z) < (v0->x + v0->y - v0->z)) {
+ ret |= 0x08;
+ }
+
+ if ((v2->x - v1->y + v2->z) < (v0->x - v0->y + v0->z)) {
+ ret |= 0x10;
+ }
+
+ if ((-v1->x - v1->y + v2->z) < (-v0->x - v0->y + v0->z)) {
+ ret |= 0x20;
+ }
+
+ if ((-v1->x - v1->y + v2->z) < (-v0->x - v0->y + v0->z)) {
+ ret |= 0x40;
+ }
+
+ if ((-v1->x - v1->y - v1->z) < (-v0->x - v0->y - v0->z)) {
+ ret |= 0x80;
+ }
+ return ret;
+}
+
+s32 func_800CBC60(Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* v3) {
+ static Vec3f D_8016A608;
+ static Vec3f D_8016A618;
+ static Vec3f D_8016A628;
+ static Vec3f D_8016A638;
+
+ s32 flags[2];
+
+ flags[0] = flags[1] = 0;
+ flags[0] = func_800CB88C(v2, v0, v1);
+ if (!flags[0]) {
+ return 1;
+ }
+
+ flags[1] = func_800CB88C(v3, v0, v1);
+ if (!flags[1]) {
+ return 1;
+ }
+
+ if (flags[0] & flags[1]) {
+ return 0;
+ }
+
+ flags[0] |= (func_800CB934(v2, v0, v1) << 8);
+ flags[1] |= (func_800CB934(v3, v0, v1) << 8);
+ if (flags[0] & flags[1]) {
+ return 0;
+ }
+
+ flags[0] |= (func_800CBAE4(v2, v0, v1) << 0x18);
+ flags[1] |= (func_800CBAE4(v3, v0, v1) << 0x18);
+ if (flags[0] & flags[1]) {
+ return 0;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v0->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, -1.0f, 0.0f, 0.0f, v0->x, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v1->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v0->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, -1.0f, 0.0f, 0.0f, v0->x, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 0.0f, 1.0f, -v1->z, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v1->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v1->x;
+ // POSSIBLE BUG?
+ D_8016A618.y = v0->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 0.0f, 1.0f, -v1->z, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v1->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v1->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v0->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 1.0f, 0.0f, -v1->y, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v1->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v1->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v0->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 1.0f, 0.0f, -v1->y, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v0->x;
+ D_8016A618.y = v1->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 0.0f, -1.0f, v0->z, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v1->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v0->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, 0.0f, -1.0f, v0->z, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v0->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, -1.0f, 0.0f, v0->y, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v0->x;
+ D_8016A608.y = v0->y;
+ D_8016A608.z = v0->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v0->x;
+ D_8016A628.y = v0->y;
+ D_8016A628.z = v1->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 0.0f, -1.0f, 0.0f, v0->y, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v1->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v0->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v1->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 1.0f, 0.0f, 0.0f, -v1->x, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+ D_8016A608.x = v1->x;
+ D_8016A608.y = v1->y;
+ D_8016A608.z = v1->z;
+ D_8016A618.x = v1->x;
+ D_8016A618.y = v0->y;
+ D_8016A618.z = v1->z;
+ D_8016A628.x = v1->x;
+ D_8016A628.y = v0->y;
+ D_8016A628.z = v0->z;
+ if (Math3D_TriLineIntersect(&D_8016A608, &D_8016A618, &D_8016A628, 1.0f, 0.0f, 0.0f, -v1->x, v2, v3, &D_8016A638,
+ 0)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+// Some type of quad detection?
+s32 func_800CC6D8(Vec3s* v0, Vec3s* v1, Vec3s* v2, Vec3s* v3) {
+ static Vec3f v0f;
+ static Vec3f v1f;
+ static Vec3f v2f;
+ static Vec3f v3f;
+
+ v0f.x = v0->x;
+ v0f.y = v0->y;
+ v0f.z = v0->z;
+ v1f.x = v1->x;
+ v1f.y = v1->y;
+ v1f.z = v1->z;
+ v2f.x = v2->x;
+ v2f.y = v2->y;
+ v2f.z = v2->z;
+ v3f.x = v3->x;
+ v3f.y = v3->y;
+ v3f.z = v3->z;
+ return func_800CBC60(&v0f, &v1f, &v2f, &v3f);
+}
+
+void func_800CC824(Vec3f* arg0, s16 angle, f32* arg2, f32* arg3, f32* arg4) {
+ *arg2 = Math_Sins(angle) * 32767.0f;
+ *arg3 = Math_Coss(angle) * 32767.0f;
+ *arg4 = -((*arg2 * arg0->x) + (*arg3 * arg0->z));
+}
+
+/*
+ * Defines a plane from verticies `va`, `vb`, and `vc`. Normal components are output to
+ * `nx`, `ny`, and `nz`. Distance from the origin is output to `originDist`
+ * Satisifes the plane equation NxVx + NyVy + NzVz + D = 0
+ */
+void func_800CC8B4(Vec3f* va, Vec3f* vb, Vec3f* vc, f32* nx, f32* ny, f32* nz, f32* originDist) {
+ static Vec3f normal;
+
+ f32 normMagnitude;
+ f32 t;
+
+ Math3D_SurfaceNorm(va, vb, vc, &normal);
+ normMagnitude = sqrtf(SQ(normal.x) + SQ(normal.y) + SQ(normal.z));
+ if (!(fabsf(normMagnitude) < 0.008f)) {
+ t = 1.0f / normMagnitude;
+ *nx = normal.x * t;
+ *ny = normal.y * t;
+ *nz = normal.z * t;
+ *originDist = -((*nx * va->x) + (*ny * va->y) + (*nz * va->z));
+ } else {
+ *originDist = 0.0f;
+ *nz = 0.0f;
+ *ny = 0.0f;
+ *nx = 0.0f;
+ }
+}
+
+/*
+ * Returns the answer to the plane equation with elements specified by arguments.
+ */
+f32 Math3D_Planef(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* v) {
+ return (v->x * nx) + (ny * v->y) + (nz * v->z) + originDist;
+}
+
+/*
+ * Returns the answer to the plane equation
+ */
+f32 Math3D_Plane(Plane* plane, Vec3f* v) {
+ return ((plane->normal.x * v->x) + (plane->normal.y * v->y) + (plane->normal.z * v->z)) + plane->originDist;
+}
+
+/*
+ * Calculates the absolute distance from a point `p` to the plane defined as
+ * `nx`, `ny`, `nz`, and `originDist`
+ */
+f32 Math3D_UDistPlaneToPos(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* p) {
+
+ if (fabsf(sqrtf(SQ(nx) + SQ(ny) + SQ(nz))) < 0.008f) {
+ osSyncPrintf(VT_COL(YELLOW, BLACK));
+ // Math3DLengthPlaneAndPos(): Normal size is near zero %f %f %f
+ osSyncPrintf("Math3DLengthPlaneAndPos():法線size がゼロ近いです%f %f %f\n", nx, ny, nz);
+ osSyncPrintf(VT_RST);
+ return 0.0f;
+ }
+ return fabsf(Math3D_DistPlaneToPos(nx, ny, nz, originDist, p));
+}
+
+/*
+ * Calculates the signed distance from a point `p` to a plane defined as
+ * `nx`, `ny`, `nz`, and `originDist`
+ */
+f32 Math3D_DistPlaneToPos(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* p) {
+ f32 normMagnitude;
+
+ normMagnitude = sqrtf(SQ(nx) + SQ(ny) + SQ(nz));
+ if (fabsf(normMagnitude) < 0.008f) {
+ osSyncPrintf(VT_COL(YELLOW, BLACK));
+ // Math3DSignedLengthPlaneAndPos(): Normal size is close to zero %f %f %f
+ osSyncPrintf("Math3DSignedLengthPlaneAndPos():法線size がゼロ近いです%f %f %f\n", nx, ny, nz);
+ osSyncPrintf(VT_RST);
+ return 0.0f;
+ }
+ return Math3D_Planef(nx, ny, nz, originDist, p) / normMagnitude;
+}
+
+s32 func_800CCBE4(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 arg5, f32 arg6, f32 ny) {
+ f32 temp_f6;
+ f32 temp_f10;
+ f32 temp_f8;
+ f32 sp60;
+ f32 sq6;
+
+ if (func_800CB1F8(v0->z, v0->x, v1->z, v1->x, v2->z, v2->x, z, x, arg6) == 0) {
+ return 0;
+ }
+
+ sq6 = SQ(arg6);
+ if (((SQ(v0->z - z) + SQ(v0->x - x)) < sq6) || ((SQ(v1->z - z) + SQ(v1->x - x)) < sq6) ||
+ ((SQ(v2->z - z) + SQ(v2->x - x)) < sq6)) {
+
+ return 1;
+ }
+
+ temp_f6 = ((v0->z - z) * (v1->x - x)) - ((v0->x - x) * (v1->z - z));
+ temp_f10 = ((v1->z - z) * (v2->x - x)) - ((v1->x - x) * (v2->z - z));
+ temp_f8 = ((v2->z - z) * (v0->x - x)) - ((v2->x - x) * (v0->z - z));
+
+ if (((temp_f6 <= arg5) && (temp_f10 <= arg5) && (temp_f8 <= arg5)) ||
+ ((-arg5 <= temp_f6) && (-arg5 <= temp_f10) && (-arg5 <= temp_f8))) {
+ return 1;
+ }
+ if (0.5f < fabsf(ny)) {
+ if (func_800CE4B8(z, x, v0->z, v0->x, v1->z, v1->x, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+
+ if (func_800CE4B8(z, x, v1->z, v1->x, v2->z, v2->x, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+ if (func_800CE4B8(z, x, v2->z, v2->x, v0->z, v0->x, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+s32 func_800CCF00(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 arg5, f32 ny) {
+ return func_800CCBE4(v0, v1, v2, z, x, arg5, 1.0f, ny);
+}
+
+s32 func_800CCF48(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x) {
+ return func_800CCBE4(v0, v1, v2, z, x, 300.0f, 1.0f, 0.6f);
+}
+
+s32 func_800CCF98(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 arg3, f32 normMagnitude, f32 arg5, f32 arg6, f32 z, f32 x,
+ f32* pointDist, f32 argA) {
+ if (fabsf(normMagnitude) < 0.008f) {
+ return 0;
+ }
+ if (func_800CCBE4(v0, v1, v2, z, x, 300.0f, argA, normMagnitude)) {
+ *pointDist = (f32)((((-arg3 * x) - (arg5 * z)) - arg6) / normMagnitude);
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD044(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 arg3, f32 ny, f32 arg5, f32 arg6, f32 z, f32 x, f32* arg9,
+ f32 argA) {
+ if (fabsf(ny) < 0.008f) {
+ return 0;
+ }
+ if (func_800CCBE4(v0, v1, v2, z, x, 0.0f, argA, ny)) {
+ *arg9 = (f32)((((-arg3 * x) - (arg5 * z)) - arg6) / ny);
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD0F0(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 ny, f32 z, f32 x) {
+ if (fabsf(ny) < 0.008f) {
+ return 0;
+ }
+ if (func_800CCBE4(v0, v1, v2, z, x, 300.0f, 1.0f, ny)) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Determines if the Triangle defined by verticies `v0`, `v1`, and `v2` with normal vector
+ * `nx`, `ny`, and `nz` is touching the cylinder defined by the center `cylZ`, `cylX` and top
+ * y componets `cylBottom` and `cylTop` are touching. The y component which they are touching is
+ * output to `yIntercept`, returns 1 if any part of the triangle is touching the cylinder.
+ */
+s32 Math3D_TriVtxCylTouching(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 cylZ,
+ f32 cylX, f32* yIntercept, f32 cylBottom, f32 cylTop) {
+ f32 bottomDist;
+ f32 topDist;
+ Vec3f cylPos;
+
+ if (fabsf(ny) < 0.008f) {
+ return 0;
+ }
+
+ cylPos.x = cylX;
+ cylPos.y = cylBottom;
+ cylPos.z = cylZ;
+
+ bottomDist = Math3D_Planef(nx, ny, nz, originDist, &cylPos);
+ cylPos.y = cylTop;
+ topDist = Math3D_Planef(nx, ny, nz, originDist, &cylPos);
+ if (((bottomDist > 0.0f) && (topDist > 0.0f)) || ((bottomDist < 0.0f) && (topDist < 0.0f))) {
+ return 0;
+ }
+
+ if (func_800CCBE4(v0, v1, v2, cylZ, cylX, 300.0f, 1.0f, ny)) {
+ *yIntercept = (((-nx * cylX) - (nz * cylZ)) - originDist) / ny;
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD2D8(Vec3f* v0, Vec3f* v1, Vec3f* v2, Plane* plane, f32 z, f32 x, f32 arg6) {
+ if (fabsf(plane->normal.y) < 0.008f) {
+ return 0;
+ }
+ if (func_800CCBE4(v0, v1, v2, z, x, 0.0f, arg6, plane->normal.y)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD34C(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7) {
+ f32 temp_f6;
+ f32 temp_f10;
+ f32 temp_f8;
+ f32 sp60;
+ f32 sq6;
+
+ if (func_800CB1F8(arg0->y, arg0->z, arg1->y, arg1->z, arg2->y, arg2->z, arg3, arg4, arg6) == 0) {
+ return 0;
+ }
+
+ sq6 = SQ(arg6);
+ if (((SQ(arg0->y - arg3) + SQ(arg0->z - arg4)) < sq6) || ((SQ(arg1->y - arg3) + SQ(arg1->z - arg4)) < sq6) ||
+ ((SQ(arg2->y - arg3) + SQ(arg2->z - arg4)) < sq6)) {
+ return 1;
+ }
+
+ temp_f6 = ((arg0->y - arg3) * (arg1->z - arg4)) - ((arg0->z - arg4) * (arg1->y - arg3));
+ temp_f10 = ((arg1->y - arg3) * (arg2->z - arg4)) - ((arg1->z - arg4) * (arg2->y - arg3));
+ temp_f8 = ((arg2->y - arg3) * (arg0->z - arg4)) - ((arg2->z - arg4) * (arg0->y - arg3));
+
+ if (((temp_f6 <= arg5) && (temp_f10 <= arg5) && (temp_f8 <= arg5)) ||
+ ((-arg5 <= temp_f6) && (-arg5 <= temp_f10) && (-arg5 <= temp_f8))) {
+ return 1;
+ }
+
+ if (0.5f < fabsf(arg7)) {
+
+ if (func_800CE4B8(arg3, arg4, arg0->y, arg0->z, arg1->y, arg1->z, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+
+ if (func_800CE4B8(arg3, arg4, arg1->y, arg1->z, arg2->y, arg2->z, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+
+ if (func_800CE4B8(arg3, arg4, arg2->y, arg2->z, arg0->y, arg0->z, &sp60)) {
+ if (sp60 < sq6) {
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+s32 func_800CD668(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6) {
+ return func_800CD34C(arg0, arg1, arg2, arg3, arg4, arg5, 1.0f, arg6);
+}
+
+s32 func_800CD6B0(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8,
+ f32* arg9) {
+ if (fabsf(arg3) < 0.008f) {
+ return 0;
+ }
+ arg3 = arg3;
+ if (func_800CD34C(arg0, arg1, arg2, arg7, arg8, 300.0f, 1.0f, arg3)) {
+ *arg9 = (f32)((((-arg4 * arg7) - (arg5 * arg8)) - arg6) / arg3);
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD760(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 y, f32 z) {
+ if (fabsf(nx) < 0.008f) {
+ return 0;
+ }
+ if (func_800CD34C(v0, v1, v2, y, z, 300.0f, 1.0f, nx)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD7D8(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8,
+ f32* arg9, f32 argA, f32 argB) {
+ static Vec3f D_8016A698;
+
+ f32 sp34;
+ f32 temp_ret;
+
+ if (fabsf(arg3) < 0.008f) {
+ return 0;
+ }
+
+ D_8016A698.x = argA;
+ D_8016A698.y = arg7;
+ D_8016A698.z = arg8;
+ sp34 = Math3D_Planef(arg3, arg4, arg5, arg6, &D_8016A698);
+ D_8016A698.x = argB;
+ temp_ret = Math3D_Planef(arg3, arg4, arg5, arg6, &D_8016A698);
+ if (((sp34 > 0.0f) && (temp_ret > 0.0f)) || ((sp34 < 0.0f) && (temp_ret < 0.0f))) {
+ return 0;
+ }
+ if (func_800CD34C(arg0, arg1, arg2, arg7, arg8, 300.0f, 1.0f, arg3)) {
+ *arg9 = (((-arg4 * arg7) - (arg5 * arg8)) - arg6) / arg3;
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD95C(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32* arg3, f32 arg4, f32 arg5, f32 arg6) {
+ if (fabsf(*arg3) < 0.008f) {
+ return 0;
+ }
+ if (func_800CD34C(arg0, arg1, arg2, arg4, arg5, 0.0f, arg6, *arg3)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CD9D0(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7) {
+ f32 temp_f4;
+ f32 temp_f8;
+ f32 temp_f10;
+ f32 sp78;
+ f32 sq6;
+
+ if (!func_800CB1F8(arg0->x, arg0->y, arg1->x, arg1->y, arg2->x, arg2->y, arg3, arg4, arg6)) {
+ return 0;
+ }
+ sq6 = SQ(arg6);
+ if (((SQ(arg3 - arg0->x) + SQ(arg4 - arg0->y)) < sq6) || ((SQ(arg3 - arg1->x) + SQ(arg4 - arg1->y)) < sq6) ||
+ ((SQ(arg3 - arg2->x) + SQ(arg4 - arg2->y)) < sq6)) {
+ return 1;
+ }
+
+ temp_f4 = ((arg0->x - arg3) * (arg1->y - arg4)) - ((arg0->y - arg4) * (arg1->x - arg3));
+ temp_f8 = ((arg1->x - arg3) * (arg2->y - arg4)) - ((arg1->y - arg4) * (arg2->x - arg3));
+ temp_f10 = ((arg2->x - arg3) * (arg0->y - arg4)) - ((arg2->y - arg4) * (arg0->x - arg3));
+
+ if (((arg5 >= temp_f4) && (arg5 >= temp_f8) && (arg5 >= temp_f10)) ||
+ ((-arg5 <= temp_f4) && (-arg5 <= temp_f8) && (-arg5 <= temp_f10))) {
+ return 1;
+ }
+
+ if (fabsf(arg7) > 0.5f) {
+
+ if (func_800CE4B8(arg3, arg4, arg0->x, arg0->y, arg1->x, arg1->y, &sp78) && (sp78 < sq6)) {
+ return 1;
+ }
+
+ if (func_800CE4B8(arg3, arg4, arg1->x, arg1->y, arg2->x, arg2->y, &sp78) && (sp78 < sq6)) {
+ return 1;
+ }
+
+ if (func_800CE4B8(arg3, arg4, arg2->x, arg2->y, arg0->x, arg0->y, &sp78) && (sp78 < sq6)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+s32 func_800CDD18(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6) {
+ return func_800CD9D0(arg0, arg1, arg2, arg3, arg4, arg5, 1.0f, arg6);
+}
+
+s32 func_800CDD60(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8,
+ f32* arg9) {
+ if (fabsf(arg5) < 0.008f) {
+ return 0;
+ }
+ if (func_800CD9D0(arg0, arg1, arg2, arg7, arg8, 300.0f, 1.0f, arg5)) {
+ *arg9 = (f32)((((-arg3 * arg7) - (arg4 * arg8)) - arg6) / arg5);
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CDE10(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nz, f32 x, f32 y) {
+ if (fabsf(nz) < 0.008f) {
+ return 0;
+ }
+ if (func_800CD9D0(v0, v1, v2, x, y, 300.0f, 1.0f, nz)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CDE88(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, f32 arg7, f32 arg8,
+ f32* arg9, f32 argA, f32 argB) {
+ static Vec3f D_8016A6A8;
+
+ f32 sp2C;
+ f32 temp_ret;
+
+ if (fabsf(arg5) < 0.008f) {
+ return 0;
+ }
+ D_8016A6A8.x = arg7;
+ D_8016A6A8.y = arg8;
+ D_8016A6A8.z = argA;
+ sp2C = Math3D_Planef(arg3, arg4, arg5, arg6, &D_8016A6A8);
+ D_8016A6A8.z = argB;
+ temp_ret = Math3D_Planef(arg3, arg4, arg5, arg6, &D_8016A6A8);
+ if (((sp2C > 0.0f) && (temp_ret > 0.0f)) || ((sp2C < 0.0f) && (temp_ret < 0.0f))) {
+ return 0;
+ }
+
+ if (func_800CD9D0(arg0, arg1, arg2, arg7, arg8, 300.0f, 1.0f, arg5)) {
+ *arg9 = (((-arg3 * arg7) - (arg4 * arg8)) - arg6) / arg5;
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CE010(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, f32 arg5, f32 arg6) {
+ if (fabsf(arg3->z) < 0.008f) {
+ return 0;
+ }
+ if (func_800CD9D0(arg0, arg1, arg2, arg4, arg5, 0.0f, arg6, arg3->z)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CE084(f32 pointADist, f32 pointBDist, Vec3f* pointA, Vec3f* pointB, Vec3f* intersect) {
+ f32 temp_f2;
+
+ temp_f2 = pointADist - pointBDist;
+ if (fabsf(temp_f2) < 0.008f) {
+ *intersect = *pointB;
+ return 0;
+ }
+
+ if (pointADist == 0.0f) {
+ *intersect = *pointA;
+ } else if (pointBDist == 0.0f) {
+ *intersect = *pointB;
+ } else {
+ func_800CAFA0(pointA, pointB, pointADist / temp_f2, intersect);
+ }
+ return 1;
+}
+
+s32 func_800CE15C(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* linePointA, Vec3f* linePointB, Vec3f* intersect,
+ s32 arg7) {
+ f32 pointADist;
+ f32 pointBDist;
+
+ pointADist = Math3D_Planef(nx, ny, nz, originDist, linePointA);
+ pointBDist = Math3D_Planef(nx, ny, nz, originDist, linePointB);
+
+ if ((pointADist * pointBDist) > 0.0f) {
+ *intersect = *linePointB;
+ return 0;
+ }
+
+ if (arg7 != 0 && (pointADist < 0.0f) && (pointBDist > 0.0f)) {
+ *intersect = *linePointB;
+ return 0;
+ }
+
+ return func_800CE084(pointADist, pointBDist, linePointA, linePointB, intersect);
+}
+
+/*
+ * Determines if the line formed by `linePiontA` and `linePointB` intersect with Triangle formed from
+ * vertices `v0`, `v1`, and `v2` with normal vector `nx`, `ny`, and `nz` with plane distance from origin
+ * `originDist` Outputs the intersection point at to `intersect`
+ * Returns 1 if the line intersects with the triangle, 0 otherwise
+ */
+s32 Math3D_TriLineIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* linePointA,
+ Vec3f* linePointB, Vec3f* intersect, s32 argA) {
+
+ if (!func_800CE15C(nx, ny, nz, originDist, linePointA, linePointB, intersect, argA)) {
+ return 0;
+ }
+
+ if (((nx == 0.0f) || (func_800CD760(v0, v1, v2, nx, intersect->y, intersect->z))) &&
+ ((ny == 0.0f) || (func_800CD0F0(v0, v1, v2, ny, intersect->z, intersect->x))) &&
+ ((nz == 0.0f) || (func_800CDE10(v0, v1, v2, nz, intersect->x, intersect->y)))) {
+ return 1;
+ }
+
+ *intersect = *linePointB;
+ return 0;
+}
+
+/*
+ * Creates a TriNorm output to `tri`, and calculates the normal vector and plane from vertices
+ * `va`, `vb`, and `vc`
+ */
+void Math3D_TriNorm(TriNorm* tri, Vec3f* va, Vec3f* vb, Vec3f* vc) {
+ tri->vtx[0] = *va;
+ tri->vtx[1] = *vb;
+ tri->vtx[2] = *vc;
+ func_800CC8B4(va, vb, vc, &tri->plane.normal.x, &tri->plane.normal.y, &tri->plane.normal.z, &tri->plane.originDist);
+}
+
+/*
+ * Determines if point `point` lies within `sphere`
+ */
+s32 Math3D_PointInSphere(Sphere16* sphere, Vec3f* point) {
+
+ if (Math3D_DistXYZ16toF(&sphere->center, point) < sphere->radius) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800CE4B8(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32* arg6) {
+ static Vec3f D_8016A6B8;
+
+ f32 temp_f0;
+ f32 temp_f2;
+ f32 temp_f16;
+ f32 temp_f18;
+ s32 ret = 0;
+
+ temp_f2 = arg4 - arg2;
+ temp_f18 = arg5 - arg3;
+ temp_f16 = (temp_f2 * temp_f2) + (temp_f18 * temp_f18);
+ if (fabsf(temp_f16) < 0.008f) {
+ *arg6 = 0.0f;
+ return 0;
+ }
+
+ temp_f0 = (((arg0 - arg2) * temp_f2) + (arg1 - arg3) * temp_f18) / temp_f16;
+ if (temp_f0 >= 0.0f) {
+ if (temp_f0 <= 1.0f) {
+ ret = 1;
+ }
+ }
+ D_8016A6B8.x = (temp_f2 * temp_f0) + arg2;
+ D_8016A6B8.y = (temp_f18 * temp_f0) + arg3;
+ *arg6 = (f32)(SQ(D_8016A6B8.x - arg0) + SQ(D_8016A6B8.y - arg1));
+ return ret;
+}
+
+s32 func_800CE600(Sphere16* arg0, Linef* arg1) {
+ static Vec3f D_8016A6C8;
+
+ Vec3f t2;
+ f32 temp_f0_2;
+ f32 temp_f2;
+
+ if ((Math3D_PointInSphere(arg0, &arg1->a)) || (Math3D_PointInSphere(arg0, &arg1->b))) {
+ return 1;
+ } else {
+ t2.x = arg1->b.x - arg1->a.x;
+ t2.y = arg1->b.y - arg1->a.y;
+ t2.z = arg1->b.z - arg1->a.z;
+
+ temp_f2 = SQ(t2.x) + SQ(t2.y) + SQ(t2.z);
+ if (fabsf(temp_f2) < 0.008f) {
+ return 0;
+ }
+ temp_f0_2 = ((((arg0->center.x - arg1->a.x) * t2.x) + ((arg0->center.y - arg1->a.y) * t2.y)) +
+ ((arg0->center.z - arg1->a.z) * t2.z)) /
+ temp_f2;
+ if ((temp_f0_2 < 0.0f) || (1.0f < temp_f0_2)) {
+ return 0;
+ }
+
+ D_8016A6C8.x = (t2.x * temp_f0_2) + arg1->a.x;
+ D_8016A6C8.y = (t2.y * temp_f0_2) + arg1->a.y;
+ D_8016A6C8.z = (t2.z * temp_f0_2) + arg1->a.z;
+
+ if (SQ(D_8016A6C8.x - arg0->center.x) + SQ(D_8016A6C8.y - arg0->center.y) + SQ(D_8016A6C8.z - arg0->center.z) <=
+ SQ((f32)arg0->radius)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void func_800CE800(Sphere16* sphere, TriNorm* tri, Vec3f* ret) {
+ static Vec3f centroid;
+ static Vec3f sphereCenter;
+
+ f32 dist;
+ f32 fw;
+
+ centroid.x = ((tri->vtx[0].x + tri->vtx[1].x) * 0.5f);
+ centroid.y = ((tri->vtx[0].y + tri->vtx[1].y) * 0.5f);
+ centroid.z = ((tri->vtx[0].z + tri->vtx[1].z) * 0.5f);
+ sphereCenter.x = sphere->center.x;
+ sphereCenter.y = sphere->center.y;
+ sphereCenter.z = sphere->center.z;
+ dist = Math3D_Vec3f_DistXYZ(&centroid, &sphereCenter);
+ if (fabsf(dist) < 0.008f) {
+ ret->x = sphereCenter.x;
+ ret->y = sphereCenter.y;
+ ret->z = sphereCenter.z;
+ return;
+ }
+ fw = sphere->radius / dist;
+ func_800CAFA0(&sphereCenter, &centroid, fw, ret);
+}
+
+s32 func_800CE934(Sphere16* arg0, TriNorm* arg1, Vec3f* arg2) {
+ static Linef D_8016A6F8;
+ static Vec3f D_8016A710;
+ static Vec3f D_8016A720;
+
+ f32 radius;
+ f32 nx;
+ f32 ny;
+ f32 nz;
+ f32 planeDist;
+
+ D_8016A710.x = arg0->center.x;
+ D_8016A710.y = arg0->center.y;
+ D_8016A710.z = arg0->center.z;
+ radius = arg0->radius;
+
+ if (func_800CB338(&arg1->vtx[0], &arg1->vtx[1], &arg1->vtx[2], &D_8016A710, radius) == 0) {
+ return 0;
+ }
+
+ planeDist = Math3D_UDistPlaneToPos(arg1->plane.normal.x, arg1->plane.normal.y, arg1->plane.normal.z,
+ arg1->plane.originDist, &D_8016A710);
+ if (radius < planeDist) {
+ return 0;
+ }
+
+ D_8016A6F8.a = arg1->vtx[0];
+ D_8016A6F8.b = arg1->vtx[1];
+
+ if (func_800CE600(arg0, &D_8016A6F8)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+ D_8016A6F8.a = arg1->vtx[1];
+ D_8016A6F8.b = arg1->vtx[2];
+ if (func_800CE600(arg0, &D_8016A6F8)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+ D_8016A6F8.a = arg1->vtx[2];
+ D_8016A6F8.b = arg1->vtx[0];
+ if (func_800CE600(arg0, &D_8016A6F8)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+
+ nx = arg1->plane.normal.x * planeDist;
+ ny = arg1->plane.normal.y * planeDist;
+ nz = arg1->plane.normal.z * planeDist;
+
+ if (Math3D_Planef(arg1->plane.normal.x, arg1->plane.normal.y, arg1->plane.normal.z, arg1->plane.originDist,
+ &D_8016A710) > 0.0f) {
+ D_8016A720.x = D_8016A710.x - nx;
+ D_8016A720.y = D_8016A710.y - ny;
+ D_8016A720.z = D_8016A710.z - nz;
+ } else {
+ D_8016A720.x = D_8016A710.x + nx;
+ D_8016A720.y = D_8016A710.y + ny;
+ D_8016A720.z = D_8016A710.z + nz;
+ }
+
+ if (0.5f < fabsf(arg1->plane.normal.y)) {
+ if (func_800CCF00(&arg1->vtx[0], &arg1->vtx[1], &arg1->vtx[2], D_8016A720.z, D_8016A720.x, 0.0f,
+ arg1->plane.normal.y)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+ } else if (0.5f < fabsf(arg1->plane.normal.x)) {
+ if (func_800CD668(&arg1->vtx[0], &arg1->vtx[1], &arg1->vtx[2], D_8016A720.y, D_8016A720.z, 0.0f,
+ arg1->plane.normal.x)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+ } else if (func_800CDD18(&arg1->vtx[0], &arg1->vtx[1], &arg1->vtx[2], D_8016A720.x, D_8016A720.y, 0.0f,
+ arg1->plane.normal.z)) {
+ func_800CE800(arg0, arg1, arg2);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Checks if point `point` is within cylinder `cyl`
+ * Returns 1 if the point is inside the cylinder, 0 otherwise.
+ */
+s32 Math3D_PointInCyl(Cylinder16* cyl, Vec3f* point) {
+ f32 bottom;
+ f32 top;
+ f32 x;
+ f32 z;
+
+ x = cyl->pos.x - point->x;
+ z = cyl->pos.z - point->z;
+ bottom = (f32)cyl->pos.y + cyl->yShift;
+ top = cyl->height + bottom;
+
+ if ((SQ(x) + SQ(z)) < SQ(cyl->radius) && (bottom < point->y) && (point->y < top)) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_800CEE0C.s")
+
+/*
+ * Determines if `cyl` and `tri` are touching. The point of intersection
+ * is placed in `intersect` Returns 1 if they are touching, 0 otherwise.
+ */
+s32 Math3D_CylTriTouchingIntersect(Cylinder16* cyl, TriNorm* tri, Vec3f* intersect) {
+ static Sphere16 topSphere;
+ static Sphere16 bottomSphere;
+ static Vec3f D_8016A740;
+ static Vec3f D_8016A750;
+
+ f32 sp8C;
+ f32 cylTop;
+ f32 cylBottom;
+ f32 phi_f2;
+ f32 t;
+ f32 temp_ret;
+ Vec3f sp6C;
+ Vec3f sp60;
+ Vec3f sp54;
+ f32 temp_f14_2;
+ f32 temp_f2;
+
+ cylBottom = (f32)cyl->pos.y + cyl->yShift;
+ cylTop = cyl->height + cylBottom;
+
+ // If all of the verticies are below or all of the verticies are above the cylinder.
+
+ if (((tri->vtx[0].y < cylBottom) && (tri->vtx[1].y < cylBottom) && (tri->vtx[2].y < cylBottom)) ||
+ ((cylTop < tri->vtx[0].y) && (cylTop < tri->vtx[1].y) && (cylTop < tri->vtx[2].y))) {
+ return 0;
+ }
+ phi_f2 = 1.e38f;
+ if (func_800CEE0C(cyl, &tri->vtx[0], &tri->vtx[1], &D_8016A740, &D_8016A750)) {
+ phi_f2 = func_800CB650(&D_8016A740, &tri->vtx[0]);
+ *intersect = D_8016A740;
+ }
+
+ if (func_800CEE0C(cyl, &tri->vtx[2], &tri->vtx[1], &D_8016A740, &D_8016A750)) {
+ temp_ret = func_800CB650(&D_8016A740, &tri->vtx[2]);
+ if (temp_ret < phi_f2) {
+ *intersect = D_8016A740;
+ phi_f2 = temp_ret;
+ }
+ }
+
+ if (func_800CEE0C(cyl, &tri->vtx[0], &tri->vtx[2], &D_8016A740, &D_8016A750)) {
+ temp_ret = func_800CB650(&D_8016A740, &tri->vtx[0]);
+ if (temp_ret < phi_f2) {
+ *intersect = D_8016A740;
+ phi_f2 = temp_ret;
+ }
+ }
+ // what is 1.e38f ?
+ if (phi_f2 != 1.e38f) {
+ return 1;
+ }
+
+ if (Math3D_TriVtxCylTouching(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], tri->plane.normal.x, tri->plane.normal.y,
+ tri->plane.normal.z, tri->plane.originDist, cyl->pos.z, cyl->pos.x, &sp8C, cylBottom,
+ cylTop)) {
+
+ sp6C.x = cyl->pos.x;
+ sp6C.y = sp8C;
+ sp6C.z = cyl->pos.z;
+
+ sp60.x = (tri->vtx[0].x + tri->vtx[1].x) * 0.5f;
+ sp60.y = (tri->vtx[0].y + tri->vtx[1].y) * 0.5f;
+ sp60.z = (tri->vtx[0].z + tri->vtx[1].z) * 0.5f;
+
+ Math_Vec3f_Diff(&sp60, &sp6C, &sp54);
+ temp_f14_2 = sqrtf((sp54.x * sp54.x) + (sp54.z * sp54.z));
+
+ if (fabsf(temp_f14_2) < 0.008f) {
+ Math_Vec3f_Copy(intersect, &sp60);
+ return 1;
+ }
+ t = cyl->radius / temp_f14_2;
+ func_800CAF5C(&sp6C, &sp54, t, intersect);
+ return 1;
+ }
+
+ topSphere.center.x = bottomSphere.center.x = cyl->pos.x;
+ topSphere.center.z = bottomSphere.center.z = cyl->pos.z;
+ topSphere.center.y = cylTop;
+ bottomSphere.center.y = cylBottom;
+ topSphere.radius = bottomSphere.radius = cyl->radius;
+
+ if ((func_800CE934(&topSphere, tri, intersect)) || (func_800CE934(&bottomSphere, tri, intersect))) {
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Returns 1 if `cyl` and `tri` and touching
+ */
+s32 Math3D_CylTriTouching(Cylinder16* cyl, TriNorm* tri) {
+ Vec3f intersect;
+
+ return Math3D_CylTriTouchingIntersect(cyl, tri, &intersect);
+}
+
+/*
+ * Deteremines if two spheres are touching. Returns 1 if their closest surface point
+ * is within 0.008f units. 0 otherwise.
+ */
+s32 Math3D_SpheresTouching(Sphere16* sphereA, Sphere16* sphereB) {
+ f32 surfaceDist;
+
+ return Math3D_SpheresTouchingSurface(sphereA, sphereB, &surfaceDist);
+}
+
+/*
+ * Determines if two spheres are within 0.008 units of each other. The distance from
+ * the closest point on the surface is placed in `surfaceDist` Returns 1 if the surfaces
+ * are not touching. Returns 0 otherwise.
+ */
+s32 Math3D_SpheresTouchingSurface(Sphere16* sphereA, Sphere16* sphereB, f32* surfaceDist) {
+ f32 centerDist;
+
+ return Math3D_SpheresTouchingSurfaceCenter(sphereA, sphereB, surfaceDist, &centerDist);
+}
+
+/*
+ * Determines if two spheres are within 0.008f units of each other. The distance from
+ * the centers is placed in `centerDist` and the closest distance to their surfaces is placed
+ * in `surfaceDist` Returns 1 if the surfaces are not touching. Returns 0 otherwise.
+ */
+s32 Math3D_SpheresTouchingSurfaceCenter(Sphere16* sphereA, Sphere16* sphereB, f32* surfaceDist, f32* centerDist) {
+ Vec3f diff;
+
+ diff.x = (f32)sphereA->center.x - (f32)sphereB->center.x;
+ diff.y = (f32)sphereA->center.y - (f32)sphereB->center.y;
+ diff.z = (f32)sphereA->center.z - (f32)sphereB->center.z;
+
+ *centerDist = sqrt(SQ(diff.x) + SQ(diff.y) + SQ(diff.z));
+
+ *surfaceDist = (((f32)sphereA->radius + (f32)sphereB->radius) - *centerDist);
+ if (0.008f < *surfaceDist) {
+ return 1;
+ }
+
+ *surfaceDist = 0.0f;
+ return 0;
+}
+
+s32 func_800CFD84(Sphere16* sph, Cylinder16* cyl, f32* surfaceDist) {
+ f32 centerDist;
+
+ return func_800CFDA4(sph, cyl, surfaceDist, &centerDist);
+}
+
+s32 func_800CFDA4(Sphere16* sph, Cylinder16* cyl, f32* surfaceDist, f32* centerDist) {
+ static Cylinderf cylf;
+ static Spheref sphf;
+
+ f32 x;
+ f32 z;
+ f32 rad;
+ f32 cylBottom;
+ f32 cylTop;
+ f32 sphBottom;
+ f32 sphTop;
+
+ if (sph->radius <= 0 || cyl->radius <= 0) {
+ return 0;
+ }
+ sphf.center.y = sph->center.y;
+ sphf.radius = sph->radius;
+ cylf.pos.y = cyl->pos.y;
+ cylf.yShift = cyl->yShift;
+ cylf.height = cyl->height;
+ x = (f32)sph->center.x - cyl->pos.x;
+ z = (f32)sph->center.z - cyl->pos.z;
+ rad = (f32)sph->radius + cyl->radius;
+ *centerDist = sqrtf(SQ(x) + SQ(z));
+ if (rad < *centerDist) {
+ return 0;
+ }
+
+ cylBottom = (cylf.pos.y + cylf.yShift);
+ cylTop = cylBottom + cylf.height;
+ sphBottom = sphf.center.y - sphf.radius;
+ sphTop = sphf.center.y + sphf.radius;
+
+ if ((sphTop >= cylBottom) && (sphBottom <= cylTop)) {
+ *surfaceDist = rad - *centerDist;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * returns 1 if cylinder `ca` is outside cylinder `cb`.
+ * Sets `deadSpace` to the mininum space between the cylinders not occupied by the other.
+ */
+s32 Math3D_CylinderOutCylinder(Cylinder16* ca, Cylinder16* cb, f32* deadSpace) {
+ f32 xzDist;
+
+ Math3D_CylinderOutCylinderDist(ca, cb, deadSpace, &xzDist);
+}
+
+/*
+ * returns 1 if cylinder `ca` is outside cylinder `cb`.
+ * Sets `xzDist` to the xz distance between the centers of the cylinders.
+ * Sets `deadSpace` to the mininum space between the cylinders not occupied by the other.
+ */
+s32 Math3D_CylinderOutCylinderDist(Cylinder16* ca, Cylinder16* cb, f32* deadSpace, f32* xzDist) {
+ static Cylinderf caf;
+ static Cylinderf cbf;
+
+ Math_Vec3s_ToVec3f(&caf.pos, &ca->pos);
+ caf.radius = ca->radius;
+ caf.yShift = ca->yShift;
+ caf.height = ca->height;
+
+ Math_Vec3s_ToVec3f(&cbf.pos, &cb->pos);
+ cbf.radius = cb->radius;
+ cbf.yShift = cb->yShift;
+ cbf.height = cb->height;
+
+ *xzDist = sqrtf(SQ(caf.pos.x - cbf.pos.x) + SQ(caf.pos.z - cbf.pos.z));
+
+ // The combined radix are within the xz distance
+ if ((caf.radius + cbf.radius) < *xzDist) {
+ return 0;
+ }
+
+ // top of ca < bottom of cb or top of cb < bottom of ca
+ if (((caf.pos.y + caf.yShift) + caf.height) < (cbf.pos.y + cbf.yShift) ||
+ (((cbf.pos.y + cbf.yShift) + cbf.height) < (caf.pos.y + caf.yShift))) {
+ return 0;
+ }
+
+ *deadSpace = caf.radius + cbf.radius - *xzDist;
+ return 1;
+}
+
+/*
+ * Determines if triangle `ta` intersects with triangle `tb` the point of
+ * intersection is output to `intersect.
+ * Returns 1 is the triangles intersect, 0 otherwise
+ */
+
+s32 Math3D_TrisIntersect(TriNorm* ta, TriNorm* tb, Vec3f* intersect) {
+ f32 dist0;
+ f32 dist1;
+ f32 dist2;
+
+ dist0 = Math3D_Plane(&ta->plane, &tb->vtx[0]);
+ dist1 = Math3D_Plane(&ta->plane, &tb->vtx[1]);
+ dist2 = Math3D_Plane(&ta->plane, &tb->vtx[2]);
+
+ if (((dist0 > 0.0f) && (dist1 > 0.0f) && (dist2 > 0.0f)) ||
+ (((dist0 < 0.0f) && (dist1 < 0.0f)) && (dist2 < 0.0f))) {
+ return 0;
+ }
+
+ dist0 = Math3D_Plane(&tb->plane, &ta->vtx[0]);
+ dist1 = Math3D_Plane(&tb->plane, &ta->vtx[1]);
+ dist2 = Math3D_Plane(&tb->plane, &ta->vtx[2]);
+
+ if ((((dist0 > 0.0f) && (dist1 > 0.0f)) && (dist2 > 0.0f)) ||
+ ((dist0 < 0.0f) && (dist1 < 0.0f) && (dist2 < 0.0f))) {
+ return 0;
+ }
+
+ if (Math3D_TriLineIntersect(&tb->vtx[0], &tb->vtx[1], &tb->vtx[2], tb->plane.normal.x, tb->plane.normal.y,
+ tb->plane.normal.z, tb->plane.originDist, &ta->vtx[0], &ta->vtx[1], intersect, 0)) {
+ return 1;
+ }
+ if (Math3D_TriLineIntersect(&tb->vtx[0], &tb->vtx[1], &tb->vtx[2], tb->plane.normal.x, tb->plane.normal.y,
+ tb->plane.normal.z, tb->plane.originDist, &ta->vtx[1], &ta->vtx[2], intersect, 0)) {
+ return 1;
+ }
+ if (Math3D_TriLineIntersect(&tb->vtx[0], &tb->vtx[1], &tb->vtx[2], tb->plane.normal.x, tb->plane.normal.y,
+ tb->plane.normal.z, tb->plane.originDist, &ta->vtx[2], &ta->vtx[0], intersect, 0)) {
+ return 1;
+ }
+ if (Math3D_TriLineIntersect(&ta->vtx[0], &ta->vtx[1], &ta->vtx[2], ta->plane.normal.x, ta->plane.normal.y,
+ ta->plane.normal.z, ta->plane.originDist, &tb->vtx[0], &tb->vtx[1], intersect,
+ 0) == 1) {
+ return 1;
+ }
+ if (Math3D_TriLineIntersect(&ta->vtx[0], &ta->vtx[1], &ta->vtx[2], ta->plane.normal.x, ta->plane.normal.y,
+ ta->plane.normal.z, ta->plane.originDist, &tb->vtx[1], &tb->vtx[2], intersect,
+ 0) == 1) {
+ return 1;
+ }
+ if (Math3D_TriLineIntersect(&ta->vtx[0], &ta->vtx[1], &ta->vtx[2], ta->plane.normal.x, ta->plane.normal.y,
+ ta->plane.normal.z, ta->plane.originDist, &tb->vtx[2], &tb->vtx[0], intersect,
+ 0) == 1) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800D0480(Sphere16* arg0, f32 arg1, f32 arg2) {
+ f32 temp_f0;
+ f32 temp_f2;
+
+ temp_f0 = arg0->center.x - arg1;
+ temp_f2 = arg0->center.z - arg2;
+ if ((SQ(temp_f0) + SQ(temp_f2)) <= SQ(arg0->radius)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800D04F0(Sphere16* arg0, f32 arg1, f32 arg2) {
+ f32 temp_f0;
+ f32 temp_f2;
+
+ temp_f0 = arg0->center.x - arg1;
+ temp_f2 = arg0->center.y - arg2;
+ if ((SQ(temp_f0) + SQ(temp_f2)) <= SQ(arg0->radius)) {
+ return 1;
+ }
+ return 0;
+}
+
+s32 func_800D0560(Sphere16* arg0, f32 arg1, f32 arg2) {
+ f32 temp_f0;
+ f32 temp_f2;
+
+ temp_f0 = arg0->center.y - arg1;
+ temp_f2 = arg0->center.z - arg2;
+ if ((SQ(temp_f0) + SQ(temp_f2)) <= SQ(arg0->radius)) {
+ return 1;
+ }
+ return 0;
+}
+
+void func_800D05D0(s32 arg0, s32 arg1) {
+}
+
+void func_800D05DC(s32 arg0, s32 arg1) {
+}
diff --git a/src/code/sys_math_atan.c b/src/code/sys_math_atan.c
new file mode 100644
index 000000000..ab62977d2
--- /dev/null
+++ b/src/code/sys_math_atan.c
@@ -0,0 +1,134 @@
+#include <global.h>
+#include <math.h>
+
+u16 sATan2Tbl[] = {
+ 0x0000, 0x000A, 0x0014, 0x001F, 0x0029, 0x0033, 0x003D, 0x0047, 0x0051, 0x005C, 0x0066, 0x0070, 0x007A, 0x0084,
+ 0x008F, 0x0099, 0x00A3, 0x00AD, 0x00B7, 0x00C2, 0x00CC, 0x00D6, 0x00E0, 0x00EA, 0x00F4, 0x00FF, 0x0109, 0x0113,
+ 0x011D, 0x0127, 0x0131, 0x013C, 0x0146, 0x0150, 0x015A, 0x0164, 0x016F, 0x0179, 0x0183, 0x018D, 0x0197, 0x01A1,
+ 0x01AC, 0x01B6, 0x01C0, 0x01CA, 0x01D4, 0x01DE, 0x01E9, 0x01F3, 0x01FD, 0x0207, 0x0211, 0x021B, 0x0226, 0x0230,
+ 0x023A, 0x0244, 0x024E, 0x0258, 0x0262, 0x026D, 0x0277, 0x0281, 0x028B, 0x0295, 0x029F, 0x02A9, 0x02B4, 0x02BE,
+ 0x02C8, 0x02D2, 0x02DC, 0x02E6, 0x02F0, 0x02FB, 0x0305, 0x030F, 0x0319, 0x0323, 0x032D, 0x0337, 0x0341, 0x034C,
+ 0x0356, 0x0360, 0x036A, 0x0374, 0x037E, 0x0388, 0x0392, 0x039C, 0x03A7, 0x03B1, 0x03BB, 0x03C5, 0x03CF, 0x03D9,
+ 0x03E3, 0x03ED, 0x03F7, 0x0401, 0x040C, 0x0416, 0x0420, 0x042A, 0x0434, 0x043E, 0x0448, 0x0452, 0x045C, 0x0466,
+ 0x0470, 0x047A, 0x0484, 0x048E, 0x0499, 0x04A3, 0x04AD, 0x04B7, 0x04C1, 0x04CB, 0x04D5, 0x04DF, 0x04E9, 0x04F3,
+ 0x04FD, 0x0507, 0x0511, 0x051B, 0x0525, 0x052F, 0x0539, 0x0543, 0x054D, 0x0557, 0x0561, 0x056B, 0x0575, 0x057F,
+ 0x0589, 0x0593, 0x059D, 0x05A7, 0x05B1, 0x05BB, 0x05C5, 0x05CF, 0x05D9, 0x05E3, 0x05ED, 0x05F7, 0x0601, 0x060B,
+ 0x0615, 0x061F, 0x0629, 0x0633, 0x063D, 0x0647, 0x0651, 0x065B, 0x0665, 0x066E, 0x0678, 0x0682, 0x068C, 0x0696,
+ 0x06A0, 0x06AA, 0x06B4, 0x06BE, 0x06C8, 0x06D2, 0x06DC, 0x06E5, 0x06EF, 0x06F9, 0x0703, 0x070D, 0x0717, 0x0721,
+ 0x072B, 0x0735, 0x073E, 0x0748, 0x0752, 0x075C, 0x0766, 0x0770, 0x077A, 0x0783, 0x078D, 0x0797, 0x07A1, 0x07AB,
+ 0x07B5, 0x07BE, 0x07C8, 0x07D2, 0x07DC, 0x07E6, 0x07EF, 0x07F9, 0x0803, 0x080D, 0x0817, 0x0820, 0x082A, 0x0834,
+ 0x083E, 0x0848, 0x0851, 0x085B, 0x0865, 0x086F, 0x0878, 0x0882, 0x088C, 0x0896, 0x089F, 0x08A9, 0x08B3, 0x08BD,
+ 0x08C6, 0x08D0, 0x08DA, 0x08E3, 0x08ED, 0x08F7, 0x0901, 0x090A, 0x0914, 0x091E, 0x0927, 0x0931, 0x093B, 0x0944,
+ 0x094E, 0x0958, 0x0961, 0x096B, 0x0975, 0x097E, 0x0988, 0x0992, 0x099B, 0x09A5, 0x09AE, 0x09B8, 0x09C2, 0x09CB,
+ 0x09D5, 0x09DE, 0x09E8, 0x09F2, 0x09FB, 0x0A05, 0x0A0E, 0x0A18, 0x0A22, 0x0A2B, 0x0A35, 0x0A3E, 0x0A48, 0x0A51,
+ 0x0A5B, 0x0A64, 0x0A6E, 0x0A77, 0x0A81, 0x0A8B, 0x0A94, 0x0A9E, 0x0AA7, 0x0AB1, 0x0ABA, 0x0AC4, 0x0ACD, 0x0AD7,
+ 0x0AE0, 0x0AE9, 0x0AF3, 0x0AFC, 0x0B06, 0x0B0F, 0x0B19, 0x0B22, 0x0B2C, 0x0B35, 0x0B3F, 0x0B48, 0x0B51, 0x0B5B,
+ 0x0B64, 0x0B6E, 0x0B77, 0x0B80, 0x0B8A, 0x0B93, 0x0B9D, 0x0BA6, 0x0BAF, 0x0BB9, 0x0BC2, 0x0BCB, 0x0BD5, 0x0BDE,
+ 0x0BE7, 0x0BF1, 0x0BFA, 0x0C03, 0x0C0D, 0x0C16, 0x0C1F, 0x0C29, 0x0C32, 0x0C3B, 0x0C45, 0x0C4E, 0x0C57, 0x0C60,
+ 0x0C6A, 0x0C73, 0x0C7C, 0x0C86, 0x0C8F, 0x0C98, 0x0CA1, 0x0CAB, 0x0CB4, 0x0CBD, 0x0CC6, 0x0CCF, 0x0CD9, 0x0CE2,
+ 0x0CEB, 0x0CF4, 0x0CFD, 0x0D07, 0x0D10, 0x0D19, 0x0D22, 0x0D2B, 0x0D34, 0x0D3E, 0x0D47, 0x0D50, 0x0D59, 0x0D62,
+ 0x0D6B, 0x0D74, 0x0D7D, 0x0D87, 0x0D90, 0x0D99, 0x0DA2, 0x0DAB, 0x0DB4, 0x0DBD, 0x0DC6, 0x0DCF, 0x0DD8, 0x0DE1,
+ 0x0DEA, 0x0DF3, 0x0DFC, 0x0E05, 0x0E0F, 0x0E18, 0x0E21, 0x0E2A, 0x0E33, 0x0E3C, 0x0E45, 0x0E4E, 0x0E56, 0x0E5F,
+ 0x0E68, 0x0E71, 0x0E7A, 0x0E83, 0x0E8C, 0x0E95, 0x0E9E, 0x0EA7, 0x0EB0, 0x0EB9, 0x0EC2, 0x0ECB, 0x0ED4, 0x0EDC,
+ 0x0EE5, 0x0EEE, 0x0EF7, 0x0F00, 0x0F09, 0x0F12, 0x0F1B, 0x0F23, 0x0F2C, 0x0F35, 0x0F3E, 0x0F47, 0x0F50, 0x0F58,
+ 0x0F61, 0x0F6A, 0x0F73, 0x0F7C, 0x0F84, 0x0F8D, 0x0F96, 0x0F9F, 0x0FA7, 0x0FB0, 0x0FB9, 0x0FC2, 0x0FCA, 0x0FD3,
+ 0x0FDC, 0x0FE5, 0x0FED, 0x0FF6, 0x0FFF, 0x1007, 0x1010, 0x1019, 0x1021, 0x102A, 0x1033, 0x103B, 0x1044, 0x104D,
+ 0x1055, 0x105E, 0x1067, 0x106F, 0x1078, 0x1080, 0x1089, 0x1092, 0x109A, 0x10A3, 0x10AB, 0x10B4, 0x10BC, 0x10C5,
+ 0x10CE, 0x10D6, 0x10DF, 0x10E7, 0x10F0, 0x10F8, 0x1101, 0x1109, 0x1112, 0x111A, 0x1123, 0x112B, 0x1134, 0x113C,
+ 0x1145, 0x114D, 0x1156, 0x115E, 0x1166, 0x116F, 0x1177, 0x1180, 0x1188, 0x1191, 0x1199, 0x11A1, 0x11AA, 0x11B2,
+ 0x11BB, 0x11C3, 0x11CB, 0x11D4, 0x11DC, 0x11E4, 0x11ED, 0x11F5, 0x11FD, 0x1206, 0x120E, 0x1216, 0x121F, 0x1227,
+ 0x122F, 0x1237, 0x1240, 0x1248, 0x1250, 0x1259, 0x1261, 0x1269, 0x1271, 0x127A, 0x1282, 0x128A, 0x1292, 0x129A,
+ 0x12A3, 0x12AB, 0x12B3, 0x12BB, 0x12C3, 0x12CC, 0x12D4, 0x12DC, 0x12E4, 0x12EC, 0x12F4, 0x12FC, 0x1305, 0x130D,
+ 0x1315, 0x131D, 0x1325, 0x132D, 0x1335, 0x133D, 0x1345, 0x134D, 0x1355, 0x135E, 0x1366, 0x136E, 0x1376, 0x137E,
+ 0x1386, 0x138E, 0x1396, 0x139E, 0x13A6, 0x13AE, 0x13B6, 0x13BE, 0x13C6, 0x13CE, 0x13D6, 0x13DE, 0x13E6, 0x13ED,
+ 0x13F5, 0x13FD, 0x1405, 0x140D, 0x1415, 0x141D, 0x1425, 0x142D, 0x1435, 0x143D, 0x1444, 0x144C, 0x1454, 0x145C,
+ 0x1464, 0x146C, 0x1473, 0x147B, 0x1483, 0x148B, 0x1493, 0x149B, 0x14A2, 0x14AA, 0x14B2, 0x14BA, 0x14C1, 0x14C9,
+ 0x14D1, 0x14D9, 0x14E0, 0x14E8, 0x14F0, 0x14F8, 0x14FF, 0x1507, 0x150F, 0x1516, 0x151E, 0x1526, 0x152D, 0x1535,
+ 0x153D, 0x1544, 0x154C, 0x1554, 0x155B, 0x1563, 0x156B, 0x1572, 0x157A, 0x1581, 0x1589, 0x1591, 0x1598, 0x15A0,
+ 0x15A7, 0x15AF, 0x15B7, 0x15BE, 0x15C6, 0x15CD, 0x15D5, 0x15DC, 0x15E4, 0x15EB, 0x15F3, 0x15FA, 0x1602, 0x1609,
+ 0x1611, 0x1618, 0x1620, 0x1627, 0x162F, 0x1636, 0x163E, 0x1645, 0x164C, 0x1654, 0x165B, 0x1663, 0x166A, 0x1671,
+ 0x1679, 0x1680, 0x1688, 0x168F, 0x1696, 0x169E, 0x16A5, 0x16AC, 0x16B4, 0x16BB, 0x16C2, 0x16CA, 0x16D1, 0x16D8,
+ 0x16E0, 0x16E7, 0x16EE, 0x16F6, 0x16FD, 0x1704, 0x170B, 0x1713, 0x171A, 0x1721, 0x1728, 0x1730, 0x1737, 0x173E,
+ 0x1745, 0x174C, 0x1754, 0x175B, 0x1762, 0x1769, 0x1770, 0x1778, 0x177F, 0x1786, 0x178D, 0x1794, 0x179B, 0x17A2,
+ 0x17AA, 0x17B1, 0x17B8, 0x17BF, 0x17C6, 0x17CD, 0x17D4, 0x17DB, 0x17E2, 0x17E9, 0x17F0, 0x17F7, 0x17FE, 0x1806,
+ 0x180D, 0x1814, 0x181B, 0x1822, 0x1829, 0x1830, 0x1837, 0x183E, 0x1845, 0x184C, 0x1853, 0x185A, 0x1860, 0x1867,
+ 0x186E, 0x1875, 0x187C, 0x1883, 0x188A, 0x1891, 0x1898, 0x189F, 0x18A6, 0x18AD, 0x18B3, 0x18BA, 0x18C1, 0x18C8,
+ 0x18CF, 0x18D6, 0x18DD, 0x18E3, 0x18EA, 0x18F1, 0x18F8, 0x18FF, 0x1906, 0x190C, 0x1913, 0x191A, 0x1921, 0x1928,
+ 0x192E, 0x1935, 0x193C, 0x1943, 0x1949, 0x1950, 0x1957, 0x195D, 0x1964, 0x196B, 0x1972, 0x1978, 0x197F, 0x1986,
+ 0x198C, 0x1993, 0x199A, 0x19A0, 0x19A7, 0x19AE, 0x19B4, 0x19BB, 0x19C2, 0x19C8, 0x19CF, 0x19D5, 0x19DC, 0x19E3,
+ 0x19E9, 0x19F0, 0x19F6, 0x19FD, 0x1A04, 0x1A0A, 0x1A11, 0x1A17, 0x1A1E, 0x1A24, 0x1A2B, 0x1A31, 0x1A38, 0x1A3E,
+ 0x1A45, 0x1A4B, 0x1A52, 0x1A58, 0x1A5F, 0x1A65, 0x1A6C, 0x1A72, 0x1A79, 0x1A7F, 0x1A86, 0x1A8C, 0x1A93, 0x1A99,
+ 0x1A9F, 0x1AA6, 0x1AAC, 0x1AB3, 0x1AB9, 0x1AC0, 0x1AC6, 0x1ACC, 0x1AD3, 0x1AD9, 0x1ADF, 0x1AE6, 0x1AEC, 0x1AF2,
+ 0x1AF9, 0x1AFF, 0x1B05, 0x1B0C, 0x1B12, 0x1B18, 0x1B1F, 0x1B25, 0x1B2B, 0x1B32, 0x1B38, 0x1B3E, 0x1B44, 0x1B4B,
+ 0x1B51, 0x1B57, 0x1B5D, 0x1B64, 0x1B6A, 0x1B70, 0x1B76, 0x1B7D, 0x1B83, 0x1B89, 0x1B8F, 0x1B95, 0x1B9C, 0x1BA2,
+ 0x1BA8, 0x1BAE, 0x1BB4, 0x1BBA, 0x1BC1, 0x1BC7, 0x1BCD, 0x1BD3, 0x1BD9, 0x1BDF, 0x1BE5, 0x1BEB, 0x1BF2, 0x1BF8,
+ 0x1BFE, 0x1C04, 0x1C0A, 0x1C10, 0x1C16, 0x1C1C, 0x1C22, 0x1C28, 0x1C2E, 0x1C34, 0x1C3A, 0x1C40, 0x1C46, 0x1C4C,
+ 0x1C52, 0x1C58, 0x1C5E, 0x1C64, 0x1C6A, 0x1C70, 0x1C76, 0x1C7C, 0x1C82, 0x1C88, 0x1C8E, 0x1C94, 0x1C9A, 0x1CA0,
+ 0x1CA6, 0x1CAC, 0x1CB2, 0x1CB8, 0x1CBE, 0x1CC3, 0x1CC9, 0x1CCF, 0x1CD5, 0x1CDB, 0x1CE1, 0x1CE7, 0x1CED, 0x1CF3,
+ 0x1CF8, 0x1CFE, 0x1D04, 0x1D0A, 0x1D10, 0x1D16, 0x1D1B, 0x1D21, 0x1D27, 0x1D2D, 0x1D33, 0x1D38, 0x1D3E, 0x1D44,
+ 0x1D4A, 0x1D4F, 0x1D55, 0x1D5B, 0x1D61, 0x1D66, 0x1D6C, 0x1D72, 0x1D78, 0x1D7D, 0x1D83, 0x1D89, 0x1D8E, 0x1D94,
+ 0x1D9A, 0x1DA0, 0x1DA5, 0x1DAB, 0x1DB1, 0x1DB6, 0x1DBC, 0x1DC2, 0x1DC7, 0x1DCD, 0x1DD3, 0x1DD8, 0x1DDE, 0x1DE3,
+ 0x1DE9, 0x1DEF, 0x1DF4, 0x1DFA, 0x1DFF, 0x1E05, 0x1E0B, 0x1E10, 0x1E16, 0x1E1B, 0x1E21, 0x1E26, 0x1E2C, 0x1E32,
+ 0x1E37, 0x1E3D, 0x1E42, 0x1E48, 0x1E4D, 0x1E53, 0x1E58, 0x1E5E, 0x1E63, 0x1E69, 0x1E6E, 0x1E74, 0x1E79, 0x1E7F,
+ 0x1E84, 0x1E8A, 0x1E8F, 0x1E94, 0x1E9A, 0x1E9F, 0x1EA5, 0x1EAA, 0x1EB0, 0x1EB5, 0x1EBA, 0x1EC0, 0x1EC5, 0x1ECB,
+ 0x1ED0, 0x1ED5, 0x1EDB, 0x1EE0, 0x1EE6, 0x1EEB, 0x1EF0, 0x1EF6, 0x1EFB, 0x1F00, 0x1F06, 0x1F0B, 0x1F10, 0x1F16,
+ 0x1F1B, 0x1F20, 0x1F26, 0x1F2B, 0x1F30, 0x1F36, 0x1F3B, 0x1F40, 0x1F45, 0x1F4B, 0x1F50, 0x1F55, 0x1F5A, 0x1F60,
+ 0x1F65, 0x1F6A, 0x1F6F, 0x1F75, 0x1F7A, 0x1F7F, 0x1F84, 0x1F8A, 0x1F8F, 0x1F94, 0x1F99, 0x1F9E, 0x1FA4, 0x1FA9,
+ 0x1FAE, 0x1FB3, 0x1FB8, 0x1FBD, 0x1FC3, 0x1FC8, 0x1FCD, 0x1FD2, 0x1FD7, 0x1FDC, 0x1FE1, 0x1FE6, 0x1FEC, 0x1FF1,
+ 0x1FF6, 0x1FFB, 0x2000,
+};
+
+u16 GetAtan2Tbl(f32 x, f32 y) {
+ s32 tblIdx;
+ u16 ret;
+
+ tblIdx = ((x / y) * 1024.0f) + 0.5f;
+
+ if (y == 0.0f) {
+ ret = sATan2Tbl[0];
+ } else if (tblIdx >= ARRAY_COUNT(sATan2Tbl)) {
+ ret = sATan2Tbl[0];
+ } else {
+ ret = sATan2Tbl[tblIdx];
+ }
+ return ret;
+}
+
+s16 atan2s(f32 x, f32 y) {
+ s32 ret;
+
+ if (y >= 0.0f) {
+ if (x >= 0.0f) {
+ if (y <= x) {
+ ret = GetAtan2Tbl(y, x);
+ } else {
+ ret = 0x4000 - GetAtan2Tbl(x, y);
+ }
+ } else {
+ if (-x < y) {
+ ret = GetAtan2Tbl(-x, y) + 0x4000;
+ } else {
+ ret = 0x8000 - GetAtan2Tbl(y, -x);
+ }
+ }
+ } else {
+ if (x < 0.0f) {
+ if (-y <= -x) {
+ ret = GetAtan2Tbl(-y, -x) + 0x8000;
+ } else {
+ ret = 0xC000 - GetAtan2Tbl(-x, -y);
+ }
+ } else {
+ if (x < -y) {
+ ret = GetAtan2Tbl(x, -y) + 0xC000;
+ } else {
+ ret = -GetAtan2Tbl(-y, x);
+ }
+ }
+ }
+ return ret;
+}
+
+f32 atan2f(f32 x, f32 y) {
+ return atan2s(x, y) * (M_PI / 32768.0f);
+}
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 662bb1ecf..55a5c4029 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1128,7 +1128,7 @@ void Gameplay_Draw(GlobalContext* globalCtx) {
view.flags = 2 | 8;
// clang-format off
- viewport.bottomY = SCREEN_HEIGHT; viewport.rightX = SCREEN_WIDTH;
+ viewport.bottomY = SCREEN_HEIGHT; viewport.rightX = SCREEN_WIDTH;
viewport.topY = 0; viewport.leftX = 0;
// clang-format on
@@ -1600,7 +1600,7 @@ s32 func_800C04D8(GlobalContext* globalCtx, s16 camId, Vec3f* arg2, Vec3f* arg3)
if (1) {} // Necessary to match
- camera->unk_DC = func_800CB678(arg2, arg3);
+ camera->unk_DC = Math3D_Vec3f_DistXYZ(arg2, arg3);
player = camera->player;
if (player != NULL) {