mirror of
https://github.com/zeldaret/af.git
synced 2026-09-27 22:45:24 -04:00
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
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
#ifndef M_CAMERA_H
|
||||
#define M_CAMERA_H
|
||||
|
||||
// these two angle conversion macros are slightly inaccurate
|
||||
#define CAM_DEG_TO_BINANG(degrees) (s16)((degrees) * ((f32)0xFFFF / 360) + .5f)
|
||||
#define CAM_BINANG_TO_DEG(binang) ((f32)(binang) * (360.0001525f / 0xFFFF))
|
||||
|
||||
#endif
|
||||
+18
-15
@@ -2,21 +2,24 @@
|
||||
#define M_OLIB_H
|
||||
|
||||
#include "ultra64.h"
|
||||
#include "m_lib.h"
|
||||
#include "libc64/math64.h"
|
||||
#include "m_camera2.h"
|
||||
|
||||
// void distance_between();
|
||||
// void distance_between2();
|
||||
// void distance_2d();
|
||||
// void never_zero();
|
||||
// void limiter();
|
||||
// void unitvector_by_2pos();
|
||||
// void spolar2world();
|
||||
// void sglobe2world();
|
||||
// void world2spolar();
|
||||
// void world2sglobe();
|
||||
// void spolar_by_2pos();
|
||||
// void sglobe_by_2pos();
|
||||
// void radianxy_by_2pos();
|
||||
// void degreexy_by_2pos();
|
||||
// void sanglexy_by_2pos();
|
||||
f32 distance_between(xyz_t* a, xyz_t* b);
|
||||
f32 distance_between2(xyz_t* a, xyz_t* b, xyz_t* dest);
|
||||
f32 distance_2d(xyz_t* a, xyz_t* b);
|
||||
f32 never_zero(f32 val, f32 min);
|
||||
f32 limiter(f32 val, f32 max);
|
||||
xyz_t unitvector_by_2pos(xyz_t* a, xyz_t* b);
|
||||
xyz_t spolar2world(VecSph* sph);
|
||||
xyz_t sglobe2world(VecGeo* geo);
|
||||
VecSph world2spolar(xyz_t* vec);
|
||||
VecGeo world2sglobe(xyz_t* vec);
|
||||
VecSph spolar_by_2pos(xyz_t* a, xyz_t* b);
|
||||
VecGeo sglobe_by_2pos(xyz_t* a, xyz_t* b);
|
||||
xyz_t radianxy_by_2pos(xyz_t* a, xyz_t* b);
|
||||
xyz_t degreexy_by_2pos(xyz_t* a, xyz_t* b);
|
||||
s_xyz sanglexy_by_2pos(xyz_t* a, xyz_t* b);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#define ABS(x) (((x) >= 0) ? (x): -(x))
|
||||
|
||||
#define CLAMP(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x))
|
||||
#define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x))
|
||||
#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x))
|
||||
|
||||
#define DECR(x) ((x) == 0 ? 0 : --(x))
|
||||
|
||||
|
||||
@@ -42,6 +42,20 @@ typedef struct {
|
||||
/* 0x8 */ s32 z;
|
||||
} Vec3i; // size = 0xC
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ f32 r; // radius
|
||||
/* 0x4 */ s16 pitch; // depends on coordinate system. See below.
|
||||
/* 0x6 */ s16 yaw; // azimuthal angle
|
||||
} VecSphGeo; // size = 0x8
|
||||
|
||||
// Defines a point in the spherical coordinate system.
|
||||
// Pitch is 0 along the positive y-axis (up)
|
||||
typedef VecSphGeo VecSph;
|
||||
|
||||
// Defines a point in the geographic coordinate system.
|
||||
// Pitch is 0 along the xz-plane (horizon)
|
||||
typedef VecSphGeo VecGeo;
|
||||
|
||||
typedef float MtxF_t[4][4];
|
||||
typedef union {
|
||||
MtxF_t mf;
|
||||
@@ -86,4 +100,10 @@ typedef union {
|
||||
#define BINANG_SUB(a, b) ((s16)(a - b))
|
||||
#define BINANG_ADD(a, b) ((s16)(a + b))
|
||||
|
||||
// Vector macros
|
||||
#define SQXZ(vec) ((vec.x) * (vec.x) + (vec.z) * (vec.z))
|
||||
#define DOTXZ(vec1, vec2) ((vec1.x) * (vec2.x) + (vec1.z) * (vec2.z))
|
||||
#define SQXYZ(vec) ((vec.x) * (vec.x) + (vec.y) * (vec.y) + (vec.z) * (vec.z))
|
||||
#define DOTXYZ(vec1, vec2) ((vec1.x) * (vec2.x) + (vec1.y) * (vec2.y) + (vec1.z) * (vec2.z))
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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[];
|
||||
|
||||
@@ -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[];
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@
|
||||
- [0x6D2720, c, code/m_npc_schedule]
|
||||
- [0x6D2A70, c, code/m_npc_walk]
|
||||
- [0x6D3CB0, asm, code/800B0010]
|
||||
- [0x6D3D20, asm, code/m_olib]
|
||||
- [0x6D3D20, c, code/m_olib]
|
||||
- [0x6D4440, c, code/m_pause]
|
||||
- [0x6D44F0, asm, code/6D44F0]
|
||||
- [0x6D4C60, c, code/m_player_call]
|
||||
@@ -223,7 +223,7 @@
|
||||
- [0x73AEF0, rodata, code/m_msg_main]
|
||||
- [0x73AF40, rodata, code/73AF40]
|
||||
- [0x73AF50, .rodata, code/m_npc]
|
||||
- [0x73B000, rodata, code/m_olib]
|
||||
- [0x73B000, .rodata, code/m_olib]
|
||||
- [0x73B020, rodata, code/m_player_lib]
|
||||
- [0x73B0F0, rodata, code/73B0F0]
|
||||
- [0x73B130, .rodata, code/m_private]
|
||||
|
||||
Reference in New Issue
Block a user