From fb02647839bda70f4e50a2f79c7bdcfb93ef61af Mon Sep 17 00:00:00 2001 From: Lucas Shaw <49287729+shawlucas@users.noreply.github.com> Date: Thu, 11 Apr 2024 02:20:00 -0400 Subject: m_olib.c OK (#167) * m_olib.c OK * ran format.py * added functions to header file * updated graphics macros in two overlays to make them work with format.py * rename z64camera.h to m_camera2.h * made recommended changes --- src/code/m_olib.c | 212 +++++++++++++++++++++++ src/overlays/actors/ovl_Koinobori/ac_koinobori.c | 6 +- src/overlays/actors/ovl_Toudai/ac_toudai.c | 18 +- 3 files changed, 228 insertions(+), 8 deletions(-) create mode 100644 src/code/m_olib.c (limited to 'src') diff --git a/src/code/m_olib.c b/src/code/m_olib.c new file mode 100644 index 0000000..7dc7058 --- /dev/null +++ b/src/code/m_olib.c @@ -0,0 +1,212 @@ +#include "global.h" +#include "m_olib.h" + +/** + * Calculates the distances between `a` and `b` + */ +f32 distance_between(xyz_t* a, xyz_t* 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 distance_between2(xyz_t* a, xyz_t* b, xyz_t* 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 distance_2d(xyz_t* a, xyz_t* 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 never_zero(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 limiter(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 + */ +xyz_t unitvector_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t v1; + xyz_t v2; + f32 dist; + + v1.x = b->x - a->x; + v1.y = b->y - a->y; + v1.z = b->z - a->z; + + dist = never_zero(sqrtf(SQXYZ(v1)), 0.01f); + + v2.x = v1.x / dist; + v2.y = v1.y / dist; + v2.z = v1.z / dist; + + return v2; +} + +/** + * Takes the spherical coordinate `sph`, and converts it into a x,y,z position + */ +xyz_t spolar2world(VecSph* sph) { + xyz_t v; + f32 sinPitch; + f32 cosPitch = cos_s(sph->pitch); + f32 sinYaw; + f32 cosYaw = cos_s(sph->yaw); + + sinPitch = sin_s(sph->pitch); + sinYaw = sin_s(sph->yaw); + + v.x = sph->r * sinPitch * sinYaw; + v.y = sph->r * cosPitch; + v.z = sph->r * sinPitch * cosYaw; + + return v; +} + +/** + * Takes the geographic point `geo` and converts it into a x,y,z position + */ +xyz_t sglobe2world(VecGeo* geo) { + VecSph sph; + + sph.r = geo->r; + sph.pitch = 0x3FFF - geo->pitch; + sph.yaw = geo->yaw; + + return spolar2world(&sph); +} + +/** + * Takes the point `vec`, and converts it into a spherical coordinate + */ +VecSph world2spolar(xyz_t* vec) { + VecSph sph; + f32 distXZSq = SQ(vec->x) + SQ(vec->z); + f32 distXZ = sqrtf(distXZSq); + + if ((distXZ == 0.0f) && (vec->y == 0.0f)) { + sph.pitch = 0; + } else { + sph.pitch = CAM_DEG_TO_BINANG(RAD_TO_DEG(fatan2(distXZ, vec->y))); + } + + sph.r = sqrtf(SQ(vec->y) + distXZSq); + if ((vec->x == 0.0f) && (vec->z == 0.0f)) { + sph.yaw = 0; + } else { + sph.yaw = CAM_DEG_TO_BINANG(RAD_TO_DEG(fatan2(vec->x, vec->z))); + } + + return sph; +} + +/** + * Takes the point `vec`, and converts it to a geographic coordinate + */ +VecGeo world2sglobe(xyz_t* vec) { + VecSph sph = world2spolar(vec); + + sph.pitch = 0x3FFF - sph.pitch; + + return sph; +} + +/** + * Takes the differences of positions `a` and `b`, and converts them to spherical coordinates + */ +VecSph spolar_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t diff; + + diff.x = b->x - a->x; + diff.y = b->y - a->y; + diff.z = b->z - a->z; + + return world2spolar(&diff); +} + +/** + * Takes the difference of positions `a` and `b`, and converts them to geographic coordinates + */ +VecGeo sglobe_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t diff; + + diff.x = b->x - a->x; + diff.y = b->y - a->y; + diff.z = b->z - a->z; + + return world2sglobe(&diff); +} + +/** + * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in radians + */ +xyz_t radianxy_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t anglesRad; + + anglesRad.x = fatan2(b->z - a->z, b->y - a->y); + anglesRad.y = fatan2(b->x - a->x, b->z - a->z); + anglesRad.z = 0.0f; + + return anglesRad; +} + +/** + * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in degrees + */ +xyz_t degreexy_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t anglesRad = radianxy_by_2pos(a, b); + xyz_t anglesDegrees; + + anglesDegrees.x = RAD_TO_DEG(anglesRad.x); + anglesDegrees.y = RAD_TO_DEG(anglesRad.y); + anglesDegrees.z = 0.0f; + + return anglesDegrees; +} + +/** + * Gets the pitch/yaw of the vector formed from `b`-`a`, result is in binary degrees + */ +s_xyz sanglexy_by_2pos(xyz_t* a, xyz_t* b) { + xyz_t anglesRad = radianxy_by_2pos(a, b); + s_xyz anglesBinAng; + + anglesBinAng.x = CAM_DEG_TO_BINANG(RAD_TO_DEG(anglesRad.x)); + anglesBinAng.y = CAM_DEG_TO_BINANG(RAD_TO_DEG(anglesRad.y)); + anglesBinAng.z = 0.0f; + + return anglesBinAng; +} diff --git a/src/overlays/actors/ovl_Koinobori/ac_koinobori.c b/src/overlays/actors/ovl_Koinobori/ac_koinobori.c index 11bad7a..e12ef87 100644 --- a/src/overlays/actors/ovl_Koinobori/ac_koinobori.c +++ b/src/overlays/actors/ovl_Koinobori/ac_koinobori.c @@ -112,13 +112,15 @@ void aKOI_actor_init(Actor* thisx, Game_Play* game_play) { { \ Gfx* __polyOpa = __gfxCtx->polyOpa.p; \ int __opa_opened = 0; \ - while (0) + do { \ + } while (0) #define CLOSE_POLY_OPA_DISPS() \ __gfxCtx->polyOpa.p = __polyOpa; \ (void)__opa_opened; \ } \ - while (0) + do { \ + } while (0) extern u16 aKOI_obj_e_koinobori_a_pal[]; extern u16 obj_e_koinobori_b_pal[]; diff --git a/src/overlays/actors/ovl_Toudai/ac_toudai.c b/src/overlays/actors/ovl_Toudai/ac_toudai.c index c128db3..abbcffa 100644 --- a/src/overlays/actors/ovl_Toudai/ac_toudai.c +++ b/src/overlays/actors/ovl_Toudai/ac_toudai.c @@ -209,37 +209,43 @@ s32 aTOU_actor_draw_before(Game_Play* game_play UNUSED, SkeletonInfoR* skeletonI { \ Gfx* __polyOpa = __gfxCtx->polyOpa.p; \ int __opa_opened = 0; \ - while (0) + do { \ + } while (0) #define CLOSE_POLY_OPA_DISPS() \ __gfxCtx->polyOpa.p = __polyOpa; \ (void)__opa_opened; \ } \ - while (0) + do { \ + } while (0) #define OPEN_POLY_XLU_DISPS() \ { \ Gfx* __polyXlu = __gfxCtx->polyXlu.p; \ int __xlu_opened = 0; \ - while (0) + do { \ + } while (0) #define CLOSE_POLY_XLU_DISPS() \ __gfxCtx->polyXlu.p = __polyXlu; \ (void)__xlu_opened; \ } \ - while (0) + do { \ + } while (0); #define OPEN_LIGHT_DISPS() \ { \ Gfx* __light = __gfxCtx->light.p; \ int __light_opened = 0; \ - while (0) + do { \ + } while (0) #define CLOSE_LIGHT_DISPS() \ __gfxCtx->light.p = __light; \ (void)__light_opened; \ } \ - while (0) + do { \ + } while (0) extern Gfx obj_s_toudai_light_model[]; extern Gfx obj_w_toudai_light_model[]; -- cgit v1.2.3