summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/z_actor.c2
-rw-r--r--src/code/z_olib.c293
-rw-r--r--src/code/z_snap.c2
3 files changed, 295 insertions, 2 deletions
diff --git a/src/code/z_actor.c b/src/code/z_actor.c
index 94b941c56..99679f1c7 100644
--- a/src/code/z_actor.c
+++ b/src/code/z_actor.c
@@ -520,7 +520,7 @@ s32 Actor_IsActorFacedByActor(Actor* actor, Actor* other, s16 tolerance) {
s16 angle;
s16 dist;
- angle = Actor_YawBetweenActors(actor, other) + 0x8000;
+ angle = BINANG_ROT180(Actor_YawBetweenActors(actor, other));
dist = angle - other->shape.rot.y;
if (ABS_ALT(dist) < tolerance) {
return 1;
diff --git a/src/code/z_olib.c b/src/code/z_olib.c
new file mode 100644
index 000000000..9c8010b6c
--- /dev/null
+++ b/src/code/z_olib.c
@@ -0,0 +1,293 @@
+#include "global.h"
+
+/**
+ * Calculates the distances between `a` and `b`
+ */
+f32 OLib_Vec3fDist(Vec3f* a, Vec3f* b) {
+ f32 dx = a->x - b->x;
+ f32 dy = a->y - b->y;
+ f32 dz = a->z - b->z;
+
+ return sqrtf(SQ(dx) + SQ(dy) + SQ(dz));
+}
+
+/**
+ * Calculates the distances between `a` and `b`, and outputs the vector
+ * created by the difference into `dest`
+ */
+f32 OLib_Vec3fDistOutDiff(Vec3f* a, Vec3f* b, Vec3f* dest) {
+ dest->x = a->x - b->x;
+ dest->y = a->y - b->y;
+ dest->z = a->z - b->z;
+
+ return sqrtf(SQ(dest->x) + SQ(dest->y) + SQ(dest->z));
+}
+
+/**
+ * Calculates the distances on the xz plane between `a` and `b`
+ */
+f32 OLib_Vec3fDistXZ(Vec3f* a, Vec3f* b) {
+ return sqrtf(SQ(a->x - b->x) + SQ(a->z - b->z));
+}
+
+/**
+ * Clamps `val` to a maximum of -`min` as `val` approaches zero, and a minimum of
+ * `min` as `val` approaches zero
+ */
+f32 OLib_ClampMinDist(f32 val, f32 min) {
+ if (val < 0.0f) {
+ return CLAMP_MAX(val, -min);
+ } else {
+ return CLAMP_MIN(val, min);
+ }
+}
+
+/**
+ * Clamps `val` to a minimum of -`max` as `val` approaches -`max`, and a maximum of `max`
+ * as `val` approaches `max`
+ */
+f32 OLib_ClampMaxDist(f32 val, f32 max) {
+ if (val < 0.0f) {
+ return CLAMP_MIN(val, -max);
+ } else {
+ return CLAMP_MAX(val, max);
+ }
+}
+
+/**
+ * Takes the difference of points b and a, and creates a normal vector
+ */
+Vec3f* OLib_Vec3fDistNormalize(Vec3f* dest, Vec3f* a, Vec3f* b) {
+ Vec3f v1;
+ Vec3f v2;
+ f32 dist;
+
+ v1.x = b->x - a->x;
+ v1.y = b->y - a->y;
+ v1.z = b->z - a->z;
+
+ dist = OLib_ClampMinDist(sqrtf(SQ(v1.x) + SQ(v1.y) + SQ(v1.z)), 0.01f);
+
+ v2.x = v1.x / dist;
+ v2.y = v1.y / dist;
+ v2.z = v1.z / dist;
+
+ *dest = v2;
+
+ return dest;
+}
+
+/**
+ * Takes the spherical coordinate `sph`, and converts it into a x,y,z position
+ */
+Vec3f* OLib_VecSphToVec3f(Vec3f* dest, VecSph* sph) {
+ Vec3f v;
+ f32 sinPitch;
+ f32 cosPitch = Math_CosS(sph->pitch);
+ f32 sinYaw;
+ f32 cosYaw = Math_CosS(sph->yaw);
+
+ sinPitch = Math_SinS(sph->pitch);
+ sinYaw = Math_SinS(sph->yaw);
+
+ v.x = sph->r * sinPitch * sinYaw;
+ v.y = sph->r * cosPitch;
+ v.z = sph->r * sinPitch * cosYaw;
+
+ *dest = v;
+
+ return dest;
+}
+
+/**
+ * Takes the geographic point `sph` and converts it into a x,y,z position
+ */
+Vec3f* OLib_VecSphGeoToVec3f(Vec3f* dest, VecSph* sph) {
+ VecSph geo;
+
+ geo.r = sph->r;
+ geo.pitch = 0x4000 - sph->pitch;
+ geo.yaw = sph->yaw;
+
+ return OLib_VecSphToVec3f(dest, &geo);
+}
+
+/**
+ * Takes the point `vec`, and converts it into a spherical coordinate
+ */
+VecSph* OLib_Vec3fToVecSph(VecSph* dest, Vec3f* vec) {
+ VecSph sph;
+ f32 distSquared = SQ(vec->x) + SQ(vec->z);
+ f32 dist = sqrtf(distSquared);
+
+ if ((dist == 0.0f) && (vec->y == 0.0f)) {
+ sph.pitch = 0;
+ } else {
+ sph.pitch = DEGF_TO_BINANG(RADF_TO_DEGF(func_80086B30(dist, vec->y)));
+ }
+
+ sph.r = sqrtf(SQ(vec->y) + distSquared);
+ if ((vec->x == 0.0f) && (vec->z == 0.0f)) {
+ sph.yaw = 0;
+ } else {
+ sph.yaw = DEGF_TO_BINANG(RADF_TO_DEGF(func_80086B30(vec->x, vec->z)));
+ }
+
+ *dest = sph;
+
+ return dest;
+}
+
+/**
+ * Takes the point `vec`, and converts it to a geographic coordinate
+ */
+VecSph* OLib_Vec3fToVecSphGeo(VecSph* dest, Vec3f* vec) {
+ VecSph sph;
+
+ OLib_Vec3fToVecSph(&sph, vec);
+ sph.pitch = 0x4000 - sph.pitch;
+
+ *dest = sph;
+
+ return dest;
+}
+
+/**
+ * Takes the differences of positions `a` and `b`, and converts them to spherical coordinates
+ */
+VecSph* OLib_Vec3fDiffToVecSph(VecSph* dest, Vec3f* a, Vec3f* b) {
+ Vec3f sph;
+
+ sph.x = b->x - a->x;
+ sph.y = b->y - a->y;
+ sph.z = b->z - a->z;
+
+ return OLib_Vec3fToVecSph(dest, &sph);
+}
+
+/**
+ * Takes the difference of positions `a` and `b`, and converts them to geographic coordinates
+ */
+VecSph* OLib_Vec3fDiffToVecSphGeo(VecSph* dest, Vec3f* a, Vec3f* b) {
+ Vec3f sph;
+
+ sph.x = b->x - a->x;
+ sph.y = b->y - a->y;
+ sph.z = b->z - a->z;
+
+ return OLib_Vec3fToVecSphGeo(dest, &sph);
+}
+
+/**
+ * Takes the sum of positions `a` (x,y,z coordinates) and `sph` (geographic coordinates), result is in x,y,z position
+ */
+Vec3f* OLib_VecSphToVec3fSum(Vec3f* dest, Vec3f* a, VecSph* sph) {
+ Vec3f vec;
+ Vec3f b;
+
+ OLib_VecSphGeoToVec3f(&b, sph);
+ vec.x = a->x + b.x;
+ vec.y = a->y + b.y;
+ vec.z = a->z + b.z;
+
+ *dest = vec;
+
+ return dest;
+}
+
+/**
+ * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in radians
+ */
+Vec3f* OLib_Vec3fDiffRad(Vec3f* dest, Vec3f* a, Vec3f* b) {
+ Vec3f anglesRad;
+
+ anglesRad.x = func_80086B30(b->z - a->z, b->y - a->y);
+ anglesRad.y = func_80086B30(b->x - a->x, b->z - a->z);
+ anglesRad.z = 0;
+
+ *dest = anglesRad;
+
+ return dest;
+}
+
+/**
+ * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in degrees
+ */
+Vec3f* OLib_Vec3fDiffDegF(Vec3f* dest, Vec3f* a, Vec3f* b) {
+ Vec3f anglesRad;
+ Vec3f anglesDegrees;
+
+ OLib_Vec3fDiffRad(&anglesRad, a, b);
+
+ anglesDegrees.x = RADF_TO_DEGF(anglesRad.x);
+ anglesDegrees.y = RADF_TO_DEGF(anglesRad.y);
+ anglesDegrees.z = 0.0f;
+
+ *dest = anglesDegrees;
+
+ return dest;
+}
+
+/**
+ * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in binary degrees
+ */
+Vec3s* OLib_Vec3fDiffBinAng(Vec3s* dest, Vec3f* a, Vec3f* b) {
+ Vec3f anglesRad;
+ Vec3s anglesBinAng;
+
+ OLib_Vec3fDiffRad(&anglesRad, a, b);
+
+ anglesBinAng.x = DEGF_TO_BINANG(RADF_TO_DEGF(anglesRad.x));
+ anglesBinAng.y = DEGF_TO_BINANG(RADF_TO_DEGF(anglesRad.y));
+ anglesBinAng.z = 0.0f;
+
+ *dest = anglesBinAng;
+
+ return dest;
+}
+
+/**
+ * Gets a x,y,z position diff depending on the dbCamera mode
+ */
+void OLib_DbCameraVec3fDiff(PosRot* a, Vec3f* b, Vec3f* dest, s16 mode) {
+ VecSph sph;
+
+ switch (mode) {
+ case 1:
+ OLib_Vec3fDiffToVecSphGeo(&sph, &a->pos, b);
+ sph.yaw -= a->rot.y;
+ OLib_VecSphGeoToVec3f(dest, &sph);
+ break;
+ case 2:
+ dest->x = b->x - a->pos.x;
+ dest->y = b->y - a->pos.y;
+ dest->z = b->z - a->pos.z;
+ break;
+ default:
+ *dest = *b;
+ break;
+ }
+}
+
+/**
+ * Gets a x,y,z position sum depending on the dbCamera mode
+ */
+void OLib_DbCameraVec3fSum(PosRot* a, Vec3f* b, Vec3f* dest, s16 mode) {
+ VecSph sph;
+
+ switch (mode) {
+ case 1:
+ OLib_Vec3fToVecSphGeo(&sph, b);
+ sph.yaw += a->rot.y;
+ OLib_VecSphToVec3fSum(dest, &a->pos, &sph);
+ break;
+ case 2:
+ dest->x = a->pos.x + b->x;
+ dest->y = a->pos.y + b->y;
+ dest->z = a->pos.z + b->z;
+ break;
+ default:
+ *dest = *b;
+ break;
+ }
+}
diff --git a/src/code/z_snap.c b/src/code/z_snap.c
index 910b28a3c..3ecb26611 100644
--- a/src/code/z_snap.c
+++ b/src/code/z_snap.c
@@ -122,7 +122,7 @@ s32 func_8013A530(GlobalContext* globalCtx, Actor* actor, s32 flag, Vec3f* pos,
camera = ACTIVE_CAM;
- distance = CamMath_Distance(pos, &camera->eye);
+ distance = OLib_Vec3fDist(pos, &camera->eye);
if ((distance < distanceMin) || (distanceMax < distance)) {
func_8013A41C(0x3f);
ret = 0x3f;