Fix some math_util functions returning the address of local variables

This commit is contained in:
Arceveti
2021-09-22 17:34:25 -07:00
parent e1c0832a9d
commit d70c34f1d0
2 changed files with 77 additions and 118 deletions

View File

@@ -20,108 +20,85 @@ Vec4s *gSplineKeyframe;
float gSplineKeyframeFraction;
int gSplineState;
// These functions have bogus return values.
// Disable the compiler warning.
#pragma GCC diagnostic push
#ifdef __GNUC__
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wreturn-stack-address"
#else
#pragma GCC diagnostic ignored "-Wreturn-local-addr"
#endif
#endif
/// Copy vector 'src' to 'dest'
void *vec3f_copy(Vec3f dest, Vec3f src) {
void vec3f_copy(Vec3f dest, Vec3f src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return &dest; //! warning: function returns address of local variable
}
/// Set vector 'dest' to (x, y, z)
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
void vec3f_set(Vec3f dest, f32 x, f32 y, f32 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return &dest; //! warning: function returns address of local variable
}
/// Add vector 'a' to 'dest'
void *vec3f_add(Vec3f dest, Vec3f a) {
void vec3f_add(Vec3f dest, Vec3f a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return &dest; //! warning: function returns address of local variable
}
/// Make 'dest' the sum of vectors a and b.
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
void vec3f_sum(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return &dest; //! warning: function returns address of local variable
}
/// Copy vector src to dest
void *vec3s_copy(Vec3s dest, Vec3s src) {
void vec3s_copy(Vec3s dest, Vec3s src) {
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
return &dest; //! warning: function returns address of local variable
}
/// Set vector 'dest' to (x, y, z)
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
void vec3s_set(Vec3s dest, s16 x, s16 y, s16 z) {
dest[0] = x;
dest[1] = y;
dest[2] = z;
return &dest; //! warning: function returns address of local variable
}
/// Add vector a to 'dest'
void *vec3s_add(Vec3s dest, Vec3s a) {
void vec3s_add(Vec3s dest, Vec3s a) {
dest[0] += a[0];
dest[1] += a[1];
dest[2] += a[2];
return &dest; //! warning: function returns address of local variable
}
/// Make 'dest' the sum of vectors a and b.
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
void vec3s_sum(Vec3s dest, Vec3s a, Vec3s b) {
dest[0] = a[0] + b[0];
dest[1] = a[1] + b[1];
dest[2] = a[2] + b[2];
return &dest; //! warning: function returns address of local variable
}
/// Subtract vector a from 'dest'
void *vec3s_sub(Vec3s dest, Vec3s a) {
void vec3s_sub(Vec3s dest, Vec3s a) {
dest[0] -= a[0];
dest[1] -= a[1];
dest[2] -= a[2];
return &dest; //! warning: function returns address of local variable
}
/// Convert short vector a to float vector 'dest'
void *vec3s_to_vec3f(Vec3f dest, Vec3s a) {
void vec3s_to_vec3f(Vec3f dest, Vec3s a) {
dest[0] = a[0];
dest[1] = a[1];
dest[2] = a[2];
return &dest; //! warning: function returns address of local variable
}
/**
* Convert float vector a to a short vector 'dest' by rounding the components
* to the nearest integer.
*/
void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
void vec3f_to_vec3s(Vec3s dest, Vec3f a) {
// add/subtract 0.5 in order to round to the nearest s32 instead of truncating
dest[0] = a[0] + ((a[0] > 0) ? 0.5f : -0.5f);
dest[1] = a[1] + ((a[1] > 0) ? 0.5f : -0.5f);
dest[2] = a[2] + ((a[2] > 0) ? 0.5f : -0.5f);
return &dest; //! warning: function returns address of local variable
}
/**
@@ -129,34 +106,29 @@ void *vec3f_to_vec3s(Vec3s dest, Vec3f a) {
* It is similar to vec3f_cross, but it calculates the vectors (c-b) and (b-a)
* at the same time.
*/
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c) {
void find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c) {
dest[0] = (b[1] - a[1]) * (c[2] - b[2]) - (c[1] - b[1]) * (b[2] - a[2]);
dest[1] = (b[2] - a[2]) * (c[0] - b[0]) - (c[2] - b[2]) * (b[0] - a[0]);
dest[2] = (b[0] - a[0]) * (c[1] - b[1]) - (c[0] - b[0]) * (b[1] - a[1]);
return &dest; //! warning: function returns address of local variable
}
/// Make vector 'dest' the cross product of vectors a and b.
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
void vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[1] * b[2] - b[1] * a[2];
dest[1] = a[2] * b[0] - b[2] * a[0];
dest[2] = a[0] * b[1] - b[0] * a[1];
return &dest; //! warning: function returns address of local variable
}
/// Scale vector 'dest' so it has length 1
void *vec3f_normalize(Vec3f dest) {
void vec3f_normalize(Vec3f dest) {
//! Possible division by zero
f32 invsqrt = 1.0f / sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]);
f32 invsqrt = 1.0f / sqrtf(sqr(dest[0]) + sqr(dest[1]) + sqr(dest[2]));
dest[0] *= invsqrt;
dest[1] *= invsqrt;
dest[2] *= invsqrt;
return &dest; //! warning: function returns address of local variable
}
#pragma GCC diagnostic pop
/// Copy matrix 'src' to 'dest'
void mtxf_copy(Mat4 dest, Mat4 src) {
register s32 i;
@@ -216,7 +188,7 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
dx = to[0] - from[0];
dz = to[2] - from[2];
invLength = -1.0f / MAX(sqrtf(dx * dx + dz * dz), 0.00001f);
invLength = -1.0f / MAX(sqrtf(sqr(dx) + sqr(dz)), 0.00001f);
dx *= invLength;
dz *= invLength;
@@ -228,7 +200,7 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
yColZ = to[1] - from[1];
zColZ = to[2] - from[2];
invLength = -1.0f / MAX(sqrtf(xColZ * xColZ + yColZ * yColZ + zColZ * zColZ), 0.00001f);
invLength = -1.0f / MAX(sqrtf(sqr(xColZ) + sqr(yColZ) + sqr(zColZ)), 0.00001f);
xColZ *= invLength;
yColZ *= invLength;
zColZ *= invLength;
@@ -237,7 +209,7 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
yColX = zColY * xColZ - xColY * zColZ;
zColX = xColY * yColZ - yColY * xColZ;
invLength = 1.0f / MAX(sqrtf(xColX * xColX + yColX * yColX + zColX * zColX), 0.00001f);
invLength = 1.0f / MAX(sqrtf(sqr(xColX) + sqr(yColX) + sqr(zColX)), 0.00001f);
xColX *= invLength;
yColX *= invLength;
@@ -247,7 +219,7 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) {
yColY = zColZ * xColX - xColZ * zColX;
zColY = xColZ * yColX - yColZ * xColX;
invLength = 1.0f / MAX(sqrtf(xColY * xColY + yColY * yColY + zColY * zColY), 0.00001f);
invLength = 1.0f / MAX(sqrtf(sqr(xColY) + sqr(yColY) + sqr(zColY)), 0.00001f);
xColY *= invLength;
yColY *= invLength;
zColY *= invLength;
@@ -579,17 +551,17 @@ void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) {
* and no crashes occur.
*/
void mtxf_to_mtx(Mtx *dest, Mat4 src) {
Mat4 temp;
register s32 i, j;
Mat4 temp;
register s32 i, j;
for( i = 0; i < 4; i++ ) {
for( j = 0; j < 3; j++ ) {
temp[i][j] = src[i][j] / gWorldScale;
}
temp[i][3] = src[i][3];
}
for( i = 0; i < 4; i++ ) {
for( j = 0; j < 3; j++ ) {
temp[i][j] = src[i][j] / gWorldScale;
}
temp[i][3] = src[i][3];
}
guMtxF2L( temp, dest );
guMtxF2L( temp, dest );
}
/**
@@ -637,8 +609,8 @@ void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *
register f32 y = to[1] - from[1];
register f32 z = to[2] - from[2];
*dist = sqrtf(x * x + y * y + z * z);
*pitch = atan2s(sqrtf(x * x + z * z), y);
*dist = sqrtf(sqr(x) + sqr(y) + sqr(z));
*pitch = atan2s(sqrtf(sqr(x) + sqr(z)), y);
*yaw = atan2s(z, x);
}
@@ -882,37 +854,31 @@ s32 anim_spline_poll(Vec3f result) {
}
/// Multiply vector 'dest' by a
void *vec3f_mul(Vec3f dest, f32 a)
{
void vec3f_mul(Vec3f dest, f32 a) {
dest[0] *= a;
dest[1] *= a;
dest[2] *= a;
return dest; //! warning: function returns address of local variable
}
/// Get length of vector 'a'
f32 vec3f_length(Vec3f a)
{
return sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
f32 vec3f_length(Vec3f a) {
return sqrtf(sqr(a[0]) + sqr(a[1]) + sqr(a[2]));
}
/// Get dot product of vectors 'a' and 'b'
f32 vec3f_dot(Vec3f a, Vec3f b)
{
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
f32 vec3f_dot(Vec3f a, Vec3f b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/// Make 'dest' the difference of vectors a and b.
void *vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
void vec3f_dif(Vec3f dest, Vec3f a, Vec3f b) {
dest[0] = a[0] - b[0];
dest[1] = a[1] - b[1];
dest[2] = a[2] - b[2];
return dest; //! warning: function returns address of local variable
}
//Raycasting
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length)
{
// Raycasting
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length) {
Vec3f v0, v1, v2, e1, e2, h, s, q;
f32 a, f, u, v;
Vec3f add_dir;
@@ -971,8 +937,7 @@ s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface
return TRUE;
}
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length)
{
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) {
s32 hit;
f32 length;
Vec3f chk_hit_pos;
@@ -982,29 +947,23 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
#endif
// Get upper and lower bounds of ray
if (dir[1] >= 0.0f)
{
if (dir[1] >= 0.0f) {
top = orig[1] + dir[1] * dir_length;
bottom = orig[1];
}
else
{
} else {
top = orig[1];
bottom = orig[1] + dir[1] * dir_length;
}
// Iterate through every surface of the list
for (; list != NULL; list = list->next)
{
for (; list != NULL; list = list->next) {
// Reject surface if out of vertical bounds
if (list->surface->lowerY > top || list->surface->upperY < bottom)
continue;
// Check intersection between the ray and this surface
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) != 0)
{
if (length <= *max_length)
{
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) != 0) {
if (length <= *max_length) {
*hit_surface = list->surface;
vec3f_copy(hit_pos, chk_hit_pos);
*max_length = length;
@@ -1018,21 +977,21 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length, s32 flags)
{
// Skip if OOB
if (cellX >= 0 && cellX <= (NUM_CELLS - 1) && cellZ >= 0 && cellZ <= (NUM_CELLS - 1))
{
// Iterate through each surface in this partition
if (normalized_dir[1] > -0.99999f && flags & RAYCAST_FIND_CEIL)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (normalized_dir[1] < 0.99999f && flags & RAYCAST_FIND_FLOOR)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (flags & RAYCAST_FIND_WALL)
// Skip if OOB
if (cellX >= 0 && cellX <= (NUM_CELLS - 1) && cellZ >= 0 && cellZ <= (NUM_CELLS - 1))
{
// Iterate through each surface in this partition
if (normalized_dir[1] > -0.99999f && flags & RAYCAST_FIND_CEIL)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (normalized_dir[1] < 0.99999f && flags & RAYCAST_FIND_FLOOR)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (flags & RAYCAST_FIND_WALL)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
@@ -1042,7 +1001,7 @@ void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
}
}
}
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags)
@@ -1076,9 +1035,9 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
// Don't do DDA if straight down
if (normalized_dir[1] >= 0.99999f || normalized_dir[1] <= -0.99999f)
{
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
return;
}
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
return;
}
// Get cells we cross using DDA
if (ABS(dir[0]) >= ABS(dir[2]))

View File

@@ -340,20 +340,20 @@ extern f32 gSineTable[];
#define RAYCAST_FIND_WATER (0x8)
#define RAYCAST_FIND_ALL (0xFFFFFFFF)
void *vec3f_copy(Vec3f dest, Vec3f src);
void *vec3f_set(Vec3f dest, f32 x, f32 y, f32 z);
void *vec3f_add(Vec3f dest, Vec3f a);
void *vec3f_sum(Vec3f dest, Vec3f a, Vec3f b);
void *vec3s_copy(Vec3s dest, Vec3s src);
void *vec3s_set(Vec3s dest, s16 x, s16 y, s16 z);
void *vec3s_add(Vec3s dest, Vec3s a);
void *vec3s_sum(Vec3s dest, Vec3s a, Vec3s b);
void *vec3s_sub(Vec3s dest, Vec3s a);
void *vec3s_to_vec3f(Vec3f dest, Vec3s a);
void *vec3f_to_vec3s(Vec3s dest, Vec3f a);
void *find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c);
void *vec3f_cross(Vec3f dest, Vec3f a, Vec3f b);
void *vec3f_normalize(Vec3f dest);
void vec3f_copy(Vec3f dest, Vec3f src);
void vec3f_set(Vec3f dest, f32 x, f32 y, f32 z);
void vec3f_add(Vec3f dest, Vec3f a);
void vec3f_sum(Vec3f dest, Vec3f a, Vec3f b);
void vec3s_copy(Vec3s dest, Vec3s src);
void vec3s_set(Vec3s dest, s16 x, s16 y, s16 z);
void vec3s_add(Vec3s dest, Vec3s a);
void vec3s_sum(Vec3s dest, Vec3s a, Vec3s b);
void vec3s_sub(Vec3s dest, Vec3s a);
void vec3s_to_vec3f(Vec3f dest, Vec3s a);
void vec3f_to_vec3s(Vec3s dest, Vec3f a);
void find_vector_perpendicular_to_plane(Vec3f dest, Vec3f a, Vec3f b, Vec3f c);
void vec3f_cross(Vec3f dest, Vec3f a, Vec3f b);
void vec3f_normalize(Vec3f dest);
void mtxf_copy(Mat4 dest, Mat4 src);
void mtxf_identity(Mat4 mtx);
void mtxf_translate(Mat4 dest, Vec3f b);