summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
authorengineer124 <47598039+engineer124@users.noreply.github.com>2024-06-15 15:39:31 +1000
committerGitHub <noreply@github.com>2024-06-14 22:39:31 -0700
commitb55f8ffe6e60ed2335acbe7d428049ea1056f4b5 (patch)
tree7aa56780d34acb286b92e829d401d5b2fa01bc65 /src/code
parent3705eaedac1d21318ee708993d366b30cdc0e8ad (diff)
`sys_math3d.c` Decompiled and Mostly Documented (#1450)
* Use matched sys_math3d functions by Tharo Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> * kinda match some unattempted functions * move sys_math3d function declarations to z64math.h * Rename some simple functions * Take matched Math3D_LineVsLineClosestTwoPoints from OoT * minor fixes to make stuff actually equivalent * func_8017FB1C * format * minor cleanup * Math3D_PointOnDirectedLine * func_8017FB1C documentation Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> * Remove actorfixer * fix merge * Apply renames * more cleanup * bss cleanup * match Math3D_CylVsLineSeg * WIP * OK * small cleanup * Remove macros.h from sys_math3d * Small cleanup * Some more small clean up * cleanup and docs * cleanup * PR Review * cleanup * fix merge * fix merge * merge main * fix bss * bss * fix * PR Review * bss fix * Merge main * Fix bss * Fix merge * Add zero vecs to sys_math3d * Format * namefixer run --------- Co-authored-by: angie <angheloalf95@gmail.com> Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> Co-authored-by: EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> Co-authored-by: Derek Hensley <hensley.derek58@gmail.com>
Diffstat (limited to 'src/code')
-rw-r--r--src/code/sys_math3d.c2653
-rw-r--r--src/code/z_actor.c18
-rw-r--r--src/code/z_bgcheck.c20
-rw-r--r--src/code/z_camera.c24
-rw-r--r--src/code/z_collision_check.c177
-rw-r--r--src/code/z_eff_blure.c4
-rw-r--r--src/code/z_eff_tire_mark.c4
-rw-r--r--src/code/z_fbdemo.c1
-rw-r--r--src/code/z_fireobj.c2
-rw-r--r--src/code/z_kankyo.c2
-rw-r--r--src/code/z_play.c4
-rw-r--r--src/code/z_sub_s.c6
12 files changed, 2593 insertions, 322 deletions
diff --git a/src/code/sys_math3d.c b/src/code/sys_math3d.c
index 45b94d569..ad617e50f 100644
--- a/src/code/sys_math3d.c
+++ b/src/code/sys_math3d.c
@@ -1,189 +1,2464 @@
-#include "global.h"
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Normalize.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PlaneVsLineSegClosestPoint.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179798.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179A44.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179B34.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179B94.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179D74.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ScaleAndAdd.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Lerp.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Parallel.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_AngleBetweenVectors.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179F64.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZBoundCheck.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A09C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A1D0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A304.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A438.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZLengthSquared.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZLength.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZDistanceSquared.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZDistance.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LengthSquared.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Vec3fMagnitude.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Vec3fDistSq.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Distance.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_DistanceS.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A7B8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A7F8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A838.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_CrossProduct.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_SurfaceNorm.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeFaces.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeEdges.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeVertices.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineVsCube.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017B68C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017B7F8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_UnitNormalVector.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_SignedDistanceFromPlane.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017B9D8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_UDistPlaneToPos.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_DistPlaneToPos.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYDist.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BD98.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BDE0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectDist.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BF8C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaYIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C17C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C1F0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri2.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXDist.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C808.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C904.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaXIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CB08.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZDist.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CEA8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaZIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CFA4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D1AC.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D220.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineSegVsPlane.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D404.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriSetCoords.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_IsPointInSphere.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointDistToLine2D.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D7C0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D814.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D91C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017DA24.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineVsSph.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017DD34.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereTri.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017E294.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017E350.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColCylinderTri.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017F1A0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_SphVsSph.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereSphereIntersect.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereSphereIntersectAndDistance.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereCylinderDistance.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereCylinderDistanceAndAmount.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmount.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmountAndDistance.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3d_ColTriTri.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZInSphere.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XYInSphere.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_YZInSphere.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017FB1C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017FD44.s")
+#include "prevent_bss_reordering.h"
+// clang-format off
+// Partial structs taken from "prevent_bss_reordering.h"
+struct Dummy200 { int x; };
+struct Dummy201 { int x; };
+struct Dummy202 { int x; };
+struct Dummy203 { int x; };
+struct Dummy204 { int x; };
+struct Dummy205 { int x; };
+struct Dummy206 { int x; };
+struct Dummy207 { int x; };
+struct Dummy208 { int x; };
+struct Dummy209 { int x; };
+struct Dummy210 { int x; };
+struct Dummy211 { int x; };
+struct Dummy212 { int x; };
+// clang-format on
+
+#include "z64math.h"
+
+#include "libc/stdbool.h"
+#include "PR/gu.h"
+
+Vec3f gZeroVec3f = { 0.0f, 0.0f, 0.0f };
+Vec3s gZeroVec3s = { 0, 0, 0 };
+
+#define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0]))
+
+f32 Math3D_Normalize(Vec3f* vec) {
+ f32 magnitude = Math3D_Vec3fMagnitude(vec);
+
+ if (IS_ZERO(magnitude)) {
+ return 0.0f;
+ }
+
+ vec->x *= 1.0f / magnitude;
+ vec->y *= 1.0f / magnitude;
+ vec->z *= 1.0f / magnitude;
+ return magnitude;
+}
+
+/**
+ * Creates an infinite line along the intersection of the plane defined from `planeAA`x + `planeAB`y + `planeAB`z +
+ * `planeADist` = 0 and `planeBA`x + `planeBB`y + `planeBC`z + `planeBDist` = 0, and finds the closest point on that
+ * intersection to the line segment `linePointA and linePointB`, outputs the intersection to `closestPoint`
+ */
+s32 Math3D_PlaneVsLineSegClosestPoint(f32 planeAA, f32 planeAB, f32 planeAC, f32 planeADist, f32 planeBA, f32 planeBB,
+ f32 planeBC, f32 planeBDist, Vec3f* linePointA, Vec3f* linePointB,
+ Vec3f* closestPoint) {
+ static InfiniteLine sPlaneIntersectLine;
+ static Linef sPlaneIntersectSeg;
+ Vec3f sp34; // unused
+
+ if (!Math3D_PlaneVsPlaneNewLine(planeAA, planeAB, planeAC, planeADist, planeBA, planeBB, planeBC, planeBDist,
+ &sPlaneIntersectLine)) {
+ // The planes are parallel
+ return false;
+ }
+
+ // create a line segment on the plane.
+ Math_Vec3f_Copy(&sPlaneIntersectSeg.a, &sPlaneIntersectLine.point);
+ sPlaneIntersectSeg.b.x = (sPlaneIntersectLine.dir.x * 100.0f) + sPlaneIntersectLine.point.x;
+ sPlaneIntersectSeg.b.y = (sPlaneIntersectLine.dir.y * 100.0f) + sPlaneIntersectLine.point.y;
+ sPlaneIntersectSeg.b.z = (sPlaneIntersectLine.dir.z * 100.0f) + sPlaneIntersectLine.point.z;
+
+ // closestPoint is a point on planeIntersect, sp34 is a point on linePointA, linePointB
+ if (!Math3D_LineSegMakePerpLineSeg(&sPlaneIntersectSeg.a, &sPlaneIntersectSeg.b, linePointA, linePointB,
+ closestPoint, &sp34)) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Finds the two points on lines A and B where the lines are closest together.
+ */
+s32 Math3D_LineSegMakePerpLineSeg(Vec3f* lineAPointA, Vec3f* lineAPointB, Vec3f* lineBPointA, Vec3f* lineBPointB,
+ Vec3f* lineAClosestToB, Vec3f* lineBClosestToA) {
+ f32 magSq;
+ f32 scaleB;
+ f32 lineAx = lineAPointB->x - lineAPointA->x;
+ f32 lineAy = lineAPointB->y - lineAPointA->y;
+ f32 lineAz = lineAPointB->z - lineAPointA->z;
+ f32 lineBx = lineBPointB->x - lineBPointA->x;
+ f32 lineBy = lineBPointB->y - lineBPointA->y;
+ f32 lineBz = lineBPointB->z - lineBPointA->z;
+ f32 compAAlongB;
+ f32 compBAAlongB;
+ Vec3f lineAPerpB;
+ Vec3f lineBAPerpB;
+ f32 tA;
+ f32 tB;
+
+ magSq = SQ(lineBx) + SQ(lineBy) + SQ(lineBz);
+ if (IS_ZERO(magSq)) {
+ return false;
+ }
+
+ scaleB = 1.0f / magSq;
+
+ compAAlongB = ((lineAx * lineBx) + (lineAy * lineBy) + (lineAz * lineBz)) * scaleB;
+
+ compBAAlongB = ((lineBx * (lineAPointA->x - lineBPointA->x)) + (lineBy * (lineAPointA->y - lineBPointA->y)) +
+ (lineBz * (lineAPointA->z - lineBPointA->z))) *
+ scaleB;
+
+ lineAPerpB.x = lineAx - (lineBx * compAAlongB);
+ lineAPerpB.y = lineAy - (lineBy * compAAlongB);
+ lineAPerpB.z = lineAz - (lineBz * compAAlongB);
+
+ magSq = SQXYZ(lineAPerpB);
+ if (IS_ZERO(magSq)) {
+ return false;
+ }
+
+ lineBAPerpB.x = (lineAPointA->x - lineBPointA->x) - (lineBx * compBAAlongB);
+ lineBAPerpB.y = (lineAPointA->y - lineBPointA->y) - (lineBy * compBAAlongB);
+ lineBAPerpB.z = (lineAPointA->z - lineBPointA->z) - (lineBz * compBAAlongB);
+
+ tA = -DOTXYZ(lineAPerpB, lineBAPerpB) / magSq;
+ lineAClosestToB->x = (lineAx * tA) + lineAPointA->x;
+ lineAClosestToB->y = (lineAy * tA) + lineAPointA->y;
+ lineAClosestToB->z = (lineAz * tA) + lineAPointA->z;
+
+ tB = (compAAlongB * tA) + compBAAlongB;
+ lineBClosestToA->x = (lineBx * tB) + lineBPointA->x;
+ lineBClosestToA->y = (lineBy * tB) + lineBPointA->y;
+ lineBClosestToA->z = (lineBz * tB) + lineBPointA->z;
+
+ return true;
+}
+
+/**
+ * Determines the closest point on the line `line` to `pos`, by forming a line perpendicular from
+ * `point` to `line` closest point is placed in `closestPoint`
+ */
+f32 Math3D_LineClosestToPoint(InfiniteLine* line, Vec3f* pos, Vec3f* closestPoint) {
+ f32 dirMagnitudeSq = Math3D_Vec3fMagnitudeSq(&line->dir);
+ f32 t;
+
+ if (IS_ZERO(dirMagnitudeSq)) {
+ Math_Vec3f_Copy(closestPoint, pos);
+ //! @bug Missing early return
+ }
+
+ t = (((pos->x - line->point.x) * line->dir.x) + ((pos->y - line->point.y) * line->dir.y) +
+ ((pos->z - line->point.z) * line->dir.z)) /
+ dirMagnitudeSq;
+ closestPoint->x = (line->dir.x * t) + line->point.x;
+ closestPoint->y = (line->dir.y * t) + line->point.y;
+ closestPoint->z = (line->dir.z * t) + line->point.z;
+
+ return t;
+}
+
+void Math3D_FindPointOnPlaneIntersect(f32 planeAAxis1Norm, f32 planeAAxis2Norm, f32 planeBAxis1Norm,
+ f32 planeBAxis2Norm, f32 axis3Direction, f32 planeADist, f32 planeBDist,
+ f32* axis1Point, f32* axis2Point) {
+ *axis1Point = ((planeAAxis2Norm * planeBDist) - (planeBAxis2Norm * planeADist)) / axis3Direction;
+ *axis2Point = ((planeBAxis1Norm * planeADist) - (planeAAxis1Norm * planeBDist)) / axis3Direction;
+}
+
+/**
+ * Creates a line between the intersections of two planes defined from `planeAA`x + `planeAB`y + `planeAC`z +
+ * `planeADist` = 0 and `planeBA`x + `planeBB`y + `planeBC`z + `planeBDist` = 0, and outputs the line to `intersect`.
+ * Returns false if the planes are parallel.
+ */
+s32 Math3D_PlaneVsPlaneNewLine(f32 planeAA, f32 planeAB, f32 planeAC, f32 planeADist, f32 planeBA, f32 planeBB,
+ f32 planeBC, f32 planeBDist, InfiniteLine* intersect) {
+ s32 pad;
+ Vec3f planeANormal;
+ Vec3f planeBNormal;
+ f32 dirX;
+ f32 dirY;
+ f32 dirZ;
+
+ VEC_SET(planeANormal, planeAA, planeAB, planeAC);
+ VEC_SET(planeBNormal, planeBA, planeBB, planeBC);
+
+ Math3D_Vec3f_Cross(&planeANormal, &planeBNormal, &intersect->dir);
+
+ if (IS_ZERO(intersect->dir.x) && IS_ZERO(intersect->dir.y) && IS_ZERO(intersect->dir.z)) {
+ // planes are parallel
+ return false;
+ }
+
+ dirX = fabsf(intersect->dir.x);
+ dirY = fabsf(intersect->dir.y);
+ dirZ = fabsf(intersect->dir.z);
+
+ if ((dirX >= dirY) && (dirX >= dirZ)) {
+ Math3D_FindPointOnPlaneIntersect(planeAB, planeAC, planeBB, planeBC, intersect->dir.x, planeADist, planeBDist,
+ &intersect->point.y, &intersect->point.z);
+ intersect->point.x = 0.0f;
+ } else if ((dirY >= dirX) && (dirY >= dirZ)) {
+ Math3D_FindPointOnPlaneIntersect(planeAC, planeAA, planeBC, planeBA, intersect->dir.y, planeADist, planeBDist,
+ &intersect->point.z, &intersect->point.x);
+ intersect->point.y = 0.0f;
+ } else {
+ Math3D_FindPointOnPlaneIntersect(planeAA, planeAB, planeBA, planeBB, intersect->dir.z, planeADist, planeBDist,
+ &intersect->point.x, &intersect->point.y);
+ intersect->point.z = 0.0f;
+ }
+ return true;
+}
+
+/**
+ * Gets the closest point on the line formed from the intersection of of the planes defined from
+ * `planeAA`x + `planeAB`y + `planeAC`z + `planeADist` = 0 and
+ * `planeBA`x + `planeBB`y + `planeBC`z + `planeBDist` = 0
+ * the point on the intersection line closest to `point` is placed in `closestPoint`
+ * returns false if the planes are parallel.
+ */
+s32 Math3D_PlaneVsPlaneVsLineClosestPoint(f32 planeAA, f32 planeAB, f32 planeAC, f32 planeADist, f32 planeBA,
+ f32 planeBB, f32 planeBC, f32 planeBDist, Vec3f* point, Vec3f* closestPoint) {
+ static InfiniteLine sPlaneIntersect;
+
+ if (!Math3D_PlaneVsPlaneNewLine(planeAA, planeAB, planeAC, planeADist, planeBA, planeBB, planeBC, planeBDist,
+ &sPlaneIntersect)) {
+ return false;
+ }
+ Math3D_LineClosestToPoint(&sPlaneIntersect, point, closestPoint);
+ return true;
+}
+
+/**
+ * Calculates the point on the line from starting point `v0`, in the direction `dir` scaled by `scale`. Result is placed
+ * in `ret`
+ */
+void Math3D_PointOnDirectedLine(Vec3f* v0, Vec3f* dir, f32 scale, Vec3f* ret) {
+ ret->x = (dir->x * scale) + v0->x;
+ ret->y = (dir->y * scale) + v0->y;
+ ret->z = (dir->z * scale) + v0->z;
+}
+
+/**
+ * Splits the line segment from end points `v0` and `v1`, and splits that segment
+ * by `ratio` of `v0`:`v1`, places the resulting point on the line in `ret`
+ */
+void Math3D_LineSplitRatio(Vec3f* v0, Vec3f* v1, f32 ratio, Vec3f* ret) {
+ Vec3f diff;
+
+ Math_Vec3f_Diff(v1, v0, &diff);
+ Math3D_PointOnDirectedLine(v0, &diff, ratio, ret);
+}
+
+/**
+ * Calculates the cosine between vectors `a` and `b`
+ */
+f32 Math3D_Cos(Vec3f* a, Vec3f* b) {
+ f32 ret;
+
+ Math3D_CosOut(a, b, &ret);
+ return ret;
+}
+
+/**
+ * Calculates the cosine between vectors `a` and `b` and places the result in `dst`
+ * returns true if the cosine cannot be calculated because the product of the magnitudes is zero
+ */
+s32 Math3D_CosOut(Vec3f* a, Vec3f* b, f32* dst) {
+ f32 magProduct = Math3D_Vec3fMagnitude(a) * Math3D_Vec3fMagnitude(b);
+
+ if (IS_ZERO(magProduct)) {
+ *dst = 0.0f;
+ return true;
+ }
+ *dst = ((a->x * b->x) + (a->y * b->y) + (a->z * b->z)) / magProduct;
+ return false;
+}
+
+/**
+ * Reflects vector `vec` across the normal vector `normal`, reflection vector is placed in
+ * `reflVec`
+ */
+void Math3D_Vec3fReflect(Vec3f* vec, Vec3f* normal, Vec3f* reflVec) {
+ f32 normScaleY;
+ Vec3f negVec;
+ f32 normScaleZ;
+ f32 normScaleX;
+ f32 vecDotNorm;
+
+ negVec.x = vec->x * -1.0f;
+ negVec.y = vec->y * -1.0f;
+ negVec.z = vec->z * -1.0f;
+
+ vecDotNorm = Math3D_Cos(&negVec, normal);
+
+ normScaleX = normal->x * vecDotNorm;
+ normScaleY = normal->y * vecDotNorm;
+ normScaleZ = normal->z * vecDotNorm;
+
+ reflVec->x = ((normScaleX + vec->x) + (normScaleX + vec->x)) + negVec.x;
+ reflVec->y = ((normScaleY + vec->y) + (normScaleY + vec->y)) + negVec.y;
+ reflVec->z = ((normScaleZ + vec->z) + (normScaleZ + vec->z)) + negVec.z;
+}
+
+/**
+ * Checks if the point (`x`,`y`) is contained within the square formed from (`upperLeftX`,`upperLeftY`) to
+ * (`lowerRightX`,`lowerRightY`)
+ */
+s32 Math3D_PointInSquare2D(f32 upperLeftX, f32 lowerRightX, f32 upperLeftY, f32 lowerRightY, f32 x, f32 y) {
+ if ((x >= upperLeftX) && (x <= lowerRightX) && (y >= upperLeftY) && (y <= lowerRightY)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Checks if the square in the XY planed formed around the circle with center (`centerX`,`centerY`)
+ * with radius `radius` touches any portion of the square formed around the triangle formed from `v0`, `v1`, and `v2`
+ */
+s32 Math3D_CirSquareVsTriSquareXY(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 centerX, f32 centerY, f32 radius) {
+ f32 min;
+ f32 max;
+
+ if (v0->x < v1->x) {
+ min = v0->x;
+ max = v1->x;
+ } else {
+ min = v1->x;
+ max = v0->x;
+ }
+
+ if (min > v2->x) {
+ min = v2->x;
+ } else if (max < v2->x) {
+ max = v2->x;
+ }
+
+ if ((centerX < (min - radius)) || ((max + radius) < centerX)) {
+ return false;
+ }
+ if (v0->y < v1->y) {
+ min = v0->y;
+ max = v1->y;
+ } else {
+ min = v1->y;
+ max = v0->y;
+ }
+ if (min > v2->y) {
+ min = v2->y;
+ } else if (max < v2->y) {
+ max = v2->y;
+ }
+
+ if ((centerY < (min - radius)) || (centerY > (max + radius))) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Checks if the square in the YZ planed formed around the circle with center (`centerY`,`centerZ`)
+ * with radius `radius` touches any portion of the square formed around the triangle formed from `v0`, `v1`, and `v2`
+ */
+s32 Math3D_CirSquareVsTriSquareYZ(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 centerY, f32 centerZ, f32 radius) {
+ f32 min;
+ f32 max;
+
+ if (v0->z < v1->z) {
+ min = v0->z;
+ max = v1->z;
+ } else {
+ min = v1->z;
+ max = v0->z;
+ }
+
+ if (min > v2->z) {
+ min = v2->z;
+ } else if (max < v2->z) {
+ max = v2->z;
+ }
+
+ if ((centerZ < (min - radius)) || ((max + radius) < centerZ)) {
+ return false;
+ }
+
+ if (v0->y < v1->y) {
+ min = v0->y;
+ max = v1->y;
+ } else {
+ min = v1->y;
+ max = v0->y;
+ }
+
+ if (min > v2->y) {
+ min = v2->y;
+ } else if (max < v2->y) {
+ max = v2->y;
+ }
+
+ if ((centerY < (min - radius)) || ((max + radius) < centerY)) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Checks if the square in the ZX planed formed around the circle with center (`centerZ`,`centerX`)
+ * with radius `radius` touches any portion of the square formed around the triangle formed from `v0`, `v1`, and `v2`
+ */
+s32 Math3D_CirSquareVsTriSquareZX(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 centerZ, f32 centerX, f32 radius) {
+ f32 min;
+ f32 max;
+
+ if (v0->x < v1->x) {
+ min = v0->x;
+ max = v1->x;
+ } else {
+ min = v1->x;
+ max = v0->x;
+ }
+
+ if (min > v2->x) {
+ min = v2->x;
+ } else if (max < v2->x) {
+ max = v2->x;
+ }
+
+ if ((centerX < (min - radius)) || ((max + radius) < centerX)) {
+ return false;
+ }
+
+ if (v0->z < v1->z) {
+ min = v0->z;
+ max = v1->z;
+ } else {
+ min = v1->z;
+ max = v0->z;
+ }
+
+ if (min > v2->z) {
+ min = v2->z;
+ } else if (max < v2->z) {
+ max = v2->z;
+ }
+
+ if ((centerZ < (min - radius)) || ((max + radius) < centerZ)) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Checks if the cube formed around the triangle formed from `v0`, `v1`, and `v2`
+ * has any portion touching the cube formed around the sphere with center `center`
+ * and radius of `radius`
+ */
+s32 Math3D_SphCubeVsTriCube(Vec3f* v0, Vec3f* v1, Vec3f* v2, Vec3f* center, f32 radius) {
+ f32 min;
+ f32 max;
+
+ if (v0->x < v1->x) {
+ min = v0->x;
+ max = v1->x;
+ } else {
+ min = v1->x;
+ max = v0->x;
+ }
+
+ if (min > v2->x) {
+ min = v2->x;
+ } else if (max < v2->x) {
+ max = v2->x;
+ }
+
+ if ((center->x < (min - radius)) || ((max + radius) < center->x)) {
+ return false;
+ }
+
+ if (v0->z < v1->z) {
+ min = v0->z;
+ max = v1->z;
+ } else {
+ min = v1->z;
+ max = v0->z;
+ }
+
+ if (min > v2->z) {
+ min = v2->z;
+ } else if (max < v2->z) {
+ max = v2->z;
+ }
+
+ if ((center->z < (min - radius)) || ((max + radius) < center->z)) {
+ return false;
+ }
+
+ if (v0->y < v1->y) {
+ min = v0->y;
+ max = v1->y;
+ } else {
+ min = v1->y;
+ max = v0->y;
+ }
+
+ if (min > v2->y) {
+ min = v2->y;
+ } else if (max < v2->y) {
+ max = v2->y;
+ }
+
+ if ((center->y < (min - radius)) || ((max + radius) < center->y)) {
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Returns the distance squared between `a` and `b` on a single axis
+ */
+f32 Math3D_Dist1DSq(f32 a, f32 b) {
+ return SQ(a) + SQ(b);
+}
+
+/**
+ * Returns the distance between `a` and `b` on a single axis
+ */
+f32 Math3D_Dist1D(f32 a, f32 b) {
+ return sqrtf(Math3D_Dist1DSq(a, b));
+}
+
+/**
+ * Returns the distance squared between (`x0`,`y0`) and (`x1`,`x2`)
+ */
+f32 Math3D_Dist2DSq(f32 x0, f32 y0, f32 x1, f32 y1) {
+ return Math3D_Dist1DSq(x0 - x1, y0 - y1);
+}
+
+/**
+ * Returns the distance between points (`x0`,`y0`) and (`x1`,`y1`)
+ */
+f32 Math3D_Dist2D(f32 x0, f32 y0, f32 x1, f32 y1) {
+ return sqrtf(Math3D_Dist2DSq(x0, y0, x1, y1));
+}
+
+/**
+ * Returns the magnitude (length) squared of `vec`
+ */
+f32 Math3D_Vec3fMagnitudeSq(Vec3f* vec) {
+ return SQ(vec->x) + SQ(vec->y) + SQ(vec->z);
+}
+
+/**
+ * Returns the magnitude (length) of `vec`
+ */
+f32 Math3D_Vec3fMagnitude(Vec3f* vec) {
+ return sqrtf(Math3D_Vec3fMagnitudeSq(vec));
+}
+
+/**
+ * Returns the distance between `a` and `b` squared.
+ */
+f32 Math3D_Vec3fDistSq(Vec3f* a, Vec3f* b) {
+ Vec3f diff;
+
+ Math_Vec3f_Diff(a, b, &diff);
+
+ return Math3D_Vec3fMagnitudeSq(&diff);
+}
+
+/*
+ * 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);
+}
+
+static Vec3f sABDiff;
+static Vec3f sACDiff;
+
+/**
+ * Gets the Z portion of the cross product of vectors `a - (`dx`,`dy`,z) and `b` - (`dx`,`dy`,z)
+ */
+f32 Math3D_Vec3fDiff_CrossZ(Vec3f* a, Vec3f* b, f32 dx, f32 dy) {
+ return ((a->x - dx) * (b->y - dy)) - ((a->y - dy) * (b->x - dx));
+}
+
+/**
+ * Gets the X portion of the cross product of vectors `a - (x,`dy`,`dz`) and `b` - (x,`dy`,`dz`)
+ */
+f32 Math3D_Vec3fDiff_CrossX(Vec3f* a, Vec3f* b, f32 dy, f32 dz) {
+ return ((a->y - dy) * (b->z - dz)) - ((a->z - dz) * (b->y - dy));
+}
+
+/**
+ * Gets the Y portion of the cross product of vectors `a - (`dx`,y,`dz`) and `b` - (`dx`,y,`dz`)
+ */
+f32 Math3D_Vec3fDiff_CrossY(Vec3f* a, Vec3f* b, f32 dz, f32 dx) {
+ return ((a->z - dz) * (b->x - dx)) - ((a->x - dx) * (b->z - dz));
+}
+
+/**
+ * Gets the Cross Product of vectors `a` and `b` and places the result in `ret`
+ */
+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) {
+ Math_Vec3f_Diff(vb, va, &sABDiff);
+ Math_Vec3f_Diff(vc, va, &sACDiff);
+ Math3D_Vec3f_Cross(&sABDiff, &sACDiff, normal);
+}
+
+/**
+ * Creates flags relative to the faces of a cube.
+ */
+s32 Math3D_PointRelativeToCubeFaces(Vec3f* point, Vec3f* min, Vec3f* max) {
+ s32 ret = 0;
+
+ if (point->x > max->x) {
+ ret = 1;
+ } else if (point->x < min->x) {
+ ret |= 2;
+ }
+
+ if (point->y > max->y) {
+ ret |= 4;
+ } else if (point->y < min->y) {
+ ret |= 8;
+ }
+
+ if (point->z > max->z) {
+ ret |= 0x10;
+ } else if (point->z < min->z) {
+ ret |= 0x20;
+ }
+
+ return ret;
+}
+
+/**
+ * Creates flags of `point` relative to the edges of a cube
+ */
+s32 Math3D_PointRelativeToCubeEdges(Vec3f* point, Vec3f* min, Vec3f* max) {
+ s32 ret = 0;
+
+ if ((-min->x + max->y) < (-point->x + point->y)) {
+ ret |= 1;
+ }
+
+ if ((-point->x + point->y) < (-max->x + min->y)) {
+ ret |= 2;
+ }
+
+ if ((max->x + max->y) < (point->x + point->y)) {
+ ret |= 4;
+ }
+
+ if ((point->x + point->y) < (min->x + min->y)) {
+ ret |= 8;
+ }
+
+ if ((-min->z + max->y) < (-point->z + point->y)) {
+ ret |= 0x10;
+ }
+
+ if ((-point->z + point->y) < (-max->z + min->y)) {
+ ret |= 0x20;
+ }
+
+ if ((max->z + max->y) < (point->z + point->y)) {
+ ret |= 0x40;
+ }
+
+ if ((point->z + point->y) < (min->z + min->y)) {
+ ret |= 0x80;
+ }
+
+ if ((-min->z + max->x) < (-point->z + point->x)) {
+ ret |= 0x100;
+ }
+
+ if ((-point->z + point->x) < (-max->z + min->x)) {
+ ret |= 0x200;
+ }
+
+ if ((max->z + max->x) < (point->z + point->x)) {
+ ret |= 0x400;
+ }
+
+ if ((point->z + point->x) < (min->z + min->x)) {
+ ret |= 0x800;
+ }
+ return ret;
+}
+
+/**
+ * Creates flags for `point` relative to the vertices of a cube
+ */
+s32 Math3D_PointRelativeToCubeVertices(Vec3f* point, Vec3f* min, Vec3f* max) {
+ s32 ret = 0;
+
+ if ((max->x + max->y + max->z) < (point->x + point->y + point->z)) {
+ ret = 1;
+ }
+
+ if ((-min->x + max->y + max->z) < (-point->x + point->y + point->z)) {
+ ret |= 2;
+ }
+
+ if ((-min->x + max->y - min->z) < (-point->x + point->y - point->z)) {
+ ret |= 4;
+ }
+
+ if ((max->x + max->y - min->z) < (point->x + point->y - point->z)) {
+ ret |= 8;
+ }
+
+ if ((max->x - min->y + max->z) < (point->x - point->y + point->z)) {
+ ret |= 0x10;
+ }
+
+ //! @bug: The next 2 conditions are the same check.
+ if ((-min->x - min->y + max->z) < (-point->x - point->y + point->z)) {
+ ret |= 0x20;
+ }
+
+ if ((-min->x - min->y + max->z) < (-point->x - point->y + point->z)) {
+ ret |= 0x40;
+ }
+
+ if ((-min->x - min->y - min->z) < (-point->x - point->y - point->z)) {
+ ret |= 0x80;
+ }
+ return ret;
+}
+
+/**
+ * Checks if a line segment with endpoints `a` and `b` intersect a cube
+ */
+s32 Math3D_LineVsCube(Vec3f* min, Vec3f* max, Vec3f* a, Vec3f* b) {
+ static Vec3f sTriVtx0;
+ static Vec3f sTriVtx1;
+ static Vec3f sTriVtx2;
+ static Vec3f sIntersectPoint;
+ s32 flags[2];
+
+ flags[0] = flags[1] = 0;
+ flags[0] = Math3D_PointRelativeToCubeFaces(a, min, max);
+ if (!flags[0]) {
+ return true;
+ }
+
+ flags[1] = Math3D_PointRelativeToCubeFaces(b, min, max);
+ if (!flags[1]) {
+ return true;
+ }
+
+ if (flags[0] & flags[1]) {
+ return false;
+ }
+
+ flags[0] |= (Math3D_PointRelativeToCubeEdges(a, min, max) << 8);
+ flags[1] |= (Math3D_PointRelativeToCubeEdges(b, min, max) << 8);
+ if (flags[0] & flags[1]) {
+ return false;
+ }
+
+ flags[0] |= (Math3D_PointRelativeToCubeVertices(a, min, max) << 0x18);
+ flags[1] |= (Math3D_PointRelativeToCubeVertices(b, min, max) << 0x18);
+ if (flags[0] & flags[1]) {
+ return false;
+ }
+
+ // face 1
+ sTriVtx0.x = min->x;
+ sTriVtx0.y = min->y;
+ sTriVtx0.z = min->z;
+ sTriVtx1.x = min->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = max->z;
+ sTriVtx2.x = min->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = max->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, -1.0f, 0.0f, 0.0f, min->x, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+
+ sTriVtx1.x = min->x;
+ sTriVtx1.y = max->y;
+ sTriVtx1.z = max->z;
+ sTriVtx2.x = min->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = min->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, -1.0f, 0.0f, 0.0f, min->x, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+
+ // face 2
+ sTriVtx0.x = min->x;
+ sTriVtx0.y = max->y;
+ sTriVtx0.z = max->z;
+ sTriVtx1.x = min->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = max->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = max->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 0.0f, 1.0f, -max->z, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx0.x = max->x;
+ sTriVtx0.y = max->y;
+ sTriVtx0.z = max->z;
+ sTriVtx2.x = max->x;
+ //! @bug trVtx1.y should be sTriVtx2.y, prevents a tri on the cube from being checked.
+ sTriVtx1.y = min->y;
+ sTriVtx2.z = max->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 0.0f, 1.0f, -max->z, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+
+ // face 3
+ sTriVtx1.x = min->x;
+ sTriVtx1.y = max->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = min->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = max->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 1.0f, 0.0f, -max->y, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = max->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = min->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = min->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 1.0f, 0.0f, -max->y, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+
+ // face 4
+ sTriVtx0.x = min->x;
+ sTriVtx0.y = min->y;
+ sTriVtx0.z = min->z;
+ sTriVtx1.x = min->x;
+ sTriVtx1.y = max->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = min->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 0.0f, -1.0f, min->z, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = max->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = min->y;
+ sTriVtx2.z = min->z;
+
+ // face 5
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, 0.0f, -1.0f, min->z, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = min->y;
+ sTriVtx2.z = max->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, -1.0f, 0.0f, min->y, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = max->z;
+ sTriVtx2.x = min->x;
+ sTriVtx2.y = min->y;
+ sTriVtx2.z = max->z;
+
+ // face 6
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 0.0f, -1.0f, 0.0f, min->y, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx0.x = max->x;
+ sTriVtx0.y = max->y;
+ sTriVtx0.z = max->z;
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = min->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = max->y;
+ sTriVtx2.z = min->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 1.0f, 0.0f, 0.0f, -max->x, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+ sTriVtx1.x = max->x;
+ sTriVtx1.y = min->y;
+ sTriVtx1.z = max->z;
+ sTriVtx2.x = max->x;
+ sTriVtx2.y = min->y;
+ sTriVtx2.z = min->z;
+ if (Math3D_TriLineIntersect(&sTriVtx0, &sTriVtx1, &sTriVtx2, 1.0f, 0.0f, 0.0f, -max->x, a, b, &sIntersectPoint,
+ 0)) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Checks if a line segment with endpoints `a` and `b` intersect a cube
+ */
+s32 Math3D_LineVsCubeShort(Vec3s* min, Vec3s* max, Vec3s* a, Vec3s* b) {
+ static Vec3f sMinF;
+ static Vec3f sMaxF;
+ static Vec3f sAF;
+ static Vec3f sBF;
+
+ sMinF.x = min->x;
+ sMinF.y = min->y;
+ sMinF.z = min->z;
+ sMaxF.x = max->x;
+ sMaxF.y = max->y;
+ sMaxF.z = max->z;
+ sAF.x = a->x;
+ sAF.y = a->y;
+ sAF.z = a->z;
+ sBF.x = b->x;
+ sBF.y = b->y;
+ sBF.z = b->z;
+
+ return Math3D_LineVsCube(&sMinF, &sMaxF, &sAF, &sBF);
+}
+
+/**
+ * Rotates the xz plane around the y axis `angle` degrees.
+ * outputs the plane equation `a``pointOnPlane->x` + 0y + `c``pointOnPlane->z`+`d` = 0
+ */
+void Math3D_RotateXZPlane(Vec3f* pointOnPlane, s16 angle, f32* a, f32* c, f32* d) {
+ *a = Math_SinS(angle) * 0x7FFF;
+ *c = Math_CosS(angle) * 0x7FFF;
+ *d = -((*a * pointOnPlane->x) + (*c * pointOnPlane->z));
+}
+
+/*
+ * Defines a plane from vertices `va`, `vb`, and `vc`. Normal components are output to
+ * `nx`, `ny`, and `nz`. Distance from the origin is output to `originDist`
+ * Satisfies the plane equation NxVx + NyVy + NzVz + D = 0
+ */
+void Math3D_DefPlane(Vec3f* va, Vec3f* vb, Vec3f* vc, f32* nx, f32* ny, f32* nz, f32* originDist) {
+ static Vec3f sNormal;
+ f32 normMagnitude;
+ f32 normMagInv;
+
+ Math3D_SurfaceNorm(va, vb, vc, &sNormal);
+ normMagnitude = sqrtf(SQ(sNormal.x) + SQ(sNormal.y) + SQ(sNormal.z));
+ if (!IS_ZERO(normMagnitude)) {
+ normMagInv = 1.0f / normMagnitude;
+ *nx = sNormal.x * normMagInv;
+ *ny = sNormal.y * normMagInv;
+ *nz = sNormal.z * normMagInv;
+ *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* pointOnPlane) {
+ return (nx * pointOnPlane->x) + (ny * pointOnPlane->y) + (nz * pointOnPlane->z) + originDist;
+}
+
+/*
+ * Returns the answer to the plane equation
+ */
+f32 Math3D_Plane(Plane* plane, Vec3f* pointOnPlane) {
+ return (plane->normal.x * pointOnPlane->x) + (plane->normal.y * pointOnPlane->y) +
+ (plane->normal.z * pointOnPlane->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) {
+ 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 = sqrtf(SQ(nx) + SQ(ny) + SQ(nz));
+
+ if (IS_ZERO(normMagnitude)) {
+ return 0.0f;
+ }
+ return Math3D_PlaneF(nx, ny, nz, originDist, p) / normMagnitude;
+}
+
+/**
+ * Checks if the point defined by (`z`,`x`) is within distance of the triangle defined from `v0`,`v1`, and `v2`
+ */
+s32 Math3D_TriChkPointParaYImpl(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 detMax, f32 chkDist, f32 ny) {
+ f32 detv0v1;
+ f32 detv1v2;
+ f32 detv2v0;
+ f32 distToEdgeSq;
+ f32 chkDistSq;
+
+ // first check if the point is within range of the triangle.
+ if (!Math3D_CirSquareVsTriSquareZX(v0, v1, v2, z, x, chkDist)) {
+ return false;
+ }
+
+ // check if the point is within `chkDist` units of any vertex of the triangle.
+ chkDistSq = SQ(chkDist);
+ if (((SQ(v0->z - z) + SQ(v0->x - x)) < chkDistSq) || ((SQ(v1->z - z) + SQ(v1->x - x)) < chkDistSq) ||
+ ((SQ(v2->z - z) + SQ(v2->x - x)) < chkDistSq)) {
+ return true;
+ }
+
+ // Calculate the determinant of each face of the triangle to the point.
+ // If all the of determinants are within abs(`detMax`), return true.
+ if (((detMax >= (detv0v1 = ((v0->z - z) * (v1->x - x)) - ((v0->x - x) * (v1->z - z)))) &&
+ (detMax >= (detv1v2 = ((v1->z - z) * (v2->x - x)) - ((v1->x - x) * (v2->z - z)))) &&
+ (detMax >= (detv2v0 = ((v2->z - z) * (v0->x - x)) - ((v2->x - x) * (v0->z - z)))))) {
+ return true;
+ }
+
+ if (((-detMax <= (detv0v1 = ((v0->z - z) * (v1->x - x)) - ((v0->x - x) * (v1->z - z)))) &&
+ (-detMax <= (detv1v2 = ((v1->z - z) * (v2->x - x)) - ((v1->x - x) * (v2->z - z)))) &&
+ (-detMax <= (detv2v0 = ((v2->z - z) * (v0->x - x)) - ((v2->x - x) * (v0->z - z)))))) {
+ return true;
+ }
+
+ if ((fabsf(ny) > 0.5f) && (chkDistSq > 0.0f)) {
+ // Do a check on each face of the triangle, if the point is within `chkDist` units return true.
+ if (Math3D_PointDistSqToLineZX(z, x, v0, v1, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if (Math3D_PointDistSqToLineZX(z, x, v1, v2, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if (Math3D_PointDistSqToLineZX(z, x, v2, v0, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+s32 Math3D_TriChkPointParaYDeterminate(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 detMax, f32 ny) {
+ return Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, detMax, 1.0f, ny);
+}
+
+s32 Math3D_TriChkPointParaYSlopedY(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x) {
+ return Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 300.0f, 1.0f, 0.6f);
+}
+
+/**
+ * Performs the triangle and point check parallel to the Y axis, outputs the y coordinate of the point to `yIntersect`
+ */
+s32 Math3D_TriChkPointParaYIntersectDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 z,
+ f32 x, f32* yIntersect, f32 chkDist) {
+ if (IS_ZERO(ny)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 300.0f, chkDist, ny)) {
+ *yIntersect = (((-nx * x) - (nz * z)) - originDist) / ny;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaYIntersectInsideTri(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist,
+ f32 z, f32 x, f32* yIntersect, f32 chkDist) {
+ if (IS_ZERO(ny)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 0.0f, chkDist, ny)) {
+ *yIntersect = (((-nx * x) - (nz * z)) - originDist) / ny;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaY(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 ny, f32 z, f32 x) {
+ if (IS_ZERO(ny)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 300.0f, 1.0f, ny)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkLineSegParaYIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 z,
+ f32 x, f32* yIntersect, f32 y0, f32 y1) {
+ f32 pointADist;
+ f32 pointBDist;
+ Vec3f planePos;
+
+ if (IS_ZERO(ny)) {
+ return false;
+ }
+
+ planePos.x = x;
+ planePos.y = y0;
+ planePos.z = z;
+
+ pointADist = Math3D_PlaneF(nx, ny, nz, originDist, &planePos);
+ planePos.y = y1;
+ pointBDist = Math3D_PlaneF(nx, ny, nz, originDist, &planePos);
+
+ if (((pointADist > 0.0f) && (pointBDist > 0.0f)) || ((pointADist < 0.0f) && (pointBDist < 0.0f))) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 300.0f, 1.0f, ny)) {
+ *yIntersect = (((-nx * x) - (nz * z)) - originDist) / ny;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaYDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, Plane* plane, f32 z, f32 x, f32 chkDist) {
+ if (IS_ZERO(plane->normal.y)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImpl(v0, v1, v2, z, x, 0.0f, chkDist, plane->normal.y)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaYImplNoCheckRange(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 detMax, f32 chkDist,
+ f32 ny) {
+ f32 detv0v1;
+ f32 detv1v2;
+ f32 detv2v0;
+ f32 distToEdgeSq;
+ f32 chkDistSq;
+
+ // check if the point is within `chkDist` units of any vertex of the triangle.
+ chkDistSq = SQ(chkDist);
+ if (((SQ(v0->z - z) + SQ(v0->x - x)) < chkDistSq) || ((SQ(v1->z - z) + SQ(v1->x - x)) < chkDistSq) ||
+ ((SQ(v2->z - z) + SQ(v2->x - x)) < chkDistSq)) {
+ return true;
+ }
+
+ // Calculate the determinant of each face of the triangle to the point.
+ // If all the of determinants are within abs(`detMax`), return true.
+ if (((detMax >= (detv0v1 = ((v0->z - z) * (v1->x - x)) - ((v0->x - x) * (v1->z - z)))) &&
+ (detMax >= (detv1v2 = ((v1->z - z) * (v2->x - x)) - ((v1->x - x) * (v2->z - z)))) &&
+ (detMax >= (detv2v0 = ((v2->z - z) * (v0->x - x)) - ((v2->x - x) * (v0->z - z)))))) {
+ return true;
+ }
+ if (((-detMax <= (detv0v1 = ((v0->z - z) * (v1->x - x)) - ((v0->x - x) * (v1->z - z)))) &&
+ (-detMax <= (detv1v2 = ((v1->z - z) * (v2->x - x)) - ((v1->x - x) * (v2->z - z)))) &&
+ (-detMax <= (detv2v0 = ((v2->z - z) * (v0->x - x)) - ((v2->x - x) * (v0->z - z)))))) {
+ return true;
+ }
+
+ if ((fabsf(ny) > 0.5f) && (chkDistSq > 0.0f)) {
+ // Do a check on each face of the triangle, if the point is within `chkDist` units return true.
+ if (Math3D_PointDistSqToLineZX(z, x, v0, v1, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if (Math3D_PointDistSqToLineZX(z, x, v1, v2, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if (Math3D_PointDistSqToLineZX(z, x, v2, v0, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaYNoRangeCheckIntersectInsideTri(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz,
+ f32 originDist, f32 z, f32 x, f32* yIntersect, f32 chkDist) {
+ if (IS_ZERO(ny)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaYImplNoCheckRange(v0, v1, v2, z, x, 0.0f, chkDist, ny)) {
+ *yIntersect = (((-nx * x) - (nz * z)) - originDist) / ny;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaXImpl(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 detMax, f32 chkDist, f32 ny) {
+ f32 detv0v1;
+ f32 detv1v2;
+ f32 detv2v0;
+ f32 distToEdgeSq;
+ f32 chkDistSq;
+
+ // first check if the point is within range of the triangle.
+ if (!Math3D_CirSquareVsTriSquareYZ(v0, v1, v2, y, z, chkDist)) {
+ return false;
+ }
+
+ // check if the point is within `chkDist` units of any vertex of the triangle.
+ chkDistSq = SQ(chkDist);
+ if (((SQ(v0->y - y) + SQ(v0->z - z)) < chkDistSq) || ((SQ(v1->y - y) + SQ(v1->z - z)) < chkDistSq) ||
+ ((SQ(v2->y - y) + SQ(v2->z - z)) < chkDistSq)) {
+ return true;
+ }
+
+ // Calculate the determinant of each face of the triangle to the point.
+ // If all the of determinants are within abs(`detMax`), return true.
+ if (((detMax >= (detv0v1 = ((v0->y - y) * (v1->z - z)) - ((v0->z - z) * (v1->y - y)))) &&
+ (detMax >= (detv1v2 = ((v1->y - y) * (v2->z - z)) - ((v1->z - z) * (v2->y - y)))) &&
+ (detMax >= (detv2v0 = ((v2->y - y) * (v0->z - z)) - ((v2->z - z) * (v0->y - y)))))) {
+ return true;
+ }
+ if (((-detMax <= (detv0v1 = ((v0->y - y) * (v1->z - z)) - ((v0->z - z) * (v1->y - y)))) &&
+ (-detMax <= (detv1v2 = ((v1->y - y) * (v2->z - z)) - ((v1->z - z) * (v2->y - y)))) &&
+ (-detMax <= (detv2v0 = ((v2->y - y) * (v0->z - z)) - ((v2->z - z) * (v0->y - y)))))) {
+ return true;
+ }
+
+ if ((fabsf(ny) > 0.5f) && (chkDistSq > 0.0f)) {
+ // Do a check on each face of the triangle, if the point is within `chkDist` units return true.
+ if ((Math3D_PointDistSqToLineYZ(y, z, v0, v1, &distToEdgeSq) != 0) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if ((Math3D_PointDistSqToLineYZ(y, z, v1, v2, &distToEdgeSq) != 0) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ if ((Math3D_PointDistSqToLineYZ(y, z, v2, v0, &distToEdgeSq) != 0) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+s32 Math3D_TriChkPointParaXDeterminate(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 detMax, f32 nx) {
+ return Math3D_TriChkPointParaXImpl(v0, v1, v2, y, z, detMax, 1.0f, nx);
+}
+
+s32 Math3D_TriChkPointParaXIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 y,
+ f32 z, f32* xIntersect) {
+ if (IS_ZERO(nx)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaXImpl(v0, v1, v2, y, z, 300.0f, 1.0f, nx)) {
+ *xIntersect = (((-ny * y) - (nz * z)) - originDist) / nx;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaX(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 y, f32 z) {
+ if (IS_ZERO(nx)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaXImpl(v0, v1, v2, y, z, 300.0f, 1.0f, nx)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkLineSegParaXIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 y,
+ f32 z, f32* xIntersect, f32 x0, f32 x1) {
+ static Vec3f sPlanePos;
+ f32 pointADist;
+ f32 pointBDist;
+
+ if (IS_ZERO(nx)) {
+ return false;
+ }
+
+ sPlanePos.x = x0;
+ sPlanePos.y = y;
+ sPlanePos.z = z;
+ pointADist = Math3D_PlaneF(nx, ny, nz, originDist, &sPlanePos);
+
+ sPlanePos.x = x1;
+ pointBDist = Math3D_PlaneF(nx, ny, nz, originDist, &sPlanePos);
+
+ if (((pointADist > 0.0f) && (pointBDist > 0.0f)) || ((pointADist < 0.0f) && (pointBDist < 0.0f))) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaXImpl(v0, v1, v2, y, z, 300.0f, 1.0f, nx)) {
+ *xIntersect = (((-ny * y) - (nz * z)) - originDist) / nx;
+ return true;
+ }
+ return false;
+}
+
+s32 Math3D_TriChkLineSegParaXDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, Plane* plane, f32 y, f32 z, f32 chkDist) {
+ if (IS_ZERO(plane->normal.x)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaXImpl(v0, v1, v2, y, z, 0.0f, chkDist, plane->normal.x)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaZImpl(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 x, f32 y, f32 detMax, f32 chkDist, f32 nz) {
+ f32 detv0v1;
+ f32 detv1v2;
+ f32 detv2v0;
+ f32 distToEdgeSq;
+ f32 chkDistSq;
+
+ if (!Math3D_CirSquareVsTriSquareXY(v0, v1, v2, x, y, chkDist)) {
+ return false;
+ }
+
+ chkDistSq = SQ(chkDist);
+
+ if (((SQ(x - v0->x) + SQ(y - v0->y)) < chkDistSq) || ((SQ(x - v1->x) + SQ(y - v1->y)) < chkDistSq) ||
+ ((SQ(x - v2->x) + SQ(y - v2->y)) < chkDistSq)) {
+ // Distance from any vertex to a point is less than chkDist
+ return true;
+ }
+
+ if (((detMax >= (detv0v1 = ((v0->x - x) * (v1->y - y)) - ((v0->y - y) * (v1->x - x)))) &&
+ (detMax >= (detv1v2 = ((v1->x - x) * (v2->y - y)) - ((v1->y - y) * (v2->x - x)))) &&
+ (detMax >= (detv2v0 = ((v2->x - x) * (v0->y - y)) - ((v2->y - y) * (v0->x - x)))))) {
+ return true;
+ }
+
+ if (((-detMax <= (detv0v1 = ((v0->x - x) * (v1->y - y)) - ((v0->y - y) * (v1->x - x)))) &&
+ (-detMax <= (detv1v2 = ((v1->x - x) * (v2->y - y)) - ((v1->y - y) * (v2->x - x)))) &&
+ (-detMax <= (detv2v0 = ((v2->x - x) * (v0->y - y)) - ((v2->y - y) * (v0->x - x)))))) {
+ return true;
+ }
+
+ if (fabsf(nz) > 0.5f && chkDistSq > 0.0f) {
+
+ if (Math3D_PointDistSqToLineXY(x, y, v0, v1, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+
+ if (Math3D_PointDistSqToLineXY(x, y, v1, v2, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+
+ if (Math3D_PointDistSqToLineXY(x, y, v2, v0, &distToEdgeSq) && (distToEdgeSq < chkDistSq)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaZDeterminate(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 detMax, f32 nx) {
+ return Math3D_TriChkPointParaZImpl(v0, v1, v2, y, z, detMax, 1.0f, nx);
+}
+
+s32 Math3D_TriChkPointParaZIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 x,
+ f32 y, f32* zIntersect) {
+ if (IS_ZERO(nz)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaZImpl(v0, v1, v2, x, y, 300.0f, 1.0f, nz)) {
+ *zIntersect = (((-nx * x) - (ny * y)) - originDist) / nz;
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkPointParaZ(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 y, f32 z) {
+ if (IS_ZERO(nx)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaZImpl(v0, v1, v2, y, z, 300.0f, 1.0f, nx)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_TriChkLineSegParaZIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 x,
+ f32 y, f32* zIntersect, f32 z0, f32 z1) {
+ static Vec3f sPlanePos;
+ f32 pointADist;
+ f32 pointBDist;
+
+ if (IS_ZERO(nz)) {
+ return false;
+ }
+
+ sPlanePos.x = x;
+ sPlanePos.y = y;
+ sPlanePos.z = z0;
+ pointADist = Math3D_PlaneF(nx, ny, nz, originDist, &sPlanePos);
+
+ sPlanePos.z = z1;
+ pointBDist = Math3D_PlaneF(nx, ny, nz, originDist, &sPlanePos);
+
+ if (((pointADist > 0.0f) && (pointBDist > 0.0f)) || ((pointADist < 0.0f) && (pointBDist < 0.0f))) {
+ // points on the line segment are on the same side of the plane
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaZImpl(v0, v1, v2, x, y, 300.0f, 1.0f, nz)) {
+ *zIntersect = (((-nx * x) - (ny * y)) - originDist) / nz;
+ return true;
+ }
+ return false;
+}
+
+s32 Math3D_TriChkLineSegParaZDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, Plane* plane, f32 x, f32 y, f32 chkDist) {
+ if (IS_ZERO(plane->normal.z)) {
+ return false;
+ }
+
+ if (Math3D_TriChkPointParaZImpl(v0, v1, v2, x, y, 0.0f, chkDist, plane->normal.z)) {
+ return true;
+ }
+
+ return false;
+}
+
+s32 Math3D_LineSegFindPlaneIntersect(f32 pointADist, f32 pointBDist, Vec3f* pointA, Vec3f* pointB, Vec3f* intersect) {
+ f32 distDiff = pointADist - pointBDist;
+
+ if (IS_ZERO(distDiff)) {
+ // both points lie on the plane.
+ *intersect = *pointB;
+ return false;
+ }
+
+ if (pointADist == 0.0f) {
+ // pointA is on the plane
+ *intersect = *pointA;
+ } else if (pointBDist == 0.0f) {
+ // pointB is on the plane
+ *intersect = *pointB;
+ } else {
+ // place the point at the intersection point.
+ Math3D_LineSplitRatio(pointA, pointB, pointADist / distDiff, intersect);
+ }
+ return true;
+}
+
+/**
+ * Determines if the line segment from `linePointA` to `linePointB` crosses the plane
+ * from `nx` + `ny` + `nz` + `originDist` = 0. If fromFront is set, then detection will only
+ * be true if point A crosses from the front of the plane
+ */
+s32 Math3D_LineSegVsPlane(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* linePointA, Vec3f* linePointB,
+ Vec3f* intersect, s32 fromFront) {
+ f32 pointADist = Math3D_PlaneF(nx, ny, nz, originDist, linePointA);
+ f32 pointBDist = Math3D_PlaneF(nx, ny, nz, originDist, linePointB);
+
+ if ((pointADist * pointBDist) > 0.0f) {
+ *intersect = *linePointB;
+ return false;
+ }
+
+ if (fromFront && (pointADist < 0.0f) && (pointBDist > 0.0f)) {
+ *intersect = *linePointB;
+ return false;
+ }
+
+ return Math3D_LineSegFindPlaneIntersect(pointADist, pointBDist, linePointA, linePointB, intersect);
+}
+
+/*
+ * Determines if the line formed by `linePointA` 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 fromFront) {
+
+ if (!Math3D_LineSegVsPlane(nx, ny, nz, originDist, linePointA, linePointB, intersect, fromFront)) {
+ return false;
+ }
+
+ if (((nx == 0.0f) || Math3D_TriChkPointParaX(v0, v1, v2, nx, intersect->y, intersect->z)) &&
+ ((ny == 0.0f) || Math3D_TriChkPointParaY(v0, v1, v2, ny, intersect->z, intersect->x)) &&
+ ((nz == 0.0f) || Math3D_TriChkPointParaZ(v0, v1, v2, nz, intersect->x, intersect->y))) {
+ return true;
+ }
+
+ *intersect = *linePointB;
+ return false;
+}
+
+/*
+ * 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;
+
+ Math3D_DefPlane(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_PointInSph(Sphere16* sphere, Vec3f* point) {
+ if (Math3D_DistXYZ16toF(&sphere->center, point) < sphere->radius) {
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Determines the distance from point (`x0`,`y0`) to the line formed from (`x1`,`y1`) and (`x2`,`y2`)
+ * Distance squared is output to `lineLenSq`, returns true if the point perpendicular from (`x0`,`y0`)
+ * is contained within the segment between (`x1`,`y1`) and (`x2`,`y2`)
+ */
+s32 Math3D_PointDistSqToLine2DImpl(f32 x0, f32 y0, f32 x1, f32 y1, f32 x2, f32 y2, f32* perpXOut, f32* perpYOut,
+ f32* lineLenSq) {
+ f32 perpendicularRatio;
+ f32 xDiff = x2 - x1;
+ f32 yDiff = y2 - y1;
+ f32 distSq = SQ(xDiff) + SQ(yDiff);
+ s32 ret = false;
+
+ if (IS_ZERO(distSq)) {
+ *lineLenSq = 0.0f;
+ return false;
+ }
+
+ perpendicularRatio = ((x0 - x1) * xDiff + (y0 - y1) * yDiff) / distSq;
+ if ((perpendicularRatio >= 0.0f) && (perpendicularRatio <= 1.0f)) {
+ ret = true;
+ }
+
+ *perpXOut = (xDiff * perpendicularRatio) + x1;
+ *perpYOut = (yDiff * perpendicularRatio) + y1;
+
+ *lineLenSq = SQ(*perpXOut - x0) + SQ(*perpYOut - y0);
+ return ret;
+}
+
+/**
+ * Determines the distance from point (`x0`,`y0`) to the line formed from (`x1`,`y1`) and (`x2`,`y2`)
+ * Distance squared is output to `lineLenSq`, returns true if the point perpendicular from (`x0`,`y0`)
+ * is contained within the segment between (`x1`,`y1`) and (`x2`,`y2`)
+ */
+s32 Math3D_PointDistSqToLine2D(f32 x0, f32 y0, f32 x1, f32 y1, f32 x2, f32 y2, f32* lineLenSq) {
+ f32 perpX;
+ f32 perpY;
+
+ return Math3D_PointDistSqToLine2DImpl(x0, y0, x1, y1, x2, y2, &perpX, &perpY, lineLenSq);
+}
+
+s32 Math3D_PointDistSqToLineXY(f32 x0, f32 y0, Vec3f* p1, Vec3f* p2, f32* lineLenSq) {
+ f32 perpendicularRatio;
+ f32 xDiff = p2->x - p1->x;
+ f32 yDiff = p2->y - p1->y;
+ f32 distSq = SQ(xDiff) + SQ(yDiff);
+ f32 perpX;
+ f32 perpY;
+ s32 ret = false;
+
+ if (IS_ZERO(distSq)) {
+ *lineLenSq = 0.0f;
+ return false;
+ }
+
+ perpendicularRatio = ((x0 - p1->x) * xDiff + (y0 - p1->y) * yDiff) / distSq;
+ if ((perpendicularRatio >= 0.0f) && (perpendicularRatio <= 1.0f)) {
+ ret = true;
+ }
+ perpX = (xDiff * perpendicularRatio) + p1->x;
+ perpY = (yDiff * perpendicularRatio) + p1->y;
+ *lineLenSq = SQ(perpX - x0) + SQ(perpY - y0);
+
+ return ret;
+}
+
+s32 Math3D_PointDistSqToLineYZ(f32 y0, f32 z0, Vec3f* p1, Vec3f* p2, f32* lineLenSq) {
+ f32 perpendicularRatio;
+ f32 yDiff = p2->y - p1->y;
+ f32 zDiff = p2->z - p1->z;
+ f32 distSq = SQ(yDiff) + SQ(zDiff);
+ f32 perpY;
+ f32 perpZ;
+ s32 ret = false;
+
+ if (IS_ZERO(distSq)) {
+ *lineLenSq = 0.0f;
+ return false;
+ }
+
+ perpendicularRatio = ((y0 - p1->y) * yDiff + (z0 - p1->z) * zDiff) / distSq;
+ if ((perpendicularRatio >= 0.0f) && (perpendicularRatio <= 1.0f)) {
+ ret = true;
+ }
+ perpY = (yDiff * perpendicularRatio) + p1->y;
+ perpZ = (zDiff * perpendicularRatio) + p1->z;
+ *lineLenSq = SQ(perpY - y0) + SQ(perpZ - z0);
+
+ return ret;
+}
+
+s32 Math3D_PointDistSqToLineZX(f32 z0, f32 x0, Vec3f* p1, Vec3f* p2, f32* lineLenSq) {
+ f32 perpendicularRatio;
+ f32 zDiff = p2->z - p1->z;
+ f32 xDiff = p2->x - p1->x;
+ f32 distSq = SQ(zDiff) + SQ(xDiff);
+ f32 perpZ;
+ f32 perpX;
+ s32 ret = false;
+
+ if (IS_ZERO(distSq)) {
+ *lineLenSq = 0.0f;
+ return false;
+ }
+
+ perpendicularRatio = ((z0 - p1->z) * zDiff + (x0 - p1->x) * xDiff) / distSq;
+ if ((perpendicularRatio >= 0.0f) && (perpendicularRatio <= 1.0f)) {
+ ret = true;
+ }
+ perpZ = (zDiff * perpendicularRatio) + p1->z;
+ perpX = (xDiff * perpendicularRatio) + p1->x;
+ *lineLenSq = SQ(perpZ - z0) + SQ(perpX - x0);
+
+ return ret;
+}
+
+/**
+ * Determines if the line `line` is touching the sphere `sphere` at any point in the line.
+ */
+s32 Math3D_LineVsSph(Sphere16* sphere, Linef* line) {
+ static Vec3f sSphLinePerpendicularPoint;
+ Vec3f lineDiff;
+ f32 temp_f0_2;
+ f32 lineLenSq;
+
+ if ((Math3D_PointInSph(sphere, &line->a)) || (Math3D_PointInSph(sphere, &line->b))) {
+ // either point of the line is in the sphere.
+ return true;
+ }
+ lineDiff.x = line->b.x - line->a.x;
+ lineDiff.y = line->b.y - line->a.y;
+ lineDiff.z = line->b.z - line->a.z;
+
+ lineLenSq = SQ(lineDiff.x) + SQ(lineDiff.y) + SQ(lineDiff.z);
+ if (IS_ZERO(lineLenSq)) {
+ // line length is "0"
+ return false;
+ }
+ temp_f0_2 = ((((sphere->center.x - line->a.x) * lineDiff.x) + ((sphere->center.y - line->a.y) * lineDiff.y)) +
+ ((sphere->center.z - line->a.z) * lineDiff.z)) /
+ lineLenSq;
+ if ((temp_f0_2 < 0.0f) || (temp_f0_2 > 1.0f)) {
+ return false;
+ }
+
+ sSphLinePerpendicularPoint.x = (lineDiff.x * temp_f0_2) + line->a.x;
+ sSphLinePerpendicularPoint.y = (lineDiff.y * temp_f0_2) + line->a.y;
+ sSphLinePerpendicularPoint.z = (lineDiff.z * temp_f0_2) + line->a.z;
+
+ if ((SQ(sSphLinePerpendicularPoint.x - sphere->center.x) + SQ(sSphLinePerpendicularPoint.y - sphere->center.y) +
+ SQ(sSphLinePerpendicularPoint.z - sphere->center.z)) <= SQ((f32)sphere->radius)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Gets the surface point of `sphere` intersecting with `tri` generated from the line formed from the
+ * sphere's surface to the midpoint of the line formed from the first two vertices of the tri
+ */
+void Math3D_GetSphVsTriIntersectPoint(Sphere16* sphere, TriNorm* tri, Vec3f* intersectPoint) {
+ static Vec3f sV0V1Center;
+ static Vec3f sSphereCenter;
+ f32 dist;
+ f32 splitRatio;
+
+ sV0V1Center.x = (tri->vtx[0].x + tri->vtx[1].x) * 0.5f;
+ sV0V1Center.y = (tri->vtx[0].y + tri->vtx[1].y) * 0.5f;
+ sV0V1Center.z = (tri->vtx[0].z + tri->vtx[1].z) * 0.5f;
+ sSphereCenter.x = sphere->center.x;
+ sSphereCenter.y = sphere->center.y;
+ sSphereCenter.z = sphere->center.z;
+ dist = Math3D_Vec3f_DistXYZ(&sV0V1Center, &sSphereCenter);
+ // Distance from the sphere's center to the center of the line formed from v0->v1
+ if (IS_ZERO(dist)) {
+ intersectPoint->x = sSphereCenter.x;
+ intersectPoint->y = sSphereCenter.y;
+ intersectPoint->z = sSphereCenter.z;
+ return;
+ }
+ splitRatio = sphere->radius / dist;
+ Math3D_LineSplitRatio(&sSphereCenter, &sV0V1Center, splitRatio, intersectPoint);
+}
+
+/**
+ * Determines if `sphere` and `tri` and touching, and outputs the intersection point to `intersectPoint`
+ */
+s32 Math3D_TriVsSphIntersect(Sphere16* sphere, TriNorm* tri, Vec3f* intersectPoint) {
+ static Linef sTriTestLine;
+ static Vec3f sSphereCenter;
+ static Vec3f sSphPlanePos;
+ f32 radius;
+ f32 nx;
+ f32 ny;
+ f32 nz;
+ f32 planeDist;
+
+ sSphereCenter.x = sphere->center.x;
+ sSphereCenter.y = sphere->center.y;
+ sSphereCenter.z = sphere->center.z;
+ radius = sphere->radius;
+
+ if (!Math3D_SphCubeVsTriCube(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], &sSphereCenter, radius)) {
+ return false;
+ }
+
+ planeDist = Math3D_UDistPlaneToPos(tri->plane.normal.x, tri->plane.normal.y, tri->plane.normal.z,
+ tri->plane.originDist, &sSphereCenter);
+ if (radius < planeDist) {
+ // the point that lies within the plane of the triangle which is perpendicular to the sphere's center is more
+ // than the radius of the sphere, the plane never crosses the sphere.
+ return false;
+ }
+
+ // tests if any of the edges of the triangle are intersecting the sphere
+ sTriTestLine.a = tri->vtx[0];
+ sTriTestLine.b = tri->vtx[1];
+ if (Math3D_LineVsSph(sphere, &sTriTestLine)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+
+ sTriTestLine.a = tri->vtx[1];
+ sTriTestLine.b = tri->vtx[2];
+ if (Math3D_LineVsSph(sphere, &sTriTestLine)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+
+ sTriTestLine.a = tri->vtx[2];
+ sTriTestLine.b = tri->vtx[0];
+ if (Math3D_LineVsSph(sphere, &sTriTestLine)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+
+ nx = tri->plane.normal.x * planeDist;
+ ny = tri->plane.normal.y * planeDist;
+ nz = tri->plane.normal.z * planeDist;
+
+ if (Math3D_PlaneF(tri->plane.normal.x, tri->plane.normal.y, tri->plane.normal.z, tri->plane.originDist,
+ &sSphereCenter) > 0.0f) {
+ sSphPlanePos.x = sSphereCenter.x - nx;
+ sSphPlanePos.y = sSphereCenter.y - ny;
+ sSphPlanePos.z = sSphereCenter.z - nz;
+ } else {
+ sSphPlanePos.x = sSphereCenter.x + nx;
+ sSphPlanePos.y = sSphereCenter.y + ny;
+ sSphPlanePos.z = sSphereCenter.z + nz;
+ }
+
+ if (fabsf(tri->plane.normal.y) > 0.5f) {
+ if (Math3D_TriChkPointParaYDeterminate(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], sSphPlanePos.z, sSphPlanePos.x,
+ 0.0f, tri->plane.normal.y)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+ } else if (fabsf(tri->plane.normal.x) > 0.5f) {
+ if (Math3D_TriChkPointParaXDeterminate(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], sSphPlanePos.y, sSphPlanePos.z,
+ 0.0f, tri->plane.normal.x)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+ } else if (Math3D_TriChkPointParaZDeterminate(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], sSphPlanePos.x,
+ sSphPlanePos.y, 0.0f, tri->plane.normal.z)) {
+ Math3D_GetSphVsTriIntersectPoint(sphere, tri, intersectPoint);
+ return true;
+ }
+ return false;
+}
+
+/*
+ * 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 = cyl->pos.x - point->x;
+ f32 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 true;
+ } else {
+ return false;
+ }
+}
+
+s32 Math3D_CylVsLineSeg(Cylinder16* cyl, Vec3f* linePointA, Vec3f* linePointB, Vec3f* intersectA, Vec3f* intersectB) {
+ Vec3f cylToPtA;
+ Vec3f cylToPtB;
+ Vec3f ptAToPtB;
+ f32 fracA;
+ f32 fracB;
+ f32 fracBase;
+ f32 zero;
+ f32 pad;
+ f32 cylRadiusSq;
+ f32 radSqDiff;
+ f32 distCent2;
+ f32 dot2AB;
+ s32 sideIntA;
+ s32 sideIntB;
+ s32 intBeyondA;
+ s32 intBeyondB;
+ s32 intFlags;
+ Vec3f intPts[4];
+ s32 count;
+ s32 i;
+
+ fracA = 0.0f;
+ fracB = 0.0f;
+
+//! FAKE:
+dummy:;
+
+ zero = 0.0f;
+ intFlags = 0;
+
+ if (Math3D_PointInCyl(cyl, linePointA) && Math3D_PointInCyl(cyl, linePointB)) {
+ // both points are in the cylinder
+ *intersectA = *linePointA;
+ *intersectB = *linePointB;
+ return 2;
+ }
+
+ cylToPtA.x = linePointA->x - cyl->pos.x;
+ cylToPtA.y = linePointA->y - cyl->pos.y - cyl->yShift;
+ cylToPtA.z = linePointA->z - cyl->pos.z;
+ cylToPtB.x = linePointB->x - cyl->pos.x;
+ cylToPtB.y = linePointB->y - cyl->pos.y - cyl->yShift;
+ cylToPtB.z = linePointB->z - cyl->pos.z;
+ Math_Vec3f_Diff(&cylToPtB, &cylToPtA, &ptAToPtB);
+ cylRadiusSq = SQ(cyl->radius);
+
+ /**
+ * This section checks for intersections with the cylinder's base and top
+ */
+ if (!IS_ZERO(ptAToPtB.y)) {
+ // fraction of length along AB to reach y = 0
+ fracBase = -cylToPtA.y / ptAToPtB.y;
+ if ((fracBase >= 0.0f) && (fracBase <= 1.0f)) {
+ f32 baseIntX = (ptAToPtB.x * fracBase) + cylToPtA.x;
+ f32 baseIntZ = (ptAToPtB.z * fracBase) + cylToPtA.z;
+
+ if ((SQ(baseIntX) + SQ(baseIntZ)) < cylRadiusSq) {
+ // adds base intersection point to intPts and sets its flag
+ intPts[0].x = cyl->pos.x + baseIntX;
+ intPts[0].y = (f32)cyl->pos.y + cyl->yShift;
+ intPts[0].z = cyl->pos.z + baseIntZ;
+ intFlags |= 1;
+ }
+ }
+ // fraction of length along AB to reach y = cyl->height
+ fracA = (cyl->height - cylToPtA.y) / ptAToPtB.y;
+ if ((fracA >= 0.0f) && (fracA <= 1.0f)) {
+ f32 topIntX = ptAToPtB.x * fracA + cylToPtA.x;
+ f32 topIntZ = ptAToPtB.z * fracA + cylToPtA.z;
+
+ if ((SQ(topIntX) + SQ(topIntZ)) < cylRadiusSq) {
+ // adds top intersection point to intPts and sets its flag
+ intPts[1].x = cyl->pos.x + topIntX;
+ intPts[1].y = (f32)cyl->pos.y + cyl->yShift + cyl->height;
+ intPts[1].z = cyl->pos.z + topIntZ;
+ intFlags |= 2;
+ }
+ }
+ }
+
+ /**
+ * This section finds the points of intersection of the infinite line containing AB with the side of the infinite
+ * cylinder containing cyl. Intersection points beyond the bounds of the segment and cylinder are filtered out
+ * afterward.
+ */
+ radSqDiff = SQXZ(cylToPtA) - cylRadiusSq;
+ if (!IS_ZERO(2.0f * SQXZ(ptAToPtB))) {
+ dot2AB = 2.0f * DOTXZ(ptAToPtB, cylToPtA);
+ if (SQ(dot2AB) < (4.0f * SQXZ(ptAToPtB) * radSqDiff)) {
+ // Line's closest xz-approach is outside cylinder. No intersections.
+ return 0;
+ }
+ if ((SQ(dot2AB) - (4.0f * SQXZ(ptAToPtB) * radSqDiff)) > zero) {
+ sideIntA = sideIntB = 1;
+ } else {
+ // Line is tangent in xz-plane. At most 1 side intersection.
+ sideIntA = 1;
+ sideIntB = 0;
+ }
+ distCent2 = sqrtf(SQ(dot2AB) - (4.0f * SQXZ(ptAToPtB) * radSqDiff));
+ if (sideIntA != 0) {
+ // fraction of length along AB for side intersection closer to A
+ fracA = (distCent2 - dot2AB) / (2.0f * SQXZ(ptAToPtB));
+ }
+ if (sideIntB != 0) {
+ // fraction of length along AB for side intersection closer to B
+ fracB = (-dot2AB - distCent2) / (2.0f * SQXZ(ptAToPtB));
+ }
+ } else if (!IS_ZERO(2.0f * DOTXZ(ptAToPtB, cylToPtA))) {
+ // Used if the line segment is nearly vertical. Unclear what it's calculating.
+ fracA = -radSqDiff / (2.0f * DOTXZ(ptAToPtB, cylToPtA));
+ sideIntA = 1;
+ sideIntB = 0;
+ } else {
+ return 0;
+ }
+
+ // checks for intersection points outside the bounds of the segment
+ if (!sideIntB) {
+ if ((fracA < 0.0f) || (fracA > 1.0f)) {
+ return 0;
+ }
+ } else {
+ intBeyondA = (fracA < 0.0f) || (fracA > 1.0f);
+ intBeyondB = (fracB < 0.0f) || (fracB > 1.0f);
+ if (intBeyondA && intBeyondB) {
+ return 0;
+ }
+ if (intBeyondA) {
+ sideIntA = 0;
+ }
+ if (intBeyondB) {
+ sideIntB = 0;
+ }
+ }
+
+ // checks for intersection points outside the bounds of the cylinder
+ if ((sideIntA != 0) &&
+ (((fracA * ptAToPtB.y + cylToPtA.y) < 0.0f) || (cyl->height < (fracA * ptAToPtB.y + cylToPtA.y)))) {
+ sideIntA = 0;
+ }
+ if ((sideIntB != 0) &&
+ (((fracB * ptAToPtB.y + cylToPtA.y) < 0.0f) || (cyl->height < (fracB * ptAToPtB.y + cylToPtA.y)))) {
+ sideIntB = 0;
+ }
+ if ((sideIntA == 0) && (sideIntB == 0)) {
+ return 0;
+ }
+
+ // Adds intersection points to intPts and sets side A and side B flags
+ if (sideIntA != 0 && sideIntB != 0) {
+ intPts[2].x = (fracA * ptAToPtB.x + cylToPtA.x) + cyl->pos.x;
+ intPts[2].y = (fracA * ptAToPtB.y + cylToPtA.y) + cyl->pos.y + cyl->yShift;
+ intPts[2].z = (fracA * ptAToPtB.z + cylToPtA.z) + cyl->pos.z;
+ intFlags |= 4;
+ intPts[3].x = (fracB * ptAToPtB.x + cylToPtA.x) + cyl->pos.x;
+ intPts[3].y = (fracB * ptAToPtB.y + cylToPtA.y) + cyl->pos.y + cyl->yShift;
+ intPts[3].z = (fracB * ptAToPtB.z + cylToPtA.z) + cyl->pos.z;
+ intFlags |= 8;
+ } else if (sideIntA != 0) {
+ intPts[2].x = (fracA * ptAToPtB.x + cylToPtA.x) + cyl->pos.x;
+ intPts[2].y = (fracA * ptAToPtB.y + cylToPtA.y) + cyl->pos.y + cyl->yShift;
+ intPts[2].z = (fracA * ptAToPtB.z + cylToPtA.z) + cyl->pos.z;
+ intFlags |= 4;
+ } else if (sideIntB != 0) {
+ intPts[2].x = (fracB * ptAToPtB.x + cylToPtA.x) + cyl->pos.x;
+ intPts[2].y = (fracB * ptAToPtB.y + cylToPtA.y) + cyl->pos.y + cyl->yShift;
+ intPts[2].z = (fracB * ptAToPtB.z + cylToPtA.z) + cyl->pos.z;
+ intFlags |= 4;
+ }
+
+ /**
+ * Places the found intersection points into intersectA and intersectB. IntersectA is always closer to point A
+ */
+ for (count = 0, i = 0; i < ARRAY_COUNT(intPts); i++) {
+ if (intFlags & (1 << i)) {
+ if (count == 0) {
+ *intersectA = intPts[i];
+ } else if (count == 1) {
+ if (Math3D_Vec3fDistSq(intersectA, linePointA) < Math3D_Vec3fDistSq(intersectA, &intPts[i])) {
+ *intersectB = intPts[i];
+ } else {
+ *intersectB = *intersectA;
+ *intersectA = intPts[i];
+ }
+ break;
+ }
+ count++;
+ }
+ }
+ return count;
+}
+
+/*
+ * 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_CylTriVsIntersect(Cylinder16* cyl, TriNorm* tri, Vec3f* intersect) {
+ static Sphere16 sTopSphere;
+ static Sphere16 sBottomSphere;
+ static Vec3f sCylIntersectA;
+ static Vec3f sCylIntersectB;
+ f32 yIntersect;
+ f32 cylTop;
+ f32 cylBottom;
+ f32 minDistSq;
+ f32 radiusTodistFromCylYIntersectTov0v1;
+ f32 distFromPointAToIntersectASq;
+ Vec3f cylIntersectCenter;
+
+ cylBottom = (f32)cyl->pos.y + cyl->yShift;
+ cylTop = cyl->height + cylBottom;
+
+ 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))) {
+ // If all of the vertices are below or all of the vertices are above the cylinder.
+ return false;
+ }
+
+ minDistSq = 1.e38f;
+ if (Math3D_CylVsLineSeg(cyl, &tri->vtx[0], &tri->vtx[1], &sCylIntersectA, &sCylIntersectB)) {
+ distFromPointAToIntersectASq = Math3D_Vec3fDistSq(&sCylIntersectA, &tri->vtx[0]);
+ minDistSq = distFromPointAToIntersectASq;
+ *intersect = sCylIntersectA;
+ }
+
+ if (Math3D_CylVsLineSeg(cyl, &tri->vtx[2], &tri->vtx[1], &sCylIntersectA, &sCylIntersectB)) {
+ distFromPointAToIntersectASq = Math3D_Vec3fDistSq(&sCylIntersectA, &tri->vtx[2]);
+ if (distFromPointAToIntersectASq < minDistSq) {
+ *intersect = sCylIntersectA;
+ minDistSq = distFromPointAToIntersectASq;
+ }
+ }
+
+ if (Math3D_CylVsLineSeg(cyl, &tri->vtx[0], &tri->vtx[2], &sCylIntersectA, &sCylIntersectB)) {
+ distFromPointAToIntersectASq = Math3D_Vec3fDistSq(&sCylIntersectA, &tri->vtx[0]);
+ if (distFromPointAToIntersectASq < minDistSq) {
+ *intersect = sCylIntersectA;
+ minDistSq = distFromPointAToIntersectASq;
+ }
+ }
+
+ if (minDistSq != 1.e38f) {
+ return true;
+ }
+
+ if (Math3D_TriChkLineSegParaYIntersect(&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, &yIntersect, cylBottom, cylTop)) {
+ Vec3f midpointv0v1;
+ Vec3f diffMidpointIntersect;
+ f32 distFromCylYIntersectTov0v1;
+ s32 pad;
+
+ cylIntersectCenter.x = cyl->pos.x;
+ cylIntersectCenter.y = yIntersect;
+ cylIntersectCenter.z = cyl->pos.z;
+
+ midpointv0v1.x = (tri->vtx[0].x + tri->vtx[1].x) * 0.5f;
+ midpointv0v1.y = (tri->vtx[0].y + tri->vtx[1].y) * 0.5f;
+ midpointv0v1.z = (tri->vtx[0].z + tri->vtx[1].z) * 0.5f;
+
+ Math_Vec3f_Diff(&midpointv0v1, &cylIntersectCenter, &diffMidpointIntersect);
+ distFromCylYIntersectTov0v1 = sqrtf(SQ(diffMidpointIntersect.x) + SQ(diffMidpointIntersect.z));
+
+ if (IS_ZERO(distFromCylYIntersectTov0v1)) {
+ Math_Vec3f_Copy(intersect, &midpointv0v1);
+ return true;
+ }
+
+ radiusTodistFromCylYIntersectTov0v1 = cyl->radius / distFromCylYIntersectTov0v1;
+ Math3D_PointOnDirectedLine(&cylIntersectCenter, &diffMidpointIntersect, radiusTodistFromCylYIntersectTov0v1,
+ intersect);
+ return true;
+ }
+
+ sTopSphere.center.x = sBottomSphere.center.x = cyl->pos.x;
+ sTopSphere.center.z = sBottomSphere.center.z = cyl->pos.z;
+ sTopSphere.center.y = cylTop;
+ sBottomSphere.center.y = cylBottom;
+ sTopSphere.radius = sBottomSphere.radius = cyl->radius;
+
+ if (Math3D_TriVsSphIntersect(&sTopSphere, tri, intersect) ||
+ Math3D_TriVsSphIntersect(&sBottomSphere, tri, intersect)) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Determines if `cyl` and `tri` are touching.
+ */
+s32 Math3D_CylVsTri(Cylinder16* cyl, TriNorm* tri) {
+ Vec3f intersect;
+
+ return Math3D_CylTriVsIntersect(cyl, tri, &intersect);
+}
+
+/*
+ * Determines if two spheres are touching.
+ */
+s32 Math3D_SphVsSph(Sphere16* sphereA, Sphere16* sphereB) {
+ f32 overlapSize;
+
+ return Math3D_SphVsSphOverlap(sphereA, sphereB, &overlapSize);
+}
+
+/*
+ * Determines if two spheres are touching. The amount that they're overlapping is placed in `overlapSize`
+ */
+s32 Math3D_SphVsSphOverlap(Sphere16* sphereA, Sphere16* sphereB, f32* overlapSize) {
+ f32 centerDist;
+
+ return Math3D_SphVsSphOverlapCenterDist(sphereA, sphereB, overlapSize, &centerDist);
+}
+
+/*
+ * Determines if two spheres are touching The distance from the centers is placed in `centerDist`,
+ * and the amount that they're overlapping is placed in `overlapSize`
+ */
+s32 Math3D_SphVsSphOverlapCenterDist(Sphere16* sphereA, Sphere16* sphereB, f32* overlapSize, 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 = sqrtf(SQ(diff.x) + SQ(diff.y) + SQ(diff.z));
+
+ *overlapSize = (((f32)sphereA->radius + (f32)sphereB->radius) - *centerDist);
+ if (*overlapSize > 0.008f) {
+ return true;
+ }
+
+ *overlapSize = 0.0f;
+ return false;
+}
+
+/**
+ * Checks if `sph` and `cyl` are touching, output the amount of xz overlap to `overlapSize`
+ */
+s32 Math3D_SphVsCylOverlap(Sphere16* sph, Cylinder16* cyl, f32* overlapSize) {
+ f32 centerDist;
+
+ return Math3D_SphVsCylOverlapCenterDist(sph, cyl, overlapSize, &centerDist);
+}
+
+/**
+ * Checks if `sph` and `cyl` are touching, output the xz distance of the centers to `centerDist`, and the amount of
+ * xz overlap to `overlapSize`
+ */
+s32 Math3D_SphVsCylOverlapCenterDist(Sphere16* sph, Cylinder16* cyl, f32* overlapSize, f32* centerDist) {
+ static Cylinderf sCylf;
+ static Spheref sSphf;
+ f32 x;
+ f32 z;
+ f32 combinedRadius;
+ f32 cylBottom;
+ f32 cylTop;
+ f32 sphBottom;
+ f32 sphTop;
+
+ if ((sph->radius <= 0) || (cyl->radius <= 0)) {
+ // either radius is 0
+ return false;
+ }
+ sSphf.center.y = sph->center.y;
+ sSphf.radius = sph->radius;
+ sCylf.pos.y = cyl->pos.y;
+ sCylf.yShift = cyl->yShift;
+ sCylf.height = cyl->height;
+ x = (f32)sph->center.x - cyl->pos.x;
+ z = (f32)sph->center.z - cyl->pos.z;
+ combinedRadius = (f32)sph->radius + cyl->radius;
+ *centerDist = sqrtf(SQ(x) + SQ(z));
+ if (combinedRadius < *centerDist) {
+ // if the combined radii is less than the distance to the centers, they cannot be touching.
+ return false;
+ }
+
+ cylBottom = (sCylf.pos.y + sCylf.yShift);
+ cylTop = cylBottom + sCylf.height;
+ sphBottom = sSphf.center.y - sSphf.radius;
+ sphTop = sSphf.center.y + sSphf.radius;
+
+ if ((sphTop >= cylBottom) && (sphBottom <= cylTop)) {
+ // if the cylinder and sphere are intersecting on the xz plane, check if they're intersecting on
+ // the y axis.
+ *overlapSize = combinedRadius - *centerDist;
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Checks if `ca` and `cb` are touching, output the amount of xz overlap to `overlapSize`
+ */
+s32 Math3D_CylVsCylOverlap(Cylinder16* ca, Cylinder16* cb, f32* overlapSize) {
+ f32 centerDist;
+
+ return Math3D_CylVsCylOverlapCenterDist(ca, cb, overlapSize, &centerDist);
+}
+
+/**
+ * Checks if `ca` and `cb` are touching, output the xz distance of the centers to `centerDist`, and the amount of
+ * xz overlap to `overlapSize`
+ */
+s32 Math3D_CylVsCylOverlapCenterDist(Cylinder16* ca, Cylinder16* cb, f32* overlapSize, f32* centerDist) {
+ static Cylinderf sCaf;
+ static Cylinderf sCbf;
+
+ Math_Vec3s_ToVec3f(&sCaf.pos, &ca->pos);
+ sCaf.radius = ca->radius;
+ sCaf.yShift = ca->yShift;
+ sCaf.height = ca->height;
+
+ Math_Vec3s_ToVec3f(&sCbf.pos, &cb->pos);
+ sCbf.radius = cb->radius;
+ sCbf.yShift = cb->yShift;
+ sCbf.height = cb->height;
+
+ *centerDist = sqrtf(SQ(sCaf.pos.x - sCbf.pos.x) + SQ(sCaf.pos.z - sCbf.pos.z));
+
+ // The combined radii are within the xz distance
+ if ((sCaf.radius + sCbf.radius) < *centerDist) {
+ return false;
+ }
+
+ // top of ca < bottom of cb or top of cb < bottom of ca
+ if ((((sCaf.pos.y + sCaf.yShift) + sCaf.height) < (sCbf.pos.y + sCbf.yShift)) ||
+ (((sCbf.pos.y + sCbf.yShift) + sCbf.height) < (sCaf.pos.y + sCaf.yShift))) {
+ return false;
+ }
+
+ *overlapSize = sCaf.radius + sCbf.radius - *centerDist;
+ return true;
+}
+
+/*
+ * Determines if triangle `ta` intersects with triangle `tb` the point of
+ * intersection is output to `intersect.
+ * Returns true is the triangles intersect, 0 otherwise
+ */
+s32 Math3D_TriVsTriIntersect(TriNorm* ta, TriNorm* tb, Vec3f* intersect) {
+ f32 dist0 = Math3D_Plane(&ta->plane, &tb->vtx[0]);
+ f32 dist1 = Math3D_Plane(&ta->plane, &tb->vtx[1]);
+ f32 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 false;
+ }
+
+ 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 false;
+ }
+
+ 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 true;
+ }
+ 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 true;
+ }
+ 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 true;
+ }
+ 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)) {
+ return true;
+ }
+ 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)) {
+ return true;
+ }
+ 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)) {
+ return true;
+ }
+ return false;
+}
+
+s32 Math3D_XZInSphere(Sphere16* sphere, f32 x, f32 z) {
+ f32 xDiff = sphere->center.x - x;
+ f32 zDiff = sphere->center.z - z;
+
+ if ((SQ(xDiff) + SQ(zDiff)) <= SQ(sphere->radius)) {
+ return true;
+ }
+ return false;
+}
+
+s32 Math3D_XYInSphere(Sphere16* sphere, f32 x, f32 y) {
+ f32 xDiff = sphere->center.x - x;
+ f32 yDiff = sphere->center.y - y;
+
+ if ((SQ(xDiff) + SQ(yDiff)) <= SQ(sphere->radius)) {
+ return true;
+ }
+ return false;
+}
+
+s32 Math3D_YZInSphere(Sphere16* sphere, f32 y, f32 z) {
+ f32 yDiff = sphere->center.y - y;
+ f32 zDiff = sphere->center.z - z;
+
+ if ((SQ(yDiff) + SQ(zDiff)) <= SQ(sphere->radius)) {
+ return true;
+ }
+ return false;
+}
+
+/**
+ * @brief Computes the intersection points, if any, of the circle of radius radius, center (centerX, centerY) with the
+ * line through the point (pointX, pointY) in direction (dirX, dirY).
+ *
+ * @param[in] centreX x coordinate of centre of circle
+ * @param[in] centerY y coordinate of centre of circle
+ * @param[in] radius of circle
+ * @param[in] pointX x coordinate of point on line
+ * @param[in] pointY y coordinate of point on line
+ * @param[in] dirX x value of direction vector of line
+ * @param[in] dirY y value of direction vecotr of line
+ * @param[out] intersectAX x coordinate of first intersection
+ * @param[out] intersectAY y coordinate of first intersection
+ * @param[out] intersectBX x coordinate of second intersection
+ * @param[out] intersectBY y coordinate of second intersection
+ * @return number of intersections(ish)
+ */
+s32 Math3D_CircleLineIntersections(f32 centreX, f32 centerY, f32 radius, f32 pointX, f32 pointY, f32 dirX, f32 dirY,
+ f32* intersectAX, f32* intersectAY, f32* intersectBX, f32* intersectBY) {
+ f32 a = SQ(dirX) + SQ(dirY); // t^2 coefficient, |dir|^2
+ f32 diffX = pointX - centreX;
+ f32 diffY = pointY - centerY;
+ f32 b; // t coefficient
+ f32 delta; // discriminant of quadratic
+ f32 rootP; // larger root of quadratic
+ f32 rootN; // smaller root of quadratic
+ s32 ret;
+
+ // if the direction vector's magnitude is too small, assume no intersections
+ if ((IS_ZERO(dirX) && IS_ZERO(dirY)) || IS_ZERO(a)) {
+ *intersectAX = 0.0f;
+ *intersectAY = 0.0f;
+ *intersectBX = 0.0f;
+ *intersectBY = 0.0f;
+ return 0;
+ }
+
+ b = 2.0f * (dirX * diffX + dirY * diffY); // 2 dir . (point - centre)
+ delta = SQ(b) - 4.0f * a * (SQ(diffX) + SQ(diffY) - SQ(radius));
+ ret = 0;
+
+ if (IS_ZERO(delta)) { // At most one root if discriminant is close to zero
+ // This root is always overwritten later.
+ rootN = -b / (2.0f * a);
+ *intersectAX = dirX * rootN + pointX;
+ *intersectAY = dirY * rootN + pointY;
+
+ *intersectBX = 0.0f;
+ *intersectBY = 0.0f;
+ }
+
+ if (delta > 0.0f) { // Two roots if discriminant > 0
+ rootN = (-b - sqrtf(delta)) / (2.0f * a);
+ *intersectAX = dirX * rootN + pointX;
+ *intersectAY = dirY * rootN + pointY;
+
+ rootP = (-b + sqrtf(delta)) / (2.0f * a);
+ *intersectBX = dirX * rootP + pointX;
+ *intersectBY = dirY * rootP + pointY;
+
+ ret = 2;
+ } else { // "No roots if discriminant <= 0.0f"*
+ //! @bug Should be one root if discriminant == 0, not zero (although this case is unlikely for floats)
+ *intersectAX = 0.0f;
+ *intersectAY = 0.0f;
+ }
+
+ return ret;
+}
+
+void func_8017FD44(Vec3f* arg0, Vec3f* arg1, Vec3f* dst, f32 arg3) {
+ Vec3f sp2C;
+ s16 sp2A;
+ f32 sp24;
+
+ if ((arg3 < -1.0f) && (arg3 > 1.0f)) {
+ return;
+ }
+
+ sp2C.x = (arg0->x + arg1->x) / 2.0f;
+ sp2C.z = (arg0->z + arg1->z) / 2.0f;
+ sp24 = sqrtf(SQ(sp2C.x - arg0->x) + SQ(sp2C.z - arg0->z));
+ dst->y = (arg1->y - arg0->y) * arg3 + arg0->y;
+ sp2A = Math_Vec3f_Yaw(&sp2C, arg0);
+ dst->x = Math_SinS(TRUNCF_BINANG(0x7FFF * arg3) + sp2A) * sp24 + sp2C.x;
+ dst->z = Math_CosS(TRUNCF_BINANG(0x7FFF * arg3) + sp2A) * sp24 + sp2C.z;
+}
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 5d31c31ac..3b6b48fda 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -4141,7 +4141,7 @@ void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3
// Find the point closest to srcPos
for (pointIndex = 0; pointIndex < numPoints; pointIndex++) {
- distSq = Math3D_XZDistanceSquared(srcPos->x, srcPos->z, points[pointIndex].x, points[pointIndex].z);
+ distSq = Math3D_Dist2DSq(srcPos->x, srcPos->z, points[pointIndex].x, points[pointIndex].z);
if (distSq < closestPointDistSq) {
closestPointDistSq = distSq;
closestPointIndex = pointIndex;
@@ -4166,8 +4166,8 @@ void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3
if ((closestPointIndex != 0) || isPathLoop) {
// Use the adjacent line
useAdjacentLines[0] =
- Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPointPrev.x, closestPointPrev.z, closestPoint.x,
- closestPoint.z, &closestPos[0].x, &closestPos[0].z, &distSq);
+ Math3D_PointDistSqToLine2DImpl(srcPos->x, srcPos->z, closestPointPrev.x, closestPointPrev.z, closestPoint.x,
+ closestPoint.z, &closestPos[0].x, &closestPos[0].z, &distSq);
}
// Analyze point on path immediately next to the closest point
@@ -4183,8 +4183,8 @@ void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3
}
if ((closestPointIndex + 1 != numPoints) || isPathLoop) {
useAdjacentLines[1] =
- Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPoint.x, closestPoint.z, closestPointNext.x,
- closestPointNext.z, &closestPos[1].x, &closestPos[1].z, &distSq);
+ Math3D_PointDistSqToLine2DImpl(srcPos->x, srcPos->z, closestPoint.x, closestPoint.z, closestPointNext.x,
+ closestPointNext.z, &closestPos[1].x, &closestPos[1].z, &distSq);
}
/**
@@ -4202,7 +4202,7 @@ void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3
for (i = 0; i < ARRAY_COUNT(loopDistSq); i++) {
if (useAdjacentLines[i]) {
// Get distSq from srcPos to closestPos
- loopDistSq[i] = Math3D_XZDistanceSquared(srcPos->x, srcPos->z, closestPos[i].x, closestPos[i].z);
+ loopDistSq[i] = Math3D_Dist2DSq(srcPos->x, srcPos->z, closestPos[i].x, closestPos[i].z);
} else {
// The closest Pos is not contained within the line-segment
loopDistSq[i] = SQ(40000.0f);
@@ -4221,9 +4221,9 @@ void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3
// srcPos is somewhere withing the bend of the path
if (!isRightSideOfAdjacentLines[0] && !isRightSideOfAdjacentLines[1]) {
// srcPos is not inside a loop
- if (!Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPos[0].x, closestPos[0].z, closestPos[1].x,
- closestPos[1].z, &dstPos->x, &dstPos->z, &distSq)) {
- // The dstPos calculated in Math3D_PointDistToLine2D was not valid.
+ if (!Math3D_PointDistSqToLine2DImpl(srcPos->x, srcPos->z, closestPos[0].x, closestPos[0].z, closestPos[1].x,
+ closestPos[1].z, &dstPos->x, &dstPos->z, &distSq)) {
+ // The dstPos calculated in Math3D_PointDistSqToLine2DImpl was not valid.
// Take the midpoint of the two closest ponits instead
dstPos->x = (closestPos[1].x + closestPos[0].x) * 0.5f;
dstPos->z = (closestPos[1].z + closestPos[0].z) * 0.5f;
diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c
index 7a4a86bcc..a73878099 100644
--- a/src/code/z_bgcheck.c
+++ b/src/code/z_bgcheck.c
@@ -355,14 +355,14 @@ s32 CollisionPoly_CheckYIntersect(CollisionPoly* poly, Vec3s* vtxList, f32 x, f3
D_801EDA18[2].y = sVerts->y;
D_801EDA18[2].z = sVerts->z;
- if (!func_8017A304(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], z, x, checkDist)) {
+ if (!Math3D_CirSquareVsTriSquareZX(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], z, x, checkDist)) {
return 0;
}
nx = COLPOLY_GET_NORMAL(poly->normal.x);
ny = COLPOLY_GET_NORMAL(poly->normal.y);
nz = COLPOLY_GET_NORMAL(poly->normal.z);
- return Math3D_TriChkPointParaYIntersectInsideTri2(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], nx, ny, nz,
- poly->dist, z, x, yIntersect, checkDist);
+ return Math3D_TriChkPointParaYNoRangeCheckIntersectInsideTri(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], nx, ny,
+ nz, poly->dist, z, x, yIntersect, checkDist);
}
s32 CollisionPoly_CheckYIntersectApprox2(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect) {
@@ -425,17 +425,17 @@ s32 CollisionPoly_LineVsPoly(BgLineVsPolyTest* a0) {
CollisionPoly_GetNormalF(a0->poly, &sPlane.normal.x, &sPlane.normal.y, &sPlane.normal.z);
CollisionPoly_GetVertices(a0->poly, a0->vtxList, sPolyVerts);
- Math3D_Lerp(a0->posA, a0->posB, planeDistA / (planeDistA - planeDistB), a0->planeIntersect);
+ Math3D_LineSplitRatio(a0->posA, a0->posB, planeDistA / (planeDistA - planeDistB), a0->planeIntersect);
if (((fabsf(sPlane.normal.x) > 0.5f) &&
- Math3D_TriChkPointParaXDist(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->y,
+ Math3D_TriChkPointParaXImpl(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->y,
a0->planeIntersect->z, 0.0f, a0->checkDist, sPlane.normal.x)) ||
((fabsf(sPlane.normal.y) > 0.5f) &&
- Math3D_TriChkPointParaYDist(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->z,
+ Math3D_TriChkPointParaYImpl(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->z,
a0->planeIntersect->x, 0.0f, a0->checkDist, sPlane.normal.y)) ||
((fabsf(sPlane.normal.z) > 0.5f) &&
- Math3D_TriChkLineSegParaZDist(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->x,
- a0->planeIntersect->y, 0.0f, a0->checkDist, sPlane.normal.z))) {
+ Math3D_TriChkPointParaZImpl(&sPolyVerts[0], &sPolyVerts[1], &sPolyVerts[2], a0->planeIntersect->x,
+ a0->planeIntersect->y, 0.0f, a0->checkDist, sPlane.normal.z))) {
return true;
}
return false;
@@ -453,7 +453,7 @@ s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center,
sSphere.center.y = center->y;
sSphere.center.z = center->z;
sSphere.radius = radius;
- return Math3D_ColSphereTri(&sSphere, &sTri, &intersect);
+ return Math3D_TriVsSphIntersect(&sSphere, &sTri, &intersect);
}
/**
@@ -3825,7 +3825,7 @@ s32 BgCheck_CheckLineAgainstDyna(CollisionContext* colCtx, u16 xpFlags, Vec3f* p
s32 pad;
s32 i;
s32 result = false;
- LineSegment line;
+ Linef line;
f32 ay;
f32 by;
diff --git a/src/code/z_camera.c b/src/code/z_camera.c
index d27639858..af7934490 100644
--- a/src/code/z_camera.c
+++ b/src/code/z_camera.c
@@ -1240,7 +1240,7 @@ s32 func_800CD44C(Camera* camera, VecGeo* diffGeo, CameraCollision* camEyeCollis
// different bgIds for at->eye[Next] and eye[Next]->at
ret = 3;
} else {
- cosEyeAt = Math3D_Parallel(&camEyeCollision->norm, &camAtCollision->norm);
+ cosEyeAt = Math3D_Cos(&camEyeCollision->norm, &camAtCollision->norm);
if (cosEyeAt < -0.5f) {
ret = 6;
} else if ((cosEyeAt > 0.5f) || (checkEye & 2)) {
@@ -1822,20 +1822,18 @@ void Camera_CalcDefaultSwing(Camera* camera, VecGeo* arg1, VecGeo* arg2, f32 arg
if (swing->unk_64 == 1) {
if (arg3 < (sp88 = OLib_Vec3fDist(at, &swing->collisionClosePoint))) {
swing->unk_64 = 0;
- } else if ((sp88 = Math3D_SignedDistanceFromPlane(swing->eyeAtColChk.norm.x, swing->eyeAtColChk.norm.y,
- swing->eyeAtColChk.norm.z, swing->eyeAtColChk.poly->dist,
- at)) > 0.0f) {
+ } else if ((sp88 = Math3D_PlaneF(swing->eyeAtColChk.norm.x, swing->eyeAtColChk.norm.y,
+ swing->eyeAtColChk.norm.z, swing->eyeAtColChk.poly->dist, at)) > 0.0f) {
swing->unk_64 = 0;
} else if ((sp88 = OLib_Vec3fDist(eye, &swing->eyeAtColChk.pos)) < 10.0f) {
swing->unk_64 = 0;
- } else if ((sp88 = Math3D_SignedDistanceFromPlane(swing->atEyeColChk.norm.x, swing->atEyeColChk.norm.y,
- swing->atEyeColChk.norm.z, swing->atEyeColChk.poly->dist,
- eye)) > 0.0f) {
+ } else if ((sp88 = Math3D_PlaneF(swing->atEyeColChk.norm.x, swing->atEyeColChk.norm.y,
+ swing->atEyeColChk.norm.z, swing->atEyeColChk.poly->dist, eye)) > 0.0f) {
swing->unk_64 = 0;
} else if (swing->atEyeColChk.norm.y > 0.50f) {
swing->unk_64 = 0;
} else {
- Math3D_AngleBetweenVectors(&camera->unk_0F0, &swing->eyeAtColChk.norm, &sp88);
+ Math3D_CosOut(&camera->unk_0F0, &swing->eyeAtColChk.norm, &sp88);
if (sp88 > 0.0f) {
swing->unk_64 = 0;
}
@@ -5415,8 +5413,8 @@ s32 Camera_Unique0(Camera* camera) {
switch (camera->animState) {
case 0:
bgCamFuncData = (BgCamFuncData*)Camera_GetBgCamOrActorCsCamFuncData(camera, camera->bgCamIndex);
- rwData->unk_1C = Camera_Vec3sToVec3f(&bgCamFuncData->pos);
- camera->eye = camera->eyeNext = rwData->unk_1C;
+ rwData->unk_1C.point = Camera_Vec3sToVec3f(&bgCamFuncData->pos);
+ camera->eye = camera->eyeNext = rwData->unk_1C.point;
rwData->unk_34 = bgCamFuncData->rot;
temp_v1 = bgCamFuncData->fov;
@@ -5447,7 +5445,7 @@ s32 Camera_Unique0(Camera* camera) {
}
rwData->unk_3A = camera->focalActor->world.rot.y;
rwData->unk_3E = 0;
- camera->eye = camera->eyeNext = rwData->unk_1C;
+ camera->eye = camera->eyeNext = rwData->unk_1C.point;
Camera_UnsetStateFlag(camera, CAM_STATE_2);
camera->animState++;
// fallthrough
@@ -5455,8 +5453,8 @@ s32 Camera_Unique0(Camera* camera) {
sp84.r = OLib_Vec3fDist(&sp8C, &camera->eye);
sp84.yaw = rwData->unk_34.y;
sp84.pitch = -rwData->unk_34.x;
- rwData->unk_28 = OLib_VecGeoToVec3f(&sp84);
- func_80179A44(&rwData->unk_1C, focalActorPosRot, &rwData->unk_0C);
+ rwData->unk_1C.dir = OLib_VecGeoToVec3f(&sp84);
+ Math3D_LineClosestToPoint(&rwData->unk_1C, &focalActorPosRot->pos, &rwData->unk_0C);
camera->at = rwData->unk_0C;
if (player->stateFlags1 & PLAYER_STATE1_20000000) {
diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c
index 11c3865e1..c3ac08936 100644
--- a/src/code/z_collision_check.c
+++ b/src/code/z_collision_check.c
@@ -17,14 +17,14 @@ Vec3f D_801EDE20;
Vec3f D_801EDE30;
TriNorm D_801EDE40;
TriNorm D_801EDE78;
-LineSegment D_801EDEB0;
+Linef D_801EDEB0;
TriNorm D_801EDEC8;
TriNorm D_801EDF00;
Vec3f D_801EDF38;
Vec3f D_801EDF48;
TriNorm D_801EDF58;
TriNorm D_801EDF90;
-LineSegment D_801EDFC8;
+Linef D_801EDFC8;
Vec3f D_801EDFE0;
Vec3f D_801EDFF0;
TriNorm D_801EE000;
@@ -631,7 +631,7 @@ s32 Collider_SetTrisElementDim(PlayState* play, TriNorm* dim, ColliderTrisElemen
*destVtx = *srcVtx;
}
- Math3D_UnitNormalVector(&src->vtx[0], &src->vtx[1], &src->vtx[2], &nx, &ny, &nz, &originDist);
+ Math3D_DefPlane(&src->vtx[0], &src->vtx[1], &src->vtx[2], &nx, &ny, &nz, &originDist);
dim->plane.normal.x = nx;
dim->plane.normal.y = ny;
@@ -1745,8 +1745,8 @@ void CollisionCheck_AC_JntSphVsJntSph(PlayState* play, CollisionCheckContext* co
continue;
}
- if (Math3D_ColSphereSphereIntersectAndDistance(&atElem->dim.worldSphere, &acElem->dim.worldSphere,
- &overlapSize, &centerDist) != 0) {
+ if (Math3D_SphVsSphOverlapCenterDist(&atElem->dim.worldSphere, &acElem->dim.worldSphere, &overlapSize,
+ &centerDist) != 0) {
f32 acToHit;
Vec3f hitPos;
Vec3f atPos;
@@ -1796,8 +1796,7 @@ void CollisionCheck_AC_JntSphVsCyl(PlayState* play, CollisionCheckContext* colCt
if (CollisionCheck_NoSharedFlags(&atElem->info, &ac->info)) {
continue;
}
- if (Math3D_ColSphereCylinderDistanceAndAmount(&atElem->dim.worldSphere, &ac->dim, &overlapSize,
- &centerDist)) {
+ if (Math3D_SphVsCylOverlapCenterDist(&atElem->dim.worldSphere, &ac->dim, &overlapSize, &centerDist)) {
Vec3f hitPos;
Vec3f atPos;
Vec3f acPos;
@@ -1846,7 +1845,7 @@ void CollisionCheck_AC_JntSphVsTris(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&atElem->info, &acElem->info)) {
continue;
}
- if (Math3D_ColSphereTri(&atElem->dim.worldSphere, &acElem->dim, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&atElem->dim.worldSphere, &acElem->dim, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -1874,8 +1873,8 @@ void CollisionCheck_AC_JntSphVsQuad(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_SkipBump(&ac->info)) {
return;
}
- Math3D_TriSetCoords(&D_801EF590, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EF5C8, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
+ Math3D_TriNorm(&D_801EF590, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
+ Math3D_TriNorm(&D_801EF5C8, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
for (sphElem = at->elements; sphElem < &at->elements[at->count]; sphElem++) {
if (CollisionCheck_SkipTouch(&sphElem->info)) {
@@ -1884,8 +1883,8 @@ void CollisionCheck_AC_JntSphVsQuad(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&sphElem->info, &ac->info)) {
continue;
}
- if (Math3D_ColSphereTri(&sphElem->dim.worldSphere, &D_801EF590, &hitPos) != 0 ||
- Math3D_ColSphereTri(&sphElem->dim.worldSphere, &D_801EF5C8, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&sphElem->dim.worldSphere, &D_801EF590, &hitPos) != 0 ||
+ Math3D_TriVsSphIntersect(&sphElem->dim.worldSphere, &D_801EF5C8, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -1921,8 +1920,8 @@ void CollisionCheck_AC_JntSphVsSphere(PlayState* play, CollisionCheckContext* co
if (CollisionCheck_NoSharedFlags(&sphElem->info, &ac->info)) {
continue;
}
- if (Math3D_ColSphereSphereIntersectAndDistance(&sphElem->dim.worldSphere, &ac->dim.worldSphere,
- &overlapSize, &centerDist) != 0) {
+ if (Math3D_SphVsSphOverlapCenterDist(&sphElem->dim.worldSphere, &ac->dim.worldSphere, &overlapSize,
+ &centerDist) != 0) {
f32 acToHit;
Vec3f hitPos;
Vec3f atPos;
@@ -1966,8 +1965,7 @@ void CollisionCheck_AC_CylVsJntSph(PlayState* play, CollisionCheckContext* colCt
if (CollisionCheck_NoSharedFlags(&at->info, &sphElem->info)) {
continue;
}
- if (Math3D_ColSphereCylinderDistanceAndAmount(&sphElem->dim.worldSphere, &at->dim, &overlapSize,
- &centerDist) != 0) {
+ if (Math3D_SphVsCylOverlapCenterDist(&sphElem->dim.worldSphere, &at->dim, &overlapSize, &centerDist) != 0) {
Vec3f hitPos;
Vec3f atPos;
Vec3f acPos;
@@ -2017,7 +2015,7 @@ void CollisionCheck_AC_CylVsCyl(PlayState* play, CollisionCheckContext* colCtxt,
return;
}
- if (Math3D_ColCylinderCylinderAmountAndDistance(&at->dim, &ac->dim, &overlapSize, &centerDist) != 0) {
+ if (Math3D_CylVsCylOverlapCenterDist(&at->dim, &ac->dim, &overlapSize, &centerDist) != 0) {
Vec3f hitPos;
Vec3f atPos;
Vec3f acPos;
@@ -2071,7 +2069,7 @@ void CollisionCheck_AC_CylVsTris(PlayState* play, CollisionCheckContext* colCtxt
continue;
}
- if (Math3D_ColCylinderTri(&at->dim, &acElem->dim, &hitPos) != 0) {
+ if (Math3D_CylTriVsIntersect(&at->dim, &acElem->dim, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2101,17 +2099,17 @@ void CollisionCheck_AC_CylVsQuad(PlayState* play, CollisionCheckContext* colCtxt
if (CollisionCheck_NoSharedFlags(&at->info, &ac->info)) {
return;
}
- Math3D_TriSetCoords(&D_801EF600, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EF638, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
+ Math3D_TriNorm(&D_801EF600, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
+ Math3D_TriNorm(&D_801EF638, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
- if (Math3D_ColCylinderTri(&at->dim, &D_801EF600, &D_801EDE00) != 0) {
+ if (Math3D_CylTriVsIntersect(&at->dim, &D_801EF600, &D_801EDE00) != 0) {
Vec3f atPos;
Vec3f acPos;
Math_Vec3s_ToVec3f(&atPos, &at->dim.pos);
CollisionCheck_QuadAvgPoint(ac, &acPos);
CollisionCheck_SetATvsAC(play, &at->base, &at->info, &atPos, &ac->base, &ac->info, &acPos, &D_801EDE00);
- } else if (Math3D_ColCylinderTri(&at->dim, &D_801EF638, &D_801EDE00) != 0) {
+ } else if (Math3D_CylTriVsIntersect(&at->dim, &D_801EF638, &D_801EDE00) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2142,7 +2140,7 @@ void CollisionCheck_AC_CylVsSphere(PlayState* play, CollisionCheckContext* colCt
return;
}
- if (Math3D_ColSphereCylinderDistanceAndAmount(&ac->dim.worldSphere, &at->dim, &overlapSize, &centerDist) != 0) {
+ if (Math3D_SphVsCylOverlapCenterDist(&ac->dim.worldSphere, &at->dim, &overlapSize, &centerDist) != 0) {
Vec3f hitPos;
Vec3f atPos;
Vec3f acPos;
@@ -2190,7 +2188,7 @@ void CollisionCheck_AC_TrisVsJntSph(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&atElem->info, &acElem->info)) {
continue;
}
- if (Math3D_ColSphereTri(&acElem->dim.worldSphere, &atElem->dim, &hitPos)) {
+ if (Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &atElem->dim, &hitPos)) {
Vec3f atPos;
Vec3f acPos;
@@ -2227,7 +2225,7 @@ void CollisionCheck_AC_TrisVsCyl(PlayState* play, CollisionCheckContext* colCtxt
if (CollisionCheck_NoSharedFlags(&atElem->info, &ac->info)) {
continue;
}
- if (Math3D_ColCylinderTri(&ac->dim, &atElem->dim, &D_801EDE10) != 0) {
+ if (Math3D_CylTriVsIntersect(&ac->dim, &atElem->dim, &D_801EDE10) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2262,7 +2260,7 @@ void CollisionCheck_AC_TrisVsTris(PlayState* play, CollisionCheckContext* colCtx
if (CollisionCheck_NoSharedFlags(&atElem->info, &acElem->info)) {
continue;
}
- if (Math3d_ColTriTri(&atElem->dim, &acElem->dim, &D_801EDE20) != 0) {
+ if (Math3D_TriVsTriIntersect(&atElem->dim, &acElem->dim, &D_801EDE20) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2290,8 +2288,8 @@ void CollisionCheck_AC_TrisVsQuad(PlayState* play, CollisionCheckContext* colCtx
return;
}
- Math3D_TriSetCoords(&D_801EDE40, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EDE78, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
+ Math3D_TriNorm(&D_801EDE40, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
+ Math3D_TriNorm(&D_801EDE78, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
for (atElem = at->elements; atElem < &at->elements[at->count]; atElem++) {
if (CollisionCheck_SkipTouch(&atElem->info)) {
@@ -2300,8 +2298,8 @@ void CollisionCheck_AC_TrisVsQuad(PlayState* play, CollisionCheckContext* colCtx
if (CollisionCheck_NoSharedFlags(&atElem->info, &ac->info)) {
continue;
}
- if (Math3d_ColTriTri(&D_801EDE40, &atElem->dim, &D_801EDE30) != 0 ||
- Math3d_ColTriTri(&D_801EDE78, &atElem->dim, &D_801EDE30) != 0) {
+ if (Math3D_TriVsTriIntersect(&D_801EDE40, &atElem->dim, &D_801EDE30) != 0 ||
+ Math3D_TriVsTriIntersect(&D_801EDE78, &atElem->dim, &D_801EDE30) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2335,7 +2333,7 @@ void CollisionCheck_AC_TrisVsSphere(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&atElem->info, &ac->info)) {
continue;
}
- if (Math3D_ColSphereTri(&ac->dim.worldSphere, &atElem->dim, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&ac->dim.worldSphere, &atElem->dim, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2360,8 +2358,8 @@ void CollisionCheck_AC_QuadVsJntSph(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_SkipTouch(&at->info)) {
return;
}
- Math3D_TriSetCoords(&D_801EDEC8, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EDF00, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
+ Math3D_TriNorm(&D_801EDEC8, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
+ Math3D_TriNorm(&D_801EDF00, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
for (acElem = ac->elements; acElem < &ac->elements[ac->count]; acElem++) {
if (CollisionCheck_SkipBump(&acElem->info)) {
@@ -2370,8 +2368,8 @@ void CollisionCheck_AC_QuadVsJntSph(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info)) {
continue;
}
- if (Math3D_ColSphereTri(&acElem->dim.worldSphere, &D_801EDEC8, &hitPos) != 0 ||
- Math3D_ColSphereTri(&acElem->dim.worldSphere, &D_801EDF00, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &D_801EDEC8, &hitPos) != 0 ||
+ Math3D_TriVsSphIntersect(&acElem->dim.worldSphere, &D_801EDF00, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2408,10 +2406,10 @@ void CollisionCheck_AC_QuadVsCyl(PlayState* play, CollisionCheckContext* colCtxt
return;
}
- Math3D_TriSetCoords(&D_801EDF58, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EDF90, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
+ Math3D_TriNorm(&D_801EDF58, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
+ Math3D_TriNorm(&D_801EDF90, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
- if (Math3D_ColCylinderTri(&ac->dim, &D_801EDF58, &D_801EDFE0) != 0) {
+ if (Math3D_CylTriVsIntersect(&ac->dim, &D_801EDF58, &D_801EDFE0) != 0) {
if (Collider_QuadSetNearestAC(play, at, &D_801EDFE0)) {
Vec3f atPos;
Vec3f acPos;
@@ -2422,7 +2420,7 @@ void CollisionCheck_AC_QuadVsCyl(PlayState* play, CollisionCheckContext* colCtxt
return;
}
}
- if (Math3D_ColCylinderTri(&ac->dim, &D_801EDF90, &D_801EDFE0) != 0) {
+ if (Math3D_CylTriVsIntersect(&ac->dim, &D_801EDF90, &D_801EDFE0) != 0) {
if (Collider_QuadSetNearestAC(play, at, &D_801EDFE0)) {
Vec3f atPos;
Vec3f acPos;
@@ -2448,8 +2446,8 @@ void CollisionCheck_AC_QuadVsTris(PlayState* play, CollisionCheckContext* colCtx
return;
}
- Math3D_TriSetCoords(&D_801EE000, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EE038, &at->dim.quad[1], &at->dim.quad[0], &at->dim.quad[2]);
+ Math3D_TriNorm(&D_801EE000, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
+ Math3D_TriNorm(&D_801EE038, &at->dim.quad[1], &at->dim.quad[0], &at->dim.quad[2]);
for (acElem = ac->elements; acElem < &ac->elements[ac->count]; acElem++) {
if (CollisionCheck_SkipBump(&acElem->info)) {
@@ -2459,8 +2457,8 @@ void CollisionCheck_AC_QuadVsTris(PlayState* play, CollisionCheckContext* colCtx
continue;
}
- if ((Math3d_ColTriTri(&D_801EE000, &acElem->dim, &D_801EDFF0) != 0) ||
- (Math3d_ColTriTri(&D_801EE038, &acElem->dim, &D_801EDFF0) != 0)) {
+ if ((Math3D_TriVsTriIntersect(&D_801EE000, &acElem->dim, &D_801EDFF0) != 0) ||
+ (Math3D_TriVsTriIntersect(&D_801EE038, &acElem->dim, &D_801EDFF0) != 0)) {
if (Collider_QuadSetNearestAC(play, at, &D_801EDFF0)) {
Vec3f atPos;
Vec3f acPos;
@@ -2495,14 +2493,14 @@ void CollisionCheck_AC_QuadVsQuad(PlayState* play, CollisionCheckContext* colCtx
return;
}
- Math3D_TriSetCoords(&D_801EE0E8[0], &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EE0E8[1], &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
- Math3D_TriSetCoords(&D_801EE070[0], &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EE070[1], &ac->dim.quad[2], &ac->dim.quad[1], &ac->dim.quad[0]);
+ Math3D_TriNorm(&D_801EE0E8[0], &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
+ Math3D_TriNorm(&D_801EE0E8[1], &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
+ Math3D_TriNorm(&D_801EE070[0], &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
+ Math3D_TriNorm(&D_801EE070[1], &ac->dim.quad[2], &ac->dim.quad[1], &ac->dim.quad[0]);
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
- if (Math3d_ColTriTri(&D_801EE0E8[j], &D_801EE070[i], &D_801EE0D8) != 0 &&
+ if (Math3D_TriVsTriIntersect(&D_801EE0E8[j], &D_801EE070[i], &D_801EE0D8) != 0 &&
Collider_QuadSetNearestAC(play, at, &D_801EE0D8) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2531,11 +2529,11 @@ void CollisionCheck_AC_QuadVsSphere(PlayState* play, CollisionCheckContext* colC
return;
}
- Math3D_TriSetCoords(&D_801EE150, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EE188, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
+ Math3D_TriNorm(&D_801EE150, &at->dim.quad[2], &at->dim.quad[3], &at->dim.quad[1]);
+ Math3D_TriNorm(&D_801EE188, &at->dim.quad[2], &at->dim.quad[1], &at->dim.quad[0]);
- if ((Math3D_ColSphereTri(&ac->dim.worldSphere, &D_801EE150, &hitPos) != 0) ||
- (Math3D_ColSphereTri(&ac->dim.worldSphere, &D_801EE188, &hitPos) != 0)) {
+ if ((Math3D_TriVsSphIntersect(&ac->dim.worldSphere, &D_801EE150, &hitPos) != 0) ||
+ (Math3D_TriVsSphIntersect(&ac->dim.worldSphere, &D_801EE188, &hitPos) != 0)) {
if (Collider_QuadSetNearestAC(play, at, &hitPos)) {
Vec3f atPos;
Vec3f acPos;
@@ -2571,8 +2569,8 @@ void CollisionCheck_AC_SphereVsJntSph(PlayState* play, CollisionCheckContext* co
continue;
}
- if (Math3D_ColSphereSphereIntersectAndDistance(&at->dim.worldSphere, &acElem->dim.worldSphere, &overlapSize,
- &centerDist) != 0) {
+ if (Math3D_SphVsSphOverlapCenterDist(&at->dim.worldSphere, &acElem->dim.worldSphere, &overlapSize,
+ &centerDist) != 0) {
f32 acToHit;
Vec3f hitPos;
Vec3f atPos;
@@ -2614,7 +2612,7 @@ void CollisionCheck_AC_SphereVsCylinder(PlayState* play, CollisionCheckContext*
return;
}
- if (Math3D_ColSphereCylinderDistanceAndAmount(&at->dim.worldSphere, &ac->dim, &overlapSize, &centerDist) != 0) {
+ if (Math3D_SphVsCylOverlapCenterDist(&at->dim.worldSphere, &ac->dim, &overlapSize, &centerDist) != 0) {
Vec3f hitPos;
Vec3f atPos;
Vec3f acPos;
@@ -2661,7 +2659,7 @@ void CollisionCheck_AC_SphereVsTris(PlayState* play, CollisionCheckContext* colC
if (CollisionCheck_NoSharedFlags(&at->info, &acElem->info)) {
continue;
}
- if (Math3D_ColSphereTri(&at->dim.worldSphere, &acElem->dim, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&at->dim.worldSphere, &acElem->dim, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2688,11 +2686,11 @@ void CollisionCheck_AC_SphereVsQuad(PlayState* play, CollisionCheckContext* colC
return;
}
- Math3D_TriSetCoords(&D_801EE6C8, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
- Math3D_TriSetCoords(&D_801EE700, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
+ Math3D_TriNorm(&D_801EE6C8, &ac->dim.quad[2], &ac->dim.quad[3], &ac->dim.quad[1]);
+ Math3D_TriNorm(&D_801EE700, &ac->dim.quad[1], &ac->dim.quad[0], &ac->dim.quad[2]);
- if (Math3D_ColSphereTri(&at->dim.worldSphere, &D_801EE6C8, &hitPos) != 0 ||
- Math3D_ColSphereTri(&at->dim.worldSphere, &D_801EE700, &hitPos) != 0) {
+ if (Math3D_TriVsSphIntersect(&at->dim.worldSphere, &D_801EE6C8, &hitPos) != 0 ||
+ Math3D_TriVsSphIntersect(&at->dim.worldSphere, &D_801EE700, &hitPos) != 0) {
Vec3f atPos;
Vec3f acPos;
@@ -2722,8 +2720,7 @@ void CollisionCheck_AC_SphereVsSphere(PlayState* play, CollisionCheckContext* co
return;
}
- if (Math3D_ColSphereSphereIntersectAndDistance(&at->dim.worldSphere, &ac->dim.worldSphere, &overlapSize,
- &centerDist) != 0) {
+ if (Math3D_SphVsSphOverlapCenterDist(&at->dim.worldSphere, &ac->dim.worldSphere, &overlapSize, &centerDist) != 0) {
f32 acToHit;
Vec3f hitPos;
Vec3f atPos;
@@ -2940,8 +2937,8 @@ s32 CollisionCheck_GetMassType(u8 mass) {
* also performs an elastic collision where both colliders are moved apart in proportion to their masses.
*/
void CollisionCheck_SetOCvsOC(PlayState* play, Collider* left, ColliderInfo* leftInfo, Vec3f* leftPos, Collider* right,
- ColliderInfo* rightInfo, Vec3f* rightPos, f32 overlap) {
- s32 pad;
+ ColliderInfo* rightInfo, Vec3f* rightPos, f32 overlapSize) {
+ f32 pad;
f32 leftDispRatio;
f32 rightDispRatio;
f32 xzDist;
@@ -3020,15 +3017,15 @@ void CollisionCheck_SetOCvsOC(PlayState* play, Collider* left, ColliderInfo* lef
}
if (!IS_ZERO(xzDist)) {
- xDelta *= overlap / xzDist;
- zDelta *= overlap / xzDist;
+ xDelta *= overlapSize / xzDist;
+ zDelta *= overlapSize / xzDist;
leftActor->colChkInfo.displacement.x += -xDelta * leftDispRatio;
leftActor->colChkInfo.displacement.z += -zDelta * leftDispRatio;
rightActor->colChkInfo.displacement.x += xDelta * rightDispRatio;
rightActor->colChkInfo.displacement.z += zDelta * rightDispRatio;
- } else if (overlap != 0.0f) {
- leftActor->colChkInfo.displacement.x += -overlap * leftDispRatio;
- rightActor->colChkInfo.displacement.x += overlap * rightDispRatio;
+ } else if (overlapSize != 0.0f) {
+ leftActor->colChkInfo.displacement.x += -overlapSize * leftDispRatio;
+ rightActor->colChkInfo.displacement.x += overlapSize * rightDispRatio;
} else {
leftActor->colChkInfo.displacement.x += -leftDispRatio;
rightActor->colChkInfo.displacement.x += rightDispRatio;
@@ -3043,7 +3040,7 @@ void CollisionCheck_OC_JntSphVsJntSph(PlayState* play, CollisionCheckContext* co
ColliderJntSph* right = (ColliderJntSph*)r;
ColliderJntSphElement* leftElem;
ColliderJntSphElement* rightElem;
- f32 overlap;
+ f32 overlapSize;
if ((left->count > 0) && (left->elements != NULL) && (right->count > 0) && (right->elements != NULL) &&
(left->base.ocFlags1 & OCELEM_ON) && (right->base.ocFlags1 & OCELEM_ON)) {
@@ -3056,15 +3053,15 @@ void CollisionCheck_OC_JntSphVsJntSph(PlayState* play, CollisionCheckContext* co
if (!(rightElem->info.ocElemFlags & OCELEM_ON)) {
continue;
}
- if (Math3D_ColSphereSphereIntersect(&leftElem->dim.worldSphere, &rightElem->dim.worldSphere,
- &overlap) != 0) {
+ if (Math3D_SphVsSphOverlap(&leftElem->dim.worldSphere, &rightElem->dim.worldSphere, &overlapSize) !=
+ 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &leftElem->dim.worldSphere.center);
Math_Vec3s_ToVec3f(&rightPos, &rightElem->dim.worldSphere.center);
CollisionCheck_SetOCvsOC(play, &left->base, &leftElem->info, &leftPos, &right->base,
- &rightElem->info, &rightPos, overlap);
+ &rightElem->info, &rightPos, overlapSize);
}
}
}
@@ -3078,7 +3075,7 @@ void CollisionCheck_OC_JntSphVsCyl(PlayState* play, CollisionCheckContext* colCt
ColliderJntSph* left = (ColliderJntSph*)l;
ColliderCylinder* right = (ColliderCylinder*)r;
ColliderJntSphElement* leftElem;
- f32 overlap;
+ f32 overlapSize;
if ((left->count > 0) && (left->elements != NULL) && (left->base.ocFlags1 & OCELEM_ON) &&
(right->base.ocFlags1 & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) {
@@ -3087,14 +3084,14 @@ void CollisionCheck_OC_JntSphVsCyl(PlayState* play, CollisionCheckContext* colCt
if (!(leftElem->info.ocElemFlags & OCELEM_ON)) {
continue;
}
- if (Math3D_ColSphereCylinderDistance(&leftElem->dim.worldSphere, &right->dim, &overlap) != 0) {
+ if (Math3D_SphVsCylOverlap(&leftElem->dim.worldSphere, &right->dim, &overlapSize) != 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &leftElem->dim.worldSphere.center);
Math_Vec3s_ToVec3f(&rightPos, &right->dim.pos);
CollisionCheck_SetOCvsOC(play, &left->base, &leftElem->info, &leftPos, &right->base, &right->info,
- &rightPos, overlap);
+ &rightPos, overlapSize);
}
}
}
@@ -3107,7 +3104,7 @@ void CollisionCheck_OC_JntSphVsSphere(PlayState* play, CollisionCheckContext* co
ColliderJntSph* left = (ColliderJntSph*)l;
ColliderSphere* right = (ColliderSphere*)r;
ColliderJntSphElement* leftElem;
- f32 overlap;
+ f32 overlapSize;
if ((left->count > 0) && (left->elements != NULL) && (left->base.ocFlags1 & OCELEM_ON) &&
(right->base.ocFlags1 & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) {
@@ -3116,14 +3113,14 @@ void CollisionCheck_OC_JntSphVsSphere(PlayState* play, CollisionCheckContext* co
if (!(leftElem->info.ocElemFlags & OCELEM_ON)) {
continue;
}
- if (Math3D_ColSphereSphereIntersect(&leftElem->dim.worldSphere, &right->dim.worldSphere, &overlap) != 0) {
+ if (Math3D_SphVsSphOverlap(&leftElem->dim.worldSphere, &right->dim.worldSphere, &overlapSize) != 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &leftElem->dim.worldSphere.center);
Math_Vec3s_ToVec3f(&rightPos, &right->dim.worldSphere.center);
CollisionCheck_SetOCvsOC(play, &left->base, &leftElem->info, &leftPos, &right->base, &right->info,
- &rightPos, overlap);
+ &rightPos, overlapSize);
}
}
}
@@ -3142,18 +3139,18 @@ void CollisionCheck_OC_CylVsJntSph(PlayState* play, CollisionCheckContext* colCt
void CollisionCheck_OC_CylVsCyl(PlayState* play, CollisionCheckContext* colCtxt, Collider* l, Collider* r) {
ColliderCylinder* left = (ColliderCylinder*)l;
ColliderCylinder* right = (ColliderCylinder*)r;
- f32 overlap;
+ f32 overlapSize;
if ((left->base.ocFlags1 & OCELEM_ON) && (right->base.ocFlags1 & OCELEM_ON) &&
(left->info.ocElemFlags & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) {
- if (Math3D_ColCylinderCylinderAmount(&left->dim, &right->dim, &overlap) != 0) {
+ if (Math3D_CylVsCylOverlap(&left->dim, &right->dim, &overlapSize) != 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &left->dim.pos);
Math_Vec3s_ToVec3f(&rightPos, &right->dim.pos);
CollisionCheck_SetOCvsOC(play, &left->base, &left->info, &leftPos, &right->base, &right->info, &rightPos,
- overlap);
+ overlapSize);
}
}
}
@@ -3164,18 +3161,18 @@ void CollisionCheck_OC_CylVsCyl(PlayState* play, CollisionCheckContext* colCtxt,
void CollisionCheck_OC_CylVsSphere(PlayState* play, CollisionCheckContext* colCtxt, Collider* l, Collider* r) {
ColliderCylinder* left = (ColliderCylinder*)l;
ColliderSphere* right = (ColliderSphere*)r;
- f32 overlap;
+ f32 overlapSize;
if ((left->base.ocFlags1 & OCELEM_ON) && (left->info.ocElemFlags & OCELEM_ON) &&
(right->base.ocFlags1 & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) {
- if (Math3D_ColSphereCylinderDistance(&right->dim.worldSphere, &left->dim, &overlap) != 0) {
+ if (Math3D_SphVsCylOverlap(&right->dim.worldSphere, &left->dim, &overlapSize) != 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &left->dim.pos);
Math_Vec3s_ToVec3f(&rightPos, &right->dim.worldSphere.center);
CollisionCheck_SetOCvsOC(play, &left->base, &left->info, &leftPos, &right->base, &right->info, &rightPos,
- overlap);
+ overlapSize);
}
}
}
@@ -3200,18 +3197,18 @@ void CollisionCheck_OC_SphereVsCyl(PlayState* play, CollisionCheckContext* colCt
void CollisionCheck_OC_SphereVsSphere(PlayState* play, CollisionCheckContext* colCtxt, Collider* l, Collider* r) {
ColliderSphere* left = (ColliderSphere*)l;
ColliderSphere* right = (ColliderSphere*)r;
- f32 overlap;
+ f32 overlapSize;
if ((left->base.ocFlags1 & OCELEM_ON) && (left->info.ocElemFlags & OCELEM_ON) &&
(right->base.ocFlags1 & OCELEM_ON) && (right->info.ocElemFlags & OCELEM_ON)) {
- if (Math3D_ColSphereSphereIntersect(&left->dim.worldSphere, &right->dim.worldSphere, &overlap) != 0) {
+ if (Math3D_SphVsSphOverlap(&left->dim.worldSphere, &right->dim.worldSphere, &overlapSize) != 0) {
Vec3f leftPos;
Vec3f rightPos;
Math_Vec3s_ToVec3f(&leftPos, &left->dim.worldSphere.center);
Math_Vec3s_ToVec3f(&rightPos, &right->dim.worldSphere.center);
CollisionCheck_SetOCvsOC(play, &left->base, &left->info, &leftPos, &right->base, &right->info, &rightPos,
- overlap);
+ overlapSize);
}
}
}
@@ -3509,7 +3506,7 @@ s32 CollisionCheck_LineOC_Cyl(PlayState* play, CollisionCheckContext* colChkCtx,
return 0;
}
- if (func_8017E350(&cylinder->dim, a, b, &D_801EDF38, &D_801EDF48) != 0) {
+ if (Math3D_CylVsLineSeg(&cylinder->dim, a, b, &D_801EDF38, &D_801EDF48) != 0) {
return 1;
}
@@ -3640,7 +3637,7 @@ void Collider_SetTrisVertices(ColliderTris* collider, s32 index, Vec3f* a, Vec3f
Math_Vec3f_Copy(&element->dim.vtx[0], a);
Math_Vec3f_Copy(&element->dim.vtx[1], b);
Math_Vec3f_Copy(&element->dim.vtx[2], c);
- Math3D_UnitNormalVector(a, b, c, &nx, &ny, &nz, &originDist);
+ Math3D_DefPlane(a, b, c, &nx, &ny, &nz, &originDist);
element->dim.plane.normal.x = nx;
element->dim.plane.normal.y = ny;
element->dim.plane.normal.z = nz;
diff --git a/src/code/z_eff_blure.c b/src/code/z_eff_blure.c
index 22dab6432..c9fc940b7 100644
--- a/src/code/z_eff_blure.c
+++ b/src/code/z_eff_blure.c
@@ -286,8 +286,8 @@ void EffectBlure_UpdateFlags(EffectBlureElement* elem) {
Math_Vec3s_DiffToVec3f(&sp4C, &next->p1, &elem->p1);
Math_Vec3s_DiffToVec3f(&sp40, &next->p2, &elem->p2);
- if (Math3D_AngleBetweenVectors(&sp64, &sp4C, &sp34) || Math3D_AngleBetweenVectors(&sp58, &sp40, &sp30) ||
- Math3D_AngleBetweenVectors(&sp4C, &sp40, &sp2C)) {
+ if (Math3D_CosOut(&sp64, &sp4C, &sp34) || Math3D_CosOut(&sp58, &sp40, &sp30) ||
+ Math3D_CosOut(&sp4C, &sp40, &sp2C)) {
elem->flags &= ~(EFFECT_BLURE_ELEMENT_FLAG_1 | EFFECT_BLURE_ELEMENT_FLAG_2);
elem->flags |= 0;
} else if ((sp34 <= -0.5f) || (sp30 <= -0.5f) || (sp2C <= 0.7071f)) {
diff --git a/src/code/z_eff_tire_mark.c b/src/code/z_eff_tire_mark.c
index bbcad604e..41e806a6c 100644
--- a/src/code/z_eff_tire_mark.c
+++ b/src/code/z_eff_tire_mark.c
@@ -59,8 +59,8 @@ void func_800AE930(CollisionContext* colCtx, EffectTireMark* this, Vec3f* pos, f
sp48.y = spB8.y;
sp48.z = spB8.z;
- if ((func_80179798(&sp84, &sp90, &sp54, &sp60, &sp6C, &sp30) != 0) &&
- (func_80179798(&sp84, &sp90, &sp3C, &sp48, &sp78, &sp30) != 0)) {
+ if (Math3D_LineSegMakePerpLineSeg(&sp84, &sp90, &sp54, &sp60, &sp6C, &sp30) &&
+ Math3D_LineSegMakePerpLineSeg(&sp84, &sp90, &sp3C, &sp48, &sp78, &sp30)) {
if (!(spAC->flags & EFFECT_TIRE_MARK_ELEMENT_FLAG_2)) {
spAC->flags |= EFFECT_TIRE_MARK_ELEMENT_FLAG_1;
}
diff --git a/src/code/z_fbdemo.c b/src/code/z_fbdemo.c
index 2f1ecdb54..b77e37745 100644
--- a/src/code/z_fbdemo.c
+++ b/src/code/z_fbdemo.c
@@ -15,6 +15,7 @@
#include "libc64/sleep.h"
#include "libc64/malloc.h"
#include "macros.h"
+#include "z64math.h"
Gfx sTransTileSetupDL[] = {
gsDPPipeSync(),
diff --git a/src/code/z_fireobj.c b/src/code/z_fireobj.c
index 9c69fb6a0..8f75a4d3e 100644
--- a/src/code/z_fireobj.c
+++ b/src/code/z_fireobj.c
@@ -114,7 +114,7 @@ void FireObj_UpdateStateTransitions(PlayState* play, FireObj* fire) {
}
if ((fire->flags & FIRE_FLAG_INTERACT_STICK) && (player->heldItemAction == PLAYER_IA_DEKU_STICK)) {
Math_Vec3f_Diff(&player->meleeWeaponInfo[0].tip, &fire->position, &dist);
- if (Math3D_LengthSquared(&dist) < SQ(20.0f)) {
+ if (Math3D_Vec3fMagnitudeSq(&dist) < SQ(20.0f)) {
sp40 = true;
}
}
diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c
index bdfb36183..7e88e81d0 100644
--- a/src/code/z_kankyo.c
+++ b/src/code/z_kankyo.c
@@ -1880,7 +1880,7 @@ void Environment_DrawLensFlare(PlayState* play, EnvironmentContext* envCtx, View
OPEN_DISPS(gfxCtx);
- dist = Math3D_Distance(&pos, &view->eye) / 12.0f;
+ dist = Math3D_Vec3f_DistXYZ(&pos, &view->eye) / 12.0f;
// compute a unit vector in the look direction
tempX = view->at.x - view->eye.x;
diff --git a/src/code/z_play.c b/src/code/z_play.c
index 61582ca0b..085f7f8a0 100644
--- a/src/code/z_play.c
+++ b/src/code/z_play.c
@@ -1681,7 +1681,7 @@ s32 Play_SetCameraAtEye(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye) {
successfullySet <<= 1;
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_EYE, eye);
- camera->dist = Math3D_Distance(at, eye);
+ camera->dist = Math3D_Vec3f_DistXYZ(at, eye);
if (camera->focalActor != NULL) {
camera->focalActorAtOffset.x = at->x - camera->focalActor->world.pos.x;
@@ -1710,7 +1710,7 @@ s32 Play_SetCameraAtEyeUp(PlayState* this, s16 camId, Vec3f* at, Vec3f* eye, Vec
successfullySet <<= 1;
successfullySet |= Camera_SetViewParam(camera, CAM_VIEW_UP, up);
- camera->dist = Math3D_Distance(at, eye);
+ camera->dist = Math3D_Vec3f_DistXYZ(at, eye);
if (camera->focalActor != NULL) {
camera->focalActorAtOffset.x = at->x - camera->focalActor->world.pos.x;
diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c
index 11f97c7d0..a7e4adfc8 100644
--- a/src/code/z_sub_s.c
+++ b/src/code/z_sub_s.c
@@ -578,7 +578,7 @@ s32 SubS_HasReachedPoint(Actor* actor, Path* path, s32 pointIndex) {
diffZ = points[index + 1].z - points[index - 1].z;
}
- func_8017B7F8(&point, RAD_TO_BINANG(Math_FAtan2F(diffX, diffZ)), &px, &pz, &d);
+ Math3D_RotateXZPlane(&point, RAD_TO_BINANG(Math_FAtan2F(diffX, diffZ)), &px, &pz, &d);
if (((px * actor->world.pos.x) + (pz * actor->world.pos.z) + d) > 0.0f) {
reached = true;
@@ -1328,8 +1328,8 @@ void SubS_ActorPathing_ComputePointInfo(PlayState* play, ActorPathing* actorPath
diff.x = actorPath->curPoint.x - actorPath->worldPos->x;
diff.y = actorPath->curPoint.y - actorPath->worldPos->y;
diff.z = actorPath->curPoint.z - actorPath->worldPos->z;
- actorPath->distSqToCurPointXZ = Math3D_XZLengthSquared(diff.x, diff.z);
- actorPath->distSqToCurPoint = Math3D_LengthSquared(&diff);
+ actorPath->distSqToCurPointXZ = Math3D_Dist1DSq(diff.x, diff.z);
+ actorPath->distSqToCurPoint = Math3D_Vec3fMagnitudeSq(&diff);
actorPath->rotToCurPoint.y = Math_Atan2S_XY(diff.z, diff.x);
actorPath->rotToCurPoint.x = Math_Atan2S_XY(sqrtf(actorPath->distSqToCurPointXZ), -diff.y);
actorPath->rotToCurPoint.z = 0;