diff --git a/src/engine/colors.c b/src/engine/colors.c index 32d7fe4b..41f67d49 100644 --- a/src/engine/colors.c +++ b/src/engine/colors.c @@ -81,8 +81,8 @@ void rgba32_to_colorRGBAf(ColorRGBAf dst, RGBA32 src) { dst[3] = COMPOSITE_TO_COLORF(src, MSK_RGBA32_A, IDX_RGBA32_A); } -void colorRGB_to_colorRGBf(ColorRGBf dst, ColorRGB src) { vec3_quot_val(dst, src, 255.0f); } -void colorRGBf_to_colorRGB(ColorRGB dst, ColorRGBf src) { vec3_prod_val(dst, src, 255.0f); } +void colorRGB_to_colorRGBf(ColorRGBf dst, ColorRGB src) { vec3_scale_dest(dst, src, 1/255.0f); } +void colorRGBf_to_colorRGB(ColorRGB dst, ColorRGBf src) { vec3_scale_dest(dst, src, 255.0f); } RGBA16Return32 colorRGBf_to_rgba16(ColorRGBf src) { return (COLORF_TO_COMPOSITE(src[0], MSK_RGBA16_C, IDX_RGBA16_R) @@ -137,7 +137,7 @@ Bool32 colorRGBA_average_3(ColorRGBA dst, ColorRGBA c1, ColorRGBA c2, ColorRGBA RGBA16Return32 rgba16_make_grayscale(RGBA16 rgba) { ColorRGBf color; rgba16_to_colorRGBf(color, rgba); - ColorF avg = vec3_average(color); + ColorF avg = (color[0] + color[1] + color[2]) / 3.f; vec3_same(color, avg); return colorRGBf_to_rgba16(color); } diff --git a/src/engine/colors.h b/src/engine/colors.h index 7db18298..866e6842 100644 --- a/src/engine/colors.h +++ b/src/engine/colors.h @@ -103,10 +103,10 @@ #define COMPOSITE_TO_COLORF(src, bitmask, index) ((ColorF)(((src) >> (index)) & (bitmask)) / (bitmask)) #define COLORF_TO_COMPOSITE(src, bitmask, index) (((CompositeColor)((src) * (bitmask)) & (bitmask)) << (index)) -#define COLORRGB_TO_COLORRGBF( dst, src) vec3_quot_val((dst), (src), 255.0f) -#define COLORRGBF_TO_COLORRGB( dst, src) vec3_prod_val((dst), (src), 255.0f) -#define COLORRGBA_TO_COLORRGBAF(dst, src) vec4_quot_val((dst), (src), 255.0f) -#define COLORRGBAF_TO_COLORRGBA(dst, src) vec4_prod_val((dst), (src), 255.0f) +#define COLORRGB_TO_COLORRGBF( dst, src) vec3_scale_dest((dst), (src), 1/255.0f) +#define COLORRGBF_TO_COLORRGB( dst, src) vec3_scale_dest((dst), (src), 255.0f) +#define COLORRGBA_TO_COLORRGBAF(dst, src) vec4_scale_dest((dst), (src), 1/255.0f) +#define COLORRGBAF_TO_COLORRGBA(dst, src) vec4_scale_dest((dst), (src), 255.0f) #define colorRGB_set( dst, r, g, b) vec3_set( (dst), (r), (g), (b)) #define colorRGB_copy( dst, src ) vec3_copy((dst), (src) ) diff --git a/src/engine/math_util.c b/src/engine/math_util.c index 16efd027..bcaca282 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -63,28 +63,7 @@ s32 random_sign(void) { return ((random_u16() >= 0x7FFF) ? 1 : -1); } -/// Returns the lowest of three values. -#define min_3_func(a0, a1, a2) {\ - if (a1 < a0) a0 = a1; \ - if (a2 < a0) a0 = a2; \ - return a0; \ -} - -f32 min_3f(f32 a, f32 b, f32 c) { min_3_func(a, b, c); } -s32 min_3i(s32 a, s32 b, s32 c) { min_3_func(a, b, c); } -s32 min_3s(s16 a, s16 b, s16 c) { min_3_func(a, b, c); } - -/// Returns the highest of three values. -#define max_3_func(a0, a1, a2) {\ - if (a1 > a0) a0 = a1; \ - if (a2 > a0) a0 = a2; \ - return a0; \ -} -f32 max_3f(f32 a, f32 b, f32 c) { max_3_func(a, b, c); } -s32 max_3i(s32 a, s32 b, s32 c) { max_3_func(a, b, c); } -s32 max_3s(s16 a, s16 b, s16 c) { max_3_func(a, b, c); } - -/// A combination of the above. +// Get the maximum and minimum of three numbers at the same time. #define min_max_3_func(a, b, c, min, max) { \ if (b < a) { \ *max = a; \ @@ -96,232 +75,24 @@ s32 max_3s(s16 a, s16 b, s16 c) { max_3_func(a, b, c); } if (c < *min) *min = c; \ if (c > *max) *max = c; \ } + void min_max_3f(f32 a, f32 b, f32 c, f32 *min, f32 *max) { min_max_3_func(a, b, c, min, max); } void min_max_3i(s32 a, s32 b, s32 c, s32 *min, s32 *max) { min_max_3_func(a, b, c, min, max); } void min_max_3s(s16 a, s16 b, s16 c, s16 *min, s16 *max) { min_max_3_func(a, b, c, min, max); } -/// Perform a bitwise copy from vector 'src' to 'dest' -#define vec3_copy_bits(destFmt, dest, srcFmt, src) { \ - register destFmt x = ((srcFmt *) src)[0]; \ - register destFmt y = ((srcFmt *) src)[1]; \ - register destFmt z = ((srcFmt *) src)[2]; \ - ((destFmt *) dest)[0] = x; \ - ((destFmt *) dest)[1] = y; \ - ((destFmt *) dest)[2] = z; \ -} -void vec3f_copy (Vec3f dest, const Vec3f src) { vec3_copy_bits(f32, dest, f32, src); } // 32 -> 32 -void vec3i_copy (Vec3i dest, const Vec3i src) { vec3_copy_bits(s32, dest, s32, src); } // 32 -> 32 -void vec3s_copy (Vec3s dest, const Vec3s src) { vec3_copy_bits(s16, dest, s16, src); } // 16 -> 16 -void vec3s_to_vec3i(Vec3i dest, const Vec3s src) { vec3_copy_bits(s32, dest, s16, src); } // 16 -> 32 -void vec3s_to_vec3f(Vec3f dest, const Vec3s src) { vec3_copy_bits(f32, dest, s16, src); } // 16 -> 32 -void vec3i_to_vec3s(Vec3s dest, const Vec3i src) { vec3_copy_bits(s16, dest, s32, src); } // 32 -> 16 -void vec3i_to_vec3f(Vec3f dest, const Vec3i src) { vec3_copy_bits(f32, dest, s32, src); } // 32 -> 32 - -void surface_normal_to_vec3f(Vec3f dest, struct Surface *surf) { - register f32 x = surf->normal.x; - register f32 y = surf->normal.y; - register f32 z = surf->normal.z; - ((f32 *) dest)[0] = x; - ((f32 *) dest)[1] = y; - ((f32 *) dest)[2] = z; -} - -/// Convert float vector a to a short vector 'dest' by rounding the components to the nearest integer. -#define vec3_copy_bits_roundf(fmt, dest, src) { \ - register fmt x = roundf(src[0]); \ - register fmt y = roundf(src[1]); \ - register fmt z = roundf(src[2]); \ - ((fmt *) dest)[0] = x; \ - ((fmt *) dest)[1] = y; \ - ((fmt *) dest)[2] = z; \ -} -void vec3f_to_vec3s(Vec3s dest, const Vec3f src) { vec3_copy_bits_roundf(s16, dest, src); } // 32 -> 16 -void vec3f_to_vec3i(Vec3i dest, const Vec3f src) { vec3_copy_bits_roundf(s32, dest, src); } // 32 -> 32 -#undef vec3_copy_bits_roundf - -#define vec3_copy_y_off_func(destFmt, dest, srcFmt, src, yOff) {\ - register destFmt x = ((srcFmt *) src)[0]; \ - register destFmt y = ((srcFmt *) src)[1] + yOff; \ - register destFmt z = ((srcFmt *) src)[2]; \ - ((destFmt *) dest)[0] = x; \ - ((destFmt *) dest)[1] = y; \ - ((destFmt *) dest)[2] = z; \ -} -void vec3f_copy_y_off(Vec3f dest, Vec3f src, f32 yOff) { vec3_copy_y_off_func(f32, dest, f32, src, yOff); } -#undef vec3_copy_y_off_func - -/// Set vector 'dest' to (x, y, z) -inline void vec3f_set(Vec3f dest, const f32 x, const f32 y, const f32 z) { vec3_set(dest, x, y, z); } -inline void vec3i_set(Vec3i dest, const s32 x, const s32 y, const s32 z) { vec3_set(dest, x, y, z); } -inline void vec3s_set(Vec3s dest, const s16 x, const s16 y, const s16 z) { vec3_set(dest, x, y, z); } - -/// Add vector 'a' to 'dest' -#define vec3_add_func(fmt, dest, a) { \ - register fmt *temp = (fmt *)(dest); \ - register fmt sum, sum2; \ - register s32 i; \ - for (i = 0; i < 3; i++) { \ - sum = *(a); \ - (a)++; \ - sum2 = *temp; \ - *temp = (sum + sum2); \ - temp++; \ - } \ -} -void vec3f_add(Vec3f dest, const Vec3f a) { vec3_add_func(f32, dest, a); } -void vec3i_add(Vec3i dest, const Vec3i a) { vec3_add_func(s32, dest, a); } -void vec3s_add(Vec3s dest, const Vec3s a) { vec3_add_func(s16, dest, a); } -#undef vec3_add_func - -/// Make 'dest' the sum of vectors a and b. -#define vec3_sum_func(fmt, dest, a, b) {\ - register fmt *temp = (fmt *)(dest); \ - register fmt sum, sum2; \ - register s32 i; \ - for (i = 0; i < 3; i++) { \ - sum = *(a); \ - (a)++; \ - sum2 = *(b); \ - (b)++; \ - *temp = (sum + sum2); \ - temp++; \ - } \ -} -void vec3f_sum(Vec3f dest, const Vec3f a, const Vec3f b) { vec3_sum_func(f32, dest, a, b); } -void vec3i_sum(Vec3i dest, const Vec3i a, const Vec3i b) { vec3_sum_func(s32, dest, a, b); } -void vec3s_sum(Vec3s dest, const Vec3s a, const Vec3s b) { vec3_sum_func(s16, dest, a, b); } -#undef vec3_sum_func - -/// Subtract vector a from 'dest' -#define vec3_sub_func(fmt, dest, a) { \ - register fmt x = ((fmt *) a)[0]; \ - register fmt y = ((fmt *) a)[1]; \ - register fmt z = ((fmt *) a)[2]; \ - ((fmt *) dest)[0] -= x; \ - ((fmt *) dest)[1] -= y; \ - ((fmt *) dest)[2] -= z; \ -} -void vec3f_sub(Vec3f dest, const Vec3f a) { vec3_sub_func(f32, dest, a); } -void vec3i_sub(Vec3i dest, const Vec3i a) { vec3_sub_func(s32, dest, a); } -void vec3s_sub(Vec3s dest, const Vec3s a) { vec3_sub_func(s16, dest, a); } -#undef vec3_sub_func - -/// Make 'dest' the difference of vectors a and b. -#define vec3_diff_func(fmt, dest, a, b) { \ - register fmt x1 = ((fmt *) a)[0]; \ - register fmt y1 = ((fmt *) a)[1]; \ - register fmt z1 = ((fmt *) a)[2]; \ - register fmt x2 = ((fmt *) b)[0]; \ - register fmt y2 = ((fmt *) b)[1]; \ - register fmt z2 = ((fmt *) b)[2]; \ - ((fmt *) dest)[0] = (x1 - x2); \ - ((fmt *) dest)[1] = (y1 - y2); \ - ((fmt *) dest)[2] = (z1 - z2); \ -} -void vec3f_diff(Vec3f dest, const Vec3f a, const Vec3f b) { vec3_diff_func(f32, dest, a, b); } -void vec3i_diff(Vec3i dest, const Vec3i a, const Vec3i b) { vec3_diff_func(s32, dest, a, b); } -void vec3s_diff(Vec3s dest, const Vec3s a, const Vec3s b) { vec3_diff_func(s16, dest, a, b); } -#undef vec3_diff_func - -/// Multiply vector 'a' into 'dest' -#define vec3_mul_func(fmt, dest, a) { \ - register fmt x = ((fmt *) a)[0]; \ - register fmt y = ((fmt *) a)[1]; \ - register fmt z = ((fmt *) a)[2]; \ - ((fmt *) dest)[0] *= x; \ - ((fmt *) dest)[1] *= y; \ - ((fmt *) dest)[2] *= z; \ -} -void vec3f_mul(Vec3f dest, const Vec3f a) { vec3_mul_func(f32, dest, a); } -void vec3i_mul(Vec3i dest, const Vec3i a) { vec3_mul_func(s32, dest, a); } -void vec3s_mul(Vec3s dest, const Vec3s a) { vec3_mul_func(s16, dest, a); } -#undef vec3_mul_func - -/// Make 'dest' the product of vectors a and b. -#define vec3_prod_func(fmt, dest, a, b) { \ - register fmt x1 = ((fmt *) a)[0]; \ - register fmt y1 = ((fmt *) a)[1]; \ - register fmt z1 = ((fmt *) a)[2]; \ - register fmt x2 = ((fmt *) b)[0]; \ - register fmt y2 = ((fmt *) b)[1]; \ - register fmt z2 = ((fmt *) b)[2]; \ - ((fmt *) dest)[0] = (x1 * x2); \ - ((fmt *) dest)[1] = (y1 * y2); \ - ((fmt *) dest)[2] = (z1 * z2); \ -} -void vec3f_prod(Vec3f dest, const Vec3f a, const Vec3f b) { vec3_prod_func(f32, dest, a, b); } -void vec3i_prod(Vec3i dest, const Vec3i a, const Vec3i b) { vec3_prod_func(s32, dest, a, b); } -void vec3s_prod(Vec3s dest, const Vec3s a, const Vec3s b) { vec3_prod_func(s16, dest, a, b); } -#undef vec3_prod_func - - -/// Performs element-wise division of two 3-vectors -#define vec3_div_func(fmt, dest, a) { \ - register fmt x = ((fmt *) a)[0]; \ - register fmt y = ((fmt *) a)[1]; \ - register fmt z = ((fmt *) a)[2]; \ - ((fmt *) dest)[0] /= x; \ - ((fmt *) dest)[1] /= y; \ - ((fmt *) dest)[2] /= z; \ -} -void vec3f_div(Vec3f dest, const Vec3f a) { vec3_div_func(f32, dest, a); } -void vec3i_div(Vec3i dest, const Vec3i a) { vec3_div_func(s32, dest, a); } -void vec3s_div(Vec3s dest, const Vec3s a) { vec3_div_func(s16, dest, a); } -#undef vec3_div_func - -/// Make 'dest' the quotient of vectors a and b. -#define vec3_quot_func(fmt, dest, a, b) { \ - register fmt x1 = ((fmt *) a)[0]; \ - register fmt y1 = ((fmt *) a)[1]; \ - register fmt z1 = ((fmt *) a)[2]; \ - register fmt x2 = ((fmt *) b)[0]; \ - register fmt y2 = ((fmt *) b)[1]; \ - register fmt z2 = ((fmt *) b)[2]; \ - ((fmt *) dest)[0] = (x1 / x2); \ - ((fmt *) dest)[1] = (y1 / y2); \ - ((fmt *) dest)[2] = (z1 / z2); \ -} -void vec3f_quot(Vec3f dest, const Vec3f a, const Vec3f b) { vec3_quot_func(f32, dest, a, b); } -void vec3i_quot(Vec3i dest, const Vec3i a, const Vec3i b) { vec3_quot_func(s32, dest, a, b); } -void vec3s_quot(Vec3s dest, const Vec3s a, const Vec3s b) { vec3_quot_func(s16, dest, a, b); } -#undef vec3_quot_func - -/// Return the dot product of vectors a and b. -f32 vec3f_dot(const Vec3f a, const Vec3f b) { - return vec3_dot(a, b); -} - -/// Make vector 'dest' the cross product of vectors a and b. -void vec3f_cross(Vec3f dest, const Vec3f a, const Vec3f b) { - vec3_cross(dest, a, b); -} - -/// Scale vector 'dest' so it has length 1 -void vec3f_normalize(Vec3f dest) { - register f32 mag = (sqr(dest[0]) + sqr(dest[1]) + sqr(dest[2])); - if (mag > NEAR_ZERO) { - register f32 invsqrt = (1.0f / sqrtf(mag)); - vec3_mul_val(dest, invsqrt); - } else { - // Default to up vector. - dest[0] = 0; - ((u32 *) dest)[1] = FLOAT_ONE; - dest[2] = 0; - } -} - /// Struct the same data size as a Mat4 struct CopyMat4 { f32 a[0x10]; }; /// Copy matrix 'src' to 'dest' by casting to a struct CopyMat4 pointer. -void mtxf_copy(register Mat4 dest, register Mat4 src) { +void mtxf_copy(Mat4 dest, Mat4 src) { *((struct CopyMat4 *) dest) = *((struct CopyMat4 *) src); } /// Set mtx to the identity matrix. -void mtxf_identity(register Mat4 mtx) { + +void mtxf_identity(Mat4 mtx) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); s32 i; f32 *dest; @@ -336,8 +107,8 @@ void mtxf_identity(register Mat4 mtx) { /// Set dest to a translation matrix of vector b. void mtxf_translate(Mat4 dest, Vec3f b) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register s32 i; - register f32 *pen; + s32 i; + f32 *pen; for (pen = ((f32 *) dest + 1), i = 0; i < 12; pen++, i++) { *pen = 0; } @@ -347,65 +118,20 @@ void mtxf_translate(Mat4 dest, Vec3f b) { vec3f_copy(&dest[3][0], &b[0]); } -/** - * Multiply a vector by a matrix of the form - * | ? ? ? 0 | - * | ? ? ? 0 | - * | ? ? ? 0 | - * | 0 0 0 1 | - * i.e. a matrix representing a linear transformation over 3 space. - */ -void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v) { - PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - s32 i; - for (i = 0; i < 3; i++) { - dst[i] = ((m[0][i] * v[0]) - + (m[1][i] * v[1]) - + (m[2][i] * v[2])); - } -} - -void linear_mtxf_mul_vec3f_and_translate(Mat4 m, Vec3f dst, Vec3f v) { - PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - s32 i; - for (i = 0; i < 3; i++) { - dst[i] = ((m[0][i] * v[0]) - + (m[1][i] * v[1]) - + (m[2][i] * v[2]) - + m[3][i]); - } -} - -/** - * Multiply a vector by the transpose of a matrix of the form - * | ? ? ? 0 | - * | ? ? ? 0 | - * | ? ? ? 0 | - * | 0 0 0 1 | - * i.e. a matrix representing a linear transformation over 3 space. - */ -void linear_mtxf_transpose_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v) { - PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - s32 i; - for (i = 0; i < 3; i++) { - dst[i] = vec3_dot(m[i], v); - } -} - /// Build a matrix that rotates around the z axis, then the x axis, then the y axis, and then translates. void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f trans, Vec3s rot) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 sx = sins(rot[0]); - register f32 cx = coss(rot[0]); - register f32 sy = sins(rot[1]); - register f32 cy = coss(rot[1]); - register f32 sz = sins(rot[2]); - register f32 cz = coss(rot[2]); - register f32 sysz = (sy * sz); - register f32 cycz = (cy * cz); + f32 sx = sins(rot[0]); + f32 cx = coss(rot[0]); + f32 sy = sins(rot[1]); + f32 cy = coss(rot[1]); + f32 sz = sins(rot[2]); + f32 cz = coss(rot[2]); + f32 sysz = (sy * sz); + f32 cycz = (cy * cz); dest[0][0] = ((sysz * sx) + cycz); - register f32 cysz = (cy * sz); - register f32 sycz = (sy * cz); + f32 cysz = (cy * sz); + f32 sycz = (sy * cz); dest[1][0] = ((sycz * sx) - cysz); dest[2][0] = (cx * sy); dest[0][1] = (cx * sz); @@ -421,20 +147,20 @@ void mtxf_rotate_zxy_and_translate(Mat4 dest, Vec3f trans, Vec3s rot) { /// Build a matrix that rotates around the x axis, then the y axis, then the z axis, and then translates. UNUSED void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f trans, Vec3s rot) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 sx = sins(rot[0]); - register f32 cx = coss(rot[0]); - register f32 sy = sins(rot[1]); - register f32 cy = coss(rot[1]); - register f32 sz = sins(rot[2]); - register f32 cz = coss(rot[2]); + f32 sx = sins(rot[0]); + f32 cx = coss(rot[0]); + f32 sy = sins(rot[1]); + f32 cy = coss(rot[1]); + f32 sz = sins(rot[2]); + f32 cz = coss(rot[2]); dest[0][0] = (cy * cz); dest[0][1] = (cy * sz); dest[0][2] = -sy; - register f32 sxcz = (sx * cz); - register f32 cxsz = (cx * sz); + f32 sxcz = (sx * cz); + f32 cxsz = (cx * sz); dest[1][0] = ((sxcz * sy) - cxsz); - register f32 sxsz = (sx * sz); - register f32 cxcz = (cx * cz); + f32 sxsz = (sx * sz); + f32 cxcz = (cx * cz); dest[1][1] = ((sxsz * sy) + cxcz); dest[1][2] = (sx * cy); dest[2][0] = ((cxcz * sy) + sxsz); @@ -447,19 +173,19 @@ UNUSED void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f trans, Vec3s rot) { /// Build a matrix that rotates around the z axis, then the x axis, then the y axis, and then translates and multiplies. void mtxf_rotate_zxy_and_translate_and_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 sx = sins(rot[0]); - register f32 cx = coss(rot[0]); - register f32 sy = sins(rot[1]); - register f32 cy = coss(rot[1]); - register f32 sz = sins(rot[2]); - register f32 cz = coss(rot[2]); + f32 sx = sins(rot[0]); + f32 cx = coss(rot[0]); + f32 sy = sins(rot[1]); + f32 cy = coss(rot[1]); + f32 sz = sins(rot[2]); + f32 cz = coss(rot[2]); Vec3f entry; - register f32 sysz = (sy * sz); - register f32 cycz = (cy * cz); + f32 sysz = (sy * sz); + f32 cycz = (cy * cz); entry[0] = ((sysz * sx) + cycz); entry[1] = (sz * cx); - register f32 cysz = (cy * sz); - register f32 sycz = (sy * cz); + f32 cysz = (cy * sz); + f32 sycz = (sy * cz); entry[2] = ((cysz * sx) - sycz); linear_mtxf_mul_vec3f(src, dest[0], entry); entry[0] = ((sycz * sx) - cysz); @@ -478,22 +204,22 @@ void mtxf_rotate_zxy_and_translate_and_mul(Vec3s rot, Vec3f trans, Mat4 dest, Ma /// Build a matrix that rotates around the x axis, then the y axis, then the z axis, and then translates and multiplies. void mtxf_rotate_xyz_and_translate_and_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 sx = sins(rot[0]); - register f32 cx = coss(rot[0]); - register f32 sy = sins(rot[1]); - register f32 cy = coss(rot[1]); - register f32 sz = sins(rot[2]); - register f32 cz = coss(rot[2]); + f32 sx = sins(rot[0]); + f32 cx = coss(rot[0]); + f32 sy = sins(rot[1]); + f32 cy = coss(rot[1]); + f32 sz = sins(rot[2]); + f32 cz = coss(rot[2]); Vec3f entry; entry[0] = (cy * cz); entry[1] = (cy * sz); entry[2] = -sy; linear_mtxf_mul_vec3f(src, dest[0], entry); - register f32 sxcz = (sx * cz); - register f32 cxsz = (cx * sz); + f32 sxcz = (sx * cz); + f32 cxsz = (cx * sz); entry[0] = ((sxcz * sy) - cxsz); - register f32 sxsz = (sx * sz); - register f32 cxcz = (cx * cz); + f32 sxsz = (sx * sz); + f32 cxcz = (cx * cz); entry[1] = ((sxsz * sy) + cxcz); entry[2] = (sx * cy); linear_mtxf_mul_vec3f(src, dest[1], entry); @@ -515,9 +241,9 @@ void mtxf_rotate_xyz_and_translate_and_mul(Vec3s rot, Vec3f trans, Mat4 dest, Ma void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); Vec3f colX, colY, colZ; - register f32 dx = (to[0] - from[0]); - register f32 dz = (to[2] - from[2]); - register f32 invLength = sqrtf(sqr(dx) + sqr(dz)); + f32 dx = (to[0] - from[0]); + f32 dz = (to[2] - from[2]); + f32 invLength = sqrtf(sqr(dx) + sqr(dz)); invLength = -(1.0f / MAX(invLength, NEAR_ZERO)); dx *= invLength; dz *= invLength; @@ -555,10 +281,10 @@ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s16 roll) { */ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, Vec3f scale, s16 angle) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register s32 i; - register f32 sx = scale[0]; - register f32 sy = scale[1]; - register f32 sz = scale[2]; + s32 i; + f32 sx = scale[0]; + f32 sy = scale[1]; + f32 sz = scale[2]; Mat4* cameraMat = &gCameraTransform; for (i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { @@ -676,7 +402,7 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) { if ((point1[1] - pos[1]) < minY) point1[1] = pos[1]; if ((point2[1] - pos[1]) < minY) point2[1] = pos[1]; - f32 avgY = average_3(point0[1], point1[1], point2[1]); + f32 avgY = (point0[1] + point1[1] + point2[1]) / 3.f; vec3f_set(forward, sins(yaw), 0.0f, coss(yaw)); find_vector_perpendicular_to_plane(yColumn, point0, point1, point2); @@ -707,10 +433,10 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s16 yaw, f32 radius) { void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); Vec3f entry; - register f32 *temp = (f32 *)a; - register f32 *temp2 = (f32 *)dest; - register f32 *temp3; - register s32 i; + f32 *temp = (f32 *)a; + f32 *temp2 = (f32 *)dest; + f32 *temp3; + s32 i; for (i = 0; i < 16; i++) { vec3_copy(entry, temp); for (temp3 = (f32 *)b; (i & 3) != 3; i++) { @@ -731,11 +457,11 @@ void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) { /** * Set matrix 'dest' to 'mtx' scaled by vector s */ -void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, register Vec3f s) { +void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 *temp = (f32 *)dest; - register f32 *temp2 = (f32 *)mtx; - register s32 i; + f32 *temp = (f32 *)dest; + f32 *temp2 = (f32 *)mtx; + s32 i; for (i = 0; i < 4; i++) { temp[ 0] = temp2[ 0] * s[0]; @@ -747,29 +473,6 @@ void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, register Vec3f s) { } } -/** - * Multiply a vector with a transformation matrix, which applies the transformation - * to the point. Note that the bottom row is assumed to be [0, 0, 0, 1], which is - * true for transformation matrices if the translation has a w component of 1. - */ -UNUSED void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) { - PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register f32 x = b[0]; - register f32 y = b[1]; - register f32 z = b[2]; - register f32 *temp2 = (f32 *)mtx; - register s32 i; - register s16 *c = b; - for (i = 0; i < 3; i++) { - c[0] = ((x * temp2[ 0]) - + (y * temp2[ 4]) - + (z * temp2[ 8]) - + temp2[12]); - c++; - temp2++; - } -} - /** * Set 'mtx' to a transformation matrix that rotates around the z axis. */ @@ -778,10 +481,10 @@ UNUSED void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) { ((s16 *) mtx)[a + 16] = (((s32) b) & 0xFFFF); void mtxf_rotate_xy(Mtx *mtx, s16 angle) { PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); - register s32 i = (coss(angle) * 0x10000); - register s32 j = (sins(angle) * 0x10000); - register f32 *temp = (f32 *)mtx; - register s32 k; + s32 i = (coss(angle) * 0x10000); + s32 j = (sins(angle) * 0x10000); + f32 *temp = (f32 *)mtx; + s32 k; for (k = 0; k < 16; k++) { *temp = 0; temp++; @@ -794,168 +497,13 @@ void mtxf_rotate_xy(Mtx *mtx, s16 angle) { ((s16 *) mtx)[15] = 1; } -/** - * Take the vector starting at 'from' pointed at 'to' an retrieve the length - * of that vector, as well as the yaw and pitch angles. - * Basically it converts the direction to spherical coordinates. - */ - -/// Finds the horizontal distance between two vectors. -void vec3f_get_lateral_dist(Vec3f from, Vec3f to, f32 *lateralDist) { - register f32 dx = (to[0] - from[0]); - register f32 dz = (to[2] - from[2]); - *lateralDist = sqrtf(sqr(dx) + sqr(dz)); -} - -/// Finds the squared horizontal distance between two vectors. Avoids a sqrtf call. -void vec3f_get_lateral_dist_squared(Vec3f from, Vec3f to, f32 *lateralDist) { - register f32 dx = (to[0] - from[0]); - register f32 dz = (to[2] - from[2]); - *lateralDist = (sqr(dx) + sqr(dz)); -} - -/// Finds the distance between two vectors. -void vec3f_get_dist(Vec3f from, Vec3f to, f32 *dist) { - Vec3f d; - vec3_diff(d, to, from); - *dist = vec3_mag(d); -} - -/// Finds the squared distance between two vectors. Avoids a sqrtf call. -void vec3f_get_dist_squared(Vec3f from, Vec3f to, f32 *dist) { - Vec3f d; - vec3_diff(d, to, from); - *dist = vec3_sumsq(d); -} - -/// Finds the distance and yaw etween two vectors. -void vec3f_get_dist_and_yaw(Vec3f from, Vec3f to, f32 *dist, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - *dist = vec3_mag(d); - *yaw = atan2s(d[2], d[0]); -} - -/// Finds the pitch between two vectors. -void vec3f_get_pitch(Vec3f from, Vec3f to, s16 *pitch) { - Vec3f d; - vec3_diff(d, to, from); - *pitch = atan2s(sqrtf(sqr(d[0]) + sqr(d[2])), d[1]); -} - -/// Finds the yaw between two vectors. -void vec3f_get_yaw(Vec3f from, Vec3f to, s16 *yaw) { - register f32 dx = (to[0] - from[0]); - register f32 dz = (to[2] - from[2]); - *yaw = atan2s(dz, dx); -} - -/// Finds the pitch and yaw between two vectors. -void vec3f_get_angle(Vec3f from, Vec3f to, s16 *pitch, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - *pitch = atan2s(sqrtf(sqr(d[0]) + sqr(d[2])), d[1]); - *yaw = atan2s(d[2], d[0]); -} - -/// Finds the horizontal distance and pitch between two vectors. -void vec3f_get_lateral_dist_and_pitch(Vec3f from, Vec3f to, f32 *lateralDist, s16 *pitch) { - Vec3f d; - vec3_diff(d, to, from); - *lateralDist = sqrtf(sqr(d[0]) + sqr(d[2])); - *pitch = atan2s(*lateralDist, d[1]); -} - -/// Finds the horizontal distance and yaw between two vectors. -void vec3f_get_lateral_dist_and_yaw(Vec3f from, Vec3f to, f32 *lateralDist, s16 *yaw) { - register f32 dx = (to[0] - from[0]); - register f32 dz = (to[2] - from[2]); - *lateralDist = sqrtf(sqr(dx) + sqr(dz)); - *yaw = atan2s(dz, dx); -} - -/// Finds the horizontal distance and angles between two vectors. -void vec3f_get_lateral_dist_and_angle(Vec3f from, Vec3f to, f32 *lateralDist, s16 *pitch, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - *lateralDist = sqrtf(sqr(d[0]) + sqr(d[2])); - *pitch = atan2s(*lateralDist, d[1]); - *yaw = atan2s(d[2], d[0]); -} - -/// Finds the distance and angles between two vectors. -void vec3f_get_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - register f32 xz = (sqr(d[0]) + sqr(d[2])); - *dist = sqrtf(xz + sqr(d[1])); - *pitch = atan2s(sqrtf(xz), d[1]); - *yaw = atan2s(d[2], d[0]); -} -void vec3s_get_dist_and_angle(Vec3s from, Vec3s to, s16 *dist, s16 *pitch, s16 *yaw) { - Vec3s d; - vec3_diff(d, to, from); - register f32 xz = (sqr(d[0]) + sqr(d[2])); - *dist = sqrtf(xz + sqr(d[1])); - *pitch = atan2s(sqrtf(xz), d[1]); - *yaw = atan2s(d[2], d[0]); -} -void vec3f_to_vec3s_get_dist_and_angle(Vec3f from, Vec3s to, f32 *dist, s16 *pitch, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - register f32 xz = (sqr(d[0]) + sqr(d[2])); - *dist = sqrtf(xz + sqr(d[1])); - *pitch = atan2s(sqrtf(xz), d[1]); - *yaw = atan2s(d[2], d[0]); -} - -/// Finds the distance, horizontal distance, and angles between two vectors. -void vec3f_get_dist_and_lateral_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, f32 *lateralDist, s16 *pitch, s16 *yaw) { - Vec3f d; - vec3_diff(d, to, from); - register f32 xz = (sqr(d[0]) + sqr(d[2])); - *dist = sqrtf(xz + sqr(d[1])); - *lateralDist = sqrtf(xz); - *pitch = atan2s(*lateralDist, d[1]); - *yaw = atan2s(d[2], d[0]); -} - -/** - * Construct the 'to' point which is distance 'dist' away from the 'from' position, - * and has the angles pitch and yaw. - */ -#define vec3_set_dist_and_angle(from, to, dist, pitch, yaw) { \ - register f32 dcos = (dist * coss(pitch)); \ - to[0] = (from[0] + (dcos * sins(yaw ))); \ - to[1] = (from[1] + (dist * sins(pitch))); \ - to[2] = (from[2] + (dcos * coss(yaw ))); \ -} -void vec3f_set_dist_and_angle(Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw) { - vec3_set_dist_and_angle(from, to, dist, pitch, yaw); -} -void vec3s_set_dist_and_angle(Vec3s from, Vec3s to, s16 dist, s16 pitch, s16 yaw) { - vec3_set_dist_and_angle(from, to, dist, pitch, yaw); -} - /** * Similar to approach_s32, but converts to s16 and allows for overflow between 32767 and -32768 */ -s16 approach_angle(s16 current, s16 target, s16 inc) { - s32 dist = (s16)(target - current); - if (dist < 0) { - dist += inc; - if (dist > 0) dist = 0; - } else if (dist > 0) { - dist -= inc; - if (dist < 0) dist = 0; - } - return (target - dist); -} -Bool32 approach_angle_bool(s16 *current, s16 target, s16 inc) { - *current = approach_angle(*current, target, inc); +Bool32 approach_s16_bool(s16 *current, s16 target, s16 inc, s16 dec) { + *current = approach_s16(*current, target, inc, dec); return (*current != target); } - s16 approach_s16(s16 current, s16 target, s16 inc, s16 dec) { s16 dist = (target - current); if (dist >= 0) { // target >= current @@ -965,15 +513,15 @@ s16 approach_s16(s16 current, s16 target, s16 inc, s16 dec) { } return current; } -Bool32 approach_s16_bool(s16 *current, s16 target, s16 inc, s16 dec) { - *current = approach_s16(*current, target, inc, dec); - return (*current != target); -} /** * Return the value 'current' after it tries to approach target, going up at * most 'inc' and going down at most 'dec'. */ +Bool32 approach_s32_bool(s32 *current, s32 target, s32 inc, s32 dec) { + *current = approach_s32(*current, target, inc, dec); + return (*current != target); +} s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) { s32 dist = (target - current); if (dist > 0) { // current < target @@ -983,15 +531,15 @@ s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec) { } return current; } -Bool32 approach_s32_bool(s32 *current, s32 target, s32 inc, s32 dec) { - *current = approach_s32(*current, target, inc, dec); - return (*current != target); -} /** * Return the value 'current' after it tries to approach target, going up at * most 'inc' and going down at most 'dec'. */ +Bool32 approach_f32_bool(f32 *current, f32 target, f32 inc, f32 dec) { + *current = approach_f32(*current, target, inc, dec); + return !(*current == target); +} f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) { f32 dist = (target - current); if (dist >= 0.0f) { // target >= current @@ -1001,10 +549,6 @@ f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec) { } return current; } -Bool32 approach_f32_bool(f32 *current, f32 target, f32 inc, f32 dec) { - *current = approach_f32(*current, target, inc, dec); - return !(*current == target); -} s32 approach_f32_signed(f32 *current, f32 target, f32 inc) { *current += inc; @@ -1077,7 +621,7 @@ s16 approach_s16_asymptotic(s16 current, s16 target, s16 divisor) { } s16 abs_angle_diff(s16 a0, s16 a1) { - register s16 diff = (a1 - a0); + s16 diff = (a1 - a0); if (diff == -0x8000) return 0x7FFF; return abss(diff); } @@ -1334,7 +878,7 @@ s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface // Successful contact. // Make 'add_dir' into 'dir' scaled by 'length'. Vec3f add_dir; - vec3_prod_val(add_dir, dir, *length); + vec3_scale_dest(add_dir, dir, *length); // Make 'hit_pos' into the sum of 'orig' and 'add_dir'. vec3f_sum(hit_pos, orig, add_dir); return TRUE; diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 7a80952b..5554791a 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -4,6 +4,7 @@ #include #include "types.h" +#include "game/puppyprint.h" #define NEAR_ZERO __FLT_EPSILON__ #define NEAR_ONE (1.0f - __FLT_EPSILON__) @@ -22,26 +23,18 @@ extern Vec3i gVec3iZero; extern Vec3f gVec3fOne; extern Vec3s gVec3sOne; + +// Angles + /** * Converts an angle in degrees to sm64's s16 angle units. For example, DEGREES(90) == 0x4000 * This should be used mainly to make camera code clearer at first glance. */ // #define DEGREES(x) ((x) * 0x10000 / 360) #define DEGREES(x) ((x) * 0x2000 / 45) -// #define DEGREES(x) (((x) << 13) / 45) -/* - * The sine and cosine tables overlap, but "#define gCosineTable (gSineTable + - * 0x400)" doesn't give expected codegen; gSineTable and gCosineTable need to - * be different symbols for code to match. Most likely the tables were placed - * adjacent to each other, and gSineTable cut short, such that reads overflow - * into gCosineTable. - * - * These kinds of out of bounds reads are undefined behavior, and break on - * e.g. GCC (which doesn't place the tables next to each other, and probably - * exploits array sizes for range analysis-based optimizations as well). - * Thus, for non-IDO compilers we use the standard-compliant version. - */ +// Trig functions + extern f32 gSineTable[]; #define gCosineTable (gSineTable + 0x400) @@ -51,6 +44,8 @@ extern f32 gSineTable[]; #define cots(x) (coss(x) / sins(x)) #define atans(x) gArctanTable[(s32)((((x) * 1024) + 0.5f))] // is this correct? used for atan2_lookup +// Angle conversion macros + #define RAD_PER_DEG (M_PI / 180.0f) #define DEG_PER_RAD (180.0f / M_PI) @@ -61,90 +56,121 @@ extern f32 gSineTable[]; #define degrees_to_radians(x) (f32)( (f32)(x) * RAD_PER_DEG ) #define radians_to_degrees(x) (f32)( (f32)(x) * DEG_PER_RAD ) -#define signum_positive(x) ((x < 0) ? -1 : 1) -// #define min(a, b) MIN((a), (b)) // ((a) < (b) ? (a) : (b)) -// #define max(a, b) MAX((a), (b)) // ((a) > (b) ? (a) : (b)) -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) +// Various basic helper macros -// from limits.h -#define S8_MAX __SCHAR_MAX__ -#define S8_MIN (-S8_MAX - 1) -#define U8_MAX (S8_MAX * 2 + 1) -#define S16_MAX __SHRT_MAX__ -#define S16_MIN (-S16_MAX - 1) -#define U16_MAX (S16_MAX * 2 + 1) -#define S32_MAX __INT_MAX__ -#define S32_MIN (-S32_MAX - 1) -#define U32_MAX (S32_MAX * 2U + 1U) -#define S64_MAX __LONG_LONG_MAX__ -#define S64_MIN (-S64_MAX - 1LL) -#define U64_MAX (S64_MAX * 2ULL + 1ULL) -#define F32_MAX __FLT_MAX__ -#define F32_MIN __FLT_MIN__ -#define F64_MAX __DBL_MAX__ -#define F64_MIN __DBL_MIN__ +// Get the square of a number +#define sqr(x) ({ \ + __auto_type _x = (x); \ + _x * _x; }) -#define CLAMP_U8( x) CLAMP((x), 0x0, U8_MAX) +// Get the sign of a number +#define signum_positive(x) (((x) < 0) ? -1 : 1) + +// Absolute value +#define ABS(x) ({ \ + __auto_type _x = (x); \ + _x > 0 ? _x : -_x; }) +#define absi ABS +#define abss ABS + +// Absolute value of a float (faster than using the above macro) +ALWAYS_INLINE f32 absf(f32 in) { + f32 out; + __asm__("abs.s %0,%1" : "=f" (out) : "f" (in)); + return out; +} + +// Get the minimum / maximum of a set of numbers +#undef MIN +#define MIN(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a < _b ? _a : _b; }) + +#undef MAX +#define MAX(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a > _b ? _a : _b; }) + +#define min_3(a, b, c) MIN(MIN(a, b), c) + +#define max_3(a, b, c) MAX(MAX(a, b), c) + +#define min_3f min_3 +#define min_3i min_3 +#define min_3s min_3 + +#define max_3f max_3 +#define max_3i max_3 +#define max_3s max_3 + +void min_max_3f(f32 a, f32 b, f32 c, f32 *min, f32 *max); +void min_max_3i(s32 a, s32 b, s32 c, s32 *min, s32 *max); +void min_max_3s(s16 a, s16 b, s16 c, s16 *min, s16 *max); + +// From Wiseguy +// Round a float to the nearest integer +ALWAYS_INLINE s32 roundf(f32 in) { + f32 tmp; + s32 out; + __asm__("round.w.s %0,%1" : "=f" (tmp) : "f" (in )); + __asm__("mfc1 %0,%1" : "=r" (out) : "f" (tmp)); + return out; +} + +#define round_float roundf + +#define FLT_IS_NONZERO(x) (absf(x) > NEAR_ZERO) + + +// Integer limits and clamping + +#define S8_MAX 127 +#define S8_MIN -128 +#define U8_MAX 255 +#define S16_MAX 32767 +#define S16_MIN -32768 +#define U16_MAX 65535 +#define S32_MAX 2147483647 +#define S32_MIN -2147483648 +#define U32_MAX 4294967295 + +// Clamp a value inbetween a range +#define CLAMP(x, low, high) MIN(MAX((x), (low)), (high)) + +// Clamp a value to the range of a specific data type +#define CLAMP_U8( x) CLAMP((x), 0, U8_MAX) #define CLAMP_S8( x) CLAMP((x), S8_MIN, S8_MAX) -#define CLAMP_U16(x) CLAMP((x), 0x0, U16_MAX) +#define CLAMP_U16(x) CLAMP((x), 0, U16_MAX) #define CLAMP_S16(x) CLAMP((x), S16_MIN, S16_MAX) -#define CLAMP_U32(x) CLAMP((x), 0x0, U32_MAX) -#define CLAMP_S32(x) CLAMP((x), S32_MIN, S32_MAX) -#define CLAMP_U64(x) CLAMP((x), 0x0, U64_MAX) -#define CLAMP_S64(x) CLAMP((x), S64_MIN, S64_MAX) -#define CLAMP_F32(x) CLAMP((x), F32_MIN, F32_MAX) -#define CLAMP_F64(x) CLAMP((x), F64_MIN, F64_MAX) -#define SWAP(a, b) { ((a) ^= (b)); ((b) ^= (a)); ((a) ^= (b)); } -#define sqr(x) ( (x) * (x)) -#define cube(x) ( sqr(x) * (x)) -#define quad(x) (cube(x) * (x)) - -#define average_2(a, b ) (((a) + (b) ) / 2.0f) -#define average_3(a, b, c ) (((a) + (b) + (c) ) / 3.0f) -#define average_4(a, b, c, d) (((a) + (b) + (c) + (d)) / 4.0f) +// Vector operations +// Set all elements of a vector to the same constant #define vec2_same(v, s) (((v)[0]) = ((v)[1]) = (s)) #define vec3_same(v, s) (((v)[0]) = ((v)[1]) = ((v)[2]) = (s)) #define vec4_same(v, s) (((v)[0]) = ((v)[1]) = ((v)[2]) = ((v)[3]) = (s)) +// Set all elements of a vector to zero #define vec2_zero(v) (vec2_same((v), 0)) #define vec3_zero(v) (vec3_same((v), 0)) #define vec4_zero(v) (vec4_same((v), 0)) -#define vec2_c(v) ( (v)[0] + (v)[1]) -#define vec3_c(v) (vec2_c(v) + (v)[2]) -#define vec4_c(v) (vec3_c(v) + (v)[3]) - -#define vec2_average(v) (vec2_c(v) / 2.0f) -#define vec3_average(v) (vec3_c(v) / 3.0f) -#define vec4_average(v) (vec4_c(v) / 4.0f) - -#define vec2_sumsq(v) ( sqr((v)[0]) + sqr((v)[1])) -#define vec3_sumsq(v) (vec2_sumsq(v) + sqr((v)[2])) -#define vec4_sumsq(v) (vec3_sumsq(v) + sqr((v)[3])) +// Sum of the squares of all elements of a vector +#define vec2_sumsq(v) (sqr((v)[0]) + sqr((v)[1])) +#define vec3_sumsq(v) (sqr((v)[0]) + sqr((v)[1]) + sqr((v)[2])) +#define vec4_sumsq(v) (sqr((v)[0]) + sqr((v)[1]) + sqr((v)[2]) + sqr((v)[3])) +// Calculate the magnitude of a vector #define vec2_mag(v) (sqrtf(vec2_sumsq(v))) #define vec3_mag(v) (sqrtf(vec3_sumsq(v))) #define vec4_mag(v) (sqrtf(vec4_sumsq(v))) -#define vec3_yaw(from, to) (atan2s(((to)[2] - (from)[2]), ((to)[0] - (from)[0]))) - -#define vec2_dot(a, b) (((a)[0] * (b)[0]) + ((a)[1] * (b)[1])) -#define vec3_dot(a, b) (vec2_dot((a), (b)) + ((a)[2] * (b)[2])) -#define vec4_dot(a, b) (vec3_dot((a), (b)) + ((a)[3] * (b)[3])) - -/// Make vector 'dest' the cross product of vectors a and b. -#define vec3_cross(dst, a, b) { \ - (dst)[0] = (((a)[1] * (b)[2]) - ((a)[2] * (b)[1])); \ - (dst)[1] = (((a)[2] * (b)[0]) - ((a)[0] * (b)[2])); \ - (dst)[2] = (((a)[0] * (b)[1]) - ((a)[1] * (b)[0])); \ -} - /** - * Set 'dest' the normal vector of a triangle with vertices a, b and c. + * Set 'dest' to the normal vector of a triangle with vertices a, b and c. * Equivalent to cross((c-b), (c-a)). */ #define find_vector_perpendicular_to_plane(dest, a, b, c) { \ @@ -153,247 +179,413 @@ extern f32 gSineTable[]; (dest)[2] = ((b)[0] - (a)[0]) * ((c)[1] - (b)[1]) - ((c)[0] - (b)[0]) * ((b)[1] - (a)[1]); \ } -/** - * | ? ? ? 0 | - * | ? ? ? 0 | - * | ? ? ? 0 | - * | 0 0 0 1 | - * i.e. a matrix representing a linear transformation over 3 space. - */ -// Multiply a vector by a matrix of the form -#define linear_mtxf_mul_vec3(mtx, dstV, srcV) { \ - (dstV)[0] = (((mtx)[0][0] * (srcV)[0]) + ((mtx)[1][0] * (srcV)[1]) + ((mtx)[2][0] * (srcV)[2]));\ - (dstV)[1] = (((mtx)[0][1] * (srcV)[0]) + ((mtx)[1][1] * (srcV)[1]) + ((mtx)[2][1] * (srcV)[2]));\ - (dstV)[2] = (((mtx)[0][2] * (srcV)[0]) + ((mtx)[1][2] * (srcV)[1]) + ((mtx)[2][2] * (srcV)[2]));\ -} - -#define linear_mtxf_mul_vec3_and_translate(mtx, dstV, srcV) { \ - linear_mtxf_mul_vec3((mtx), (dstV), (srcV)); \ - vec3_add((dstV), (mtx)[3]); \ -} - -// Multiply a vector by the transpose of a matrix of the form -#define linear_mtxf_transpose_mul_vec3(mtx, dstV, srcV) { \ - (dstV)[0] = vec3_dot((mtx)[0], (srcV)); \ - (dstV)[1] = vec3_dot((mtx)[1], (srcV)); \ - (dstV)[2] = vec3_dot((mtx)[2], (srcV)); \ -} - +// Set the elements of vector 'dst' to the given values #define vec2_set(dst, x, y) { \ (dst)[0] = (x); \ (dst)[1] = (y); \ } #define vec3_set(dst, x, y, z) { \ - vec2_set((dst), (x), (y)); \ + (dst)[0] = (x); \ + (dst)[1] = (y); \ (dst)[2] = (z); \ } #define vec4_set(dst, x, y, z, w) { \ - vec3_set((dst), (x), (y), (z)); \ + (dst)[0] = (x); \ + (dst)[1] = (y); \ + (dst)[2] = (z); \ (dst)[3] = (w); \ } +#define vec3f_set vec3_set +#define vec3i_set vec3_set +#define vec3s_set vec3_set + +// Copy vector 'src' to vector 'dst' #define vec2_copy(dst, src) { \ - (dst)[0] = (src)[0]; \ - (dst)[1] = (src)[1]; \ + __auto_type _x = (src)[0]; \ + __auto_type _y = (src)[1]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } #define vec3_copy(dst, src) { \ - vec2_copy((dst), (src)); \ - (dst)[2] = (src)[2]; \ + __auto_type _x = (src)[0]; \ + __auto_type _y = (src)[1]; \ + __auto_type _z = (src)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } #define vec4_copy(dst, src) { \ - vec3_copy((dst), (src)); \ - (dst)[3] = (src)[3]; \ + __auto_type _x = (src)[0]; \ + __auto_type _y = (src)[1]; \ + __auto_type _z = (src)[2]; \ + __auto_type _w = (src)[3]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } +#define vec3f_copy vec3_copy +#define vec3i_copy vec3_copy +#define vec3s_copy vec3_copy +#define vec3s_to_vec3i vec3_copy +#define vec3s_to_vec3f vec3_copy +#define vec3i_to_vec3s vec3_copy +#define vec3i_to_vec3f vec3_copy +#define vec3f_to_vec3s vec3_copy +#define vec3f_to_vec3i vec3_copy + +#define surface_normal_to_vec3f(dst, surf) vec3f_copy((dst), &((surf)->normal.x)) + +// Copy vector 'src' to vector 'dst' and add a scalar to the y component #define vec3_copy_y_off(dst, src, y) { \ - (dst)[0] = (src)[0]; \ - (dst)[1] = ((src)[1] + (y)); \ - (dst)[2] = (src)[2]; \ + __auto_type _x = (src)[0]; \ + __auto_type _y = (src)[1] + (y); \ + __auto_type _z = (src)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec2_copy_roundf(dst, src) { \ - (dst)[0] = roundf((src)[0]); \ - (dst)[1] = roundf((src)[1]); \ +#define vec3f_copy_y_off vec3_copy_y_off + +// Set vector 'dst' to the sum of vectors 'src1' and 'src2' +#define vec2_sum(dst, src1, src2) { \ + __auto_type _x = (src1)[0] + (src2)[0]; \ + __auto_type _y = (src1)[1] + (src2)[1]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } -#define vec3_copy_roundf(dst, src) { \ - vec2_copy_roundf((dst), (src)); \ - (dst)[2] = roundf((src)[2]); \ +#define vec3_sum(dst, src1, src2) { \ + __auto_type _x = (src1)[0] + (src2)[0]; \ + __auto_type _y = (src1)[1] + (src2)[1]; \ + __auto_type _z = (src1)[2] + (src2)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec4_copy_roundf(dst, src) { \ - vec3_copy_roundf((dst), (src)); \ - (dst)[3] = roundf((src)[3]); \ +#define vec4_sum(dst, src1, src2) { \ + __auto_type _x = (src1)[0] + (src2)[0]; \ + __auto_type _y = (src1)[1] + (src2)[1]; \ + __auto_type _z = (src1)[2] + (src2)[2]; \ + __auto_type _w = (src1)[3] + (src2)[3]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } -#define vec2_copy_inverse(dst, src) { \ - (dst)[0] = (src)[1]; \ - (dst)[1] = (src)[0]; \ -} -#define vec3_copy_inverse(dst, src) { \ - (dst)[0] = (src)[2]; \ - (dst)[1] = (src)[1]; \ - (dst)[2] = (src)[0]; \ -} -#define vec4_copy_inverse(dst, src) { \ - (dst)[0] = (src)[3]; \ - (dst)[1] = (src)[2]; \ - (dst)[2] = (src)[1]; \ - (dst)[3] = (src)[0]; \ -} - -#define vec3_copy_offset_m1(dst, src) { \ - (dst)[0] = (src)[1]; \ - (dst)[1] = (src)[2]; \ - (dst)[2] = (src)[0]; \ -} - -#define vec2_copy_negative(dst, src) { \ - (dst)[0] = -(src)[0]; \ - (dst)[1] = -(src)[1]; \ -} -#define vec3_copy_negative(dst, src) { \ - vec2_copy_negative((dst), (src)); \ - (dst)[2] = -(src)[2]; \ -} -#define vec4_copy_negative(dst, src) { \ - vec3_copy_negative((dst), (src)); \ - (dst)[3] = -(src)[3]; \ -} - -#define vec2_sum(dst, src1, src2) { \ - (dst)[0] = ((src1)[0] + (src2)[0]); \ - (dst)[1] = ((src1)[1] + (src2)[1]); \ -} -#define vec3_sum(dst, src1, src2) { \ - vec2_sum((dst), (src1), (src2)); \ - (dst)[2] = ((src1)[2] + (src2)[2]); \ -} -#define vec4_sum(dst, src1, src2) { \ - vec3_sum((dst), (src1), (src2)); \ - (dst)[3] = ((src1)[3] + (src2)[3]); \ -} +#define vec3f_sum vec3_sum +#define vec3i_sum vec3_sum +#define vec3s_sum vec3_sum +// Add the vector 'src' to vector 'dst' #define vec2_add(dst, src) vec2_sum((dst), (dst), (src)) #define vec3_add(dst, src) vec3_sum((dst), (dst), (src)) #define vec4_add(dst, src) vec4_sum((dst), (dst), (src)) -#define vec2_sum_val(dst, src, x) { \ - (dst)[0] = ((src)[0] + (x)); \ - (dst)[1] = ((src)[1] + (x)); \ +#define vec3f_add vec3_add +#define vec3i_add vec3_add +#define vec3s_add vec3_add + +// Set vector 'dst' to the difference of vectors 'src1' and 'src2' +#define vec2_diff(dst, src1, src2) { \ + __auto_type _x = (src1)[0] - (src2)[0]; \ + __auto_type _y = (src1)[1] - (src2)[1]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } -#define vec3_sum_val(dst, src, x) { \ - vec2_sum_val((dst), (src), (x)); \ - (dst)[2] = ((src)[2] + (x)); \ +#define vec3_diff(dst, src1, src2) { \ + __auto_type _x = (src1)[0] - (src2)[0]; \ + __auto_type _y = (src1)[1] - (src2)[1]; \ + __auto_type _z = (src1)[2] - (src2)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec4_sum_val(dst, src, x) { \ - vec3_sum_val((dst), (src), (x)); \ - (dst)[3] = ((src)[2] + (x)); \ +#define vec4_diff(dst, src1, src2) { \ + __auto_type _x = (src1)[0] - (src2)[0]; \ + __auto_type _y = (src1)[1] - (src2)[1]; \ + __auto_type _z = (src1)[2] - (src2)[2]; \ + __auto_type _w = (src1)[3] - (src2)[3]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } -#define vec2_add_val(dst, x) vec2_sum_val((dst), (dst), (x)) -#define vec3_add_val(dst, x) vec3_sum_val((dst), (dst), (x)) -#define vec4_add_val(dst, x) vec4_sum_val((dst), (dst), (x)) - -#define vec2_diff(dst, src1, src2) { \ - (dst)[0] = ((src1)[0] - (src2)[0]); \ - (dst)[1] = ((src1)[1] - (src2)[1]); \ -} -#define vec3_diff(dst, src1, src2) { \ - vec2_diff((dst), (src1), (src2)); \ - (dst)[2] = ((src1)[2] - (src2)[2]); \ -} -#define vec4_diff(dst, src1, src2) { \ - vec3_diff((dst), (src1), (src2)); \ - (dst)[3] = ((src1)[3] - (src2)[3]); \ -} +#define vec3f_diff vec3_diff +#define vec3i_diff vec3_diff +#define vec3s_diff vec3_diff +// Subtract the vector 'src' from vector 'dst' #define vec2_sub(dst, src) vec2_diff((dst), (dst), (src)) #define vec3_sub(dst, src) vec3_diff((dst), (dst), (src)) #define vec4_sub(dst, src) vec4_diff((dst), (dst), (src)) -#define vec2_diff_val(dst, src, x) { \ - (dst)[0] = ((src)[0] - (x)); \ - (dst)[1] = ((src)[1] - (x)); \ +#define vec3f_sub vec3_sub +#define vec3i_sub vec3_sub +#define vec3s_sub vec3_sub + +// Set vector 'dst' to the product of vectors 'src1' and 'src2' +#define vec2_prod(dst, src1, src2) { \ + __auto_type _x = (src1)[0] * (src2)[0]; \ + __auto_type _y = (src1)[1] * (src2)[1]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } -#define vec3_diff_val(dst, src, x) { \ - vec2_diff_val((dst), (src), (x)); \ - (dst)[2] = ((src)[2] - (x)); \ +#define vec3_prod(dst, src1, src2) { \ + __auto_type _x = (src1)[0] * (src2)[0]; \ + __auto_type _y = (src1)[1] * (src2)[1]; \ + __auto_type _z = (src1)[2] * (src2)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec4_diff_val(dst, src, x) { \ - vec3_diff_val((dst), (src), (x)); \ - (dst)[3] = ((src)[3] - (x)); \ +#define vec4_prod(dst, src1, src2) { \ + __auto_type _x = (src1)[0] * (src2)[0]; \ + __auto_type _y = (src1)[1] * (src2)[1]; \ + __auto_type _z = (src1)[2] * (src2)[2]; \ + __auto_type _w = (src1)[3] * (src2)[3]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } -#define vec2_sub_val(dst, x) vec2_diff_val((dst), (dst), (x)) -#define vec3_sub_val(dst, x) vec3_diff_val((dst), (dst), (x)) -#define vec4_sub_val(dst, x) vec4_diff_val((dst), (dst), (x)) - -#define vec2_prod(dst, src1, src2) { \ - (dst)[0] = ((src1)[0] * (src2)[0]); \ - (dst)[1] = ((src1)[1] * (src2)[1]); \ -} -#define vec3_prod(dst, src1, src2) { \ - vec2_prod((dst), (src1), (src2)); \ - (dst)[2] = ((src1)[2] * (src2)[2]); \ -} -#define vec4_prod(dst, src1, src2) { \ - vec3_prod((dst), (src1), (src2)); \ - (dst)[3] = ((src1)[3] * (src2)[3]); \ -} +#define vec3f_prod vec3_prod +#define vec3i_prod vec3_prod +#define vec3s_prod vec3_prod +// Multiply vector 'dst' by vector 'src' #define vec2_mul(dst, src) vec2_prod((dst), (dst), (src)) #define vec3_mul(dst, src) vec3_prod((dst), (dst), (src)) #define vec4_mul(dst, src) vec4_prod((dst), (dst), (src)) -#define vec2_prod_val(dst, src, x) { \ - (dst)[0] = ((src)[0] * (x)); \ - (dst)[1] = ((src)[1] * (x)); \ +#define vec3f_mul vec3_mul +#define vec3i_mul vec3_mul +#define vec3s_mul vec3_mul + +// Set vector 'dst' to vector 'src' scaled by the scalar 'x' +#define vec2_scale_dest(dst, src, x) { \ + __auto_type _x = (src)[0] * (x); \ + __auto_type _y = (src)[1] * (x); \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } -#define vec3_prod_val(dst, src, x) { \ - vec2_prod_val((dst), (src), (x)); \ - (dst)[2] = ((src)[2] * (x)); \ +#define vec3_scale_dest(dst, src, x) { \ + __auto_type _x = (src)[0] * (x); \ + __auto_type _y = (src)[1] * (x); \ + __auto_type _z = (src)[2] * (x); \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec4_prod_val(dst, src, x) { \ - vec3_prod_val((dst), (src), (x)); \ - (dst)[3] = ((src)[3] * (x)); \ +#define vec4_scale_dest(dst, src, x) { \ + __auto_type _x = (src)[0] * (x); \ + __auto_type _y = (src)[1] * (x); \ + __auto_type _z = (src)[2] * (x); \ + __auto_type _w = (src)[3] * (x); \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } -#define vec2_mul_val(dst, x) vec2_prod_val(dst, dst, x) -#define vec3_mul_val(dst, x) vec3_prod_val(dst, dst, x) -#define vec4_mul_val(dst, x) vec4_prod_val(dst, dst, x) +// Scale vector 'dst' by the scalar 'x' +#define vec2_scale(dst, x) vec2_scale_dest(dst, dst, x) +#define vec3_scale(dst, x) vec3_scale_dest(dst, dst, x) +#define vec4_scale(dst, x) vec4_scale_dest(dst, dst, x) -#define vec2_quot(dst, src1, src2) { \ - (dst)[0] = ((src1)[0] / (src2)[0]); \ - (dst)[1] = ((src1)[1] / (src2)[1]); \ +// Set vector 'dst' to vector 'src1' divided by vector 'src2' +#define vec2_quot(dst, src1, src2) { \ + __auto_type _x = (src1)[0] / (src2)[0]; \ + __auto_type _y = (src1)[1] / (src2)[1]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ } -#define vec3_quot(dst, src1, src2) { \ - vec2_quot((dst), (src1), (src2)); \ - (dst)[2] = ((src1)[2] / (src2)[2]); \ +#define vec3_quot(dst, src1, src2) { \ + __auto_type _x = (src1)[0] / (src2)[0]; \ + __auto_type _y = (src1)[1] / (src2)[1]; \ + __auto_type _z = (src1)[2] / (src2)[2]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec4_quot(dst, src1, src2) { \ - vec3_quot((dst), (src1), (src2)); \ - (dst)[3] = ((src1)[3] / (src2)[3]); \ +#define vec4_quot(dst, src1, src2) { \ + __auto_type _x = (src1)[0] / (src2)[0]; \ + __auto_type _y = (src1)[1] / (src2)[1]; \ + __auto_type _z = (src1)[2] / (src2)[2]; \ + __auto_type _w = (src1)[3] / (src2)[3]; \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ + (dst)[3] = _w; \ } +#define vec3f_quot vec3_quot +#define vec3i_quot vec3_quot +#define vec3s_quot vec3_quot + +// Divide vector 'dst' by vector 'src' #define vec2_div(dst, src) vec2_quot((dst), (dst), (src)) #define vec3_div(dst, src) vec3_quot((dst), (dst), (src)) #define vec4_div(dst, src) vec4_quot((dst), (dst), (src)) -#define vec2_quot_val(dst, src, x) { \ - (dst)[0] = ((src)[0] / (x)); \ - (dst)[1] = ((src)[1] / (x)); \ -} -#define vec3_quot_val(dst, src, x) { \ - vec2_quot_val((dst), (src), (x)); \ - (dst)[2] = ((src)[2] / (x)); \ -} -#define vec4_quot_val(dst, src, x) { \ - vec3_quot_val((dst), (src), (x)); \ - (dst)[3] = ((src)[3] / (x)); \ +#define vec3f_div vec3_div +#define vec3i_div vec3_div +#define vec3s_div vec3_div + +// The yaw between two points in 3D space +#define vec3_yaw(from, to) (atan2s(((to)[2] - (from)[2]), ((to)[0] - (from)[0]))) + +// Calculate the dot product of two vectors +#define vec2_dot(a, b) (((a)[0] * (b)[0]) + ((a)[1] * (b)[1])) +#define vec3_dot(a, b) (vec2_dot((a), (b)) + ((a)[2] * (b)[2])) +#define vec4_dot(a, b) (vec3_dot((a), (b)) + ((a)[3] * (b)[3])) + +#define vec3f_dot vec3_dot + +// Make vector 'dest' the cross product of vectors a and b. +#define vec3_cross(dst, a, b) { \ + __auto_type _x = ((a)[1] * (b)[2]) - ((a)[2] * (b)[1]); \ + __auto_type _y = ((a)[2] * (b)[0]) - ((a)[0] * (b)[2]); \ + __auto_type _z = ((a)[0] * (b)[1]) - ((a)[1] * (b)[0]); \ + (dst)[0] = _x; \ + (dst)[1] = _y; \ + (dst)[2] = _z; \ } -#define vec2_div_val(dst, x) vec2_quot_val((dst), (dst), (x)) -#define vec3_div_val(dst, x) vec3_quot_val((dst), (dst), (x)) -#define vec4_div_val(dst, x) vec4_quot_val((dst), (dst), (x)) +#define vec3f_cross vec3_cross + +// Scale vector 'v' so it has length 1 +#define vec3_normalize(v) { \ + f32 _v_invmag = vec3_mag((v)); \ + _v_invmag = (1.0f / MAX(_v_invmag, NEAR_ZERO)); \ + vec3_scale((v), _v_invmag); \ +} + +#define vec3f_normalize vec3_normalize + +// If the magnitude of vector 'v' is greater than 'max', scale it down to 'max' +#define vec3_set_max_dist(v, max) { \ + f32 _v_mag = vec3_mag(v); \ + f32 _max = max; \ + _v_mag = MAX(_v_mag, NEAR_ZERO); \ + if (_v_mag > _max) { \ + _v_mag = (_max / _v_mag); \ + vec3_scale(v, _v_mag); \ + } \ +} + +// Transform the vector 'srcV' by the matrix 'mtx' and store the result in 'dstV'. Ignores translation. +#define linear_mtxf_mul_vec3(mtx, dstV, srcV) { \ + PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); \ + __auto_type _x = ((mtx)[0][0] * (srcV)[0]) + ((mtx)[1][0] * (srcV)[1]) + ((mtx)[2][0] * (srcV)[2]); \ + __auto_type _y = ((mtx)[0][1] * (srcV)[0]) + ((mtx)[1][1] * (srcV)[1]) + ((mtx)[2][1] * (srcV)[2]); \ + __auto_type _z = ((mtx)[0][2] * (srcV)[0]) + ((mtx)[1][2] * (srcV)[1]) + ((mtx)[2][2] * (srcV)[2]); \ + (dstV)[0] = _x; \ + (dstV)[1] = _y; \ + (dstV)[2] = _z; \ +} + +// Transform the vector 'srcV' by the matrix 'mtx' including translation, and store the result in 'dstV' +#define linear_mtxf_mul_vec3_and_translate(mtx, dstV, srcV) { \ + linear_mtxf_mul_vec3((mtx), (dstV), (srcV)); \ + vec3_add((dstV), (mtx)[3]); \ +} + +// Transform the vector 'srcV' by the transpose of the matrix 'mtx' +// and store the result in 'dstV'. Ignores translation. +// For most transformation matrices, this will apply the inverse of the transformation. +#define linear_mtxf_transpose_mul_vec3(mtx, dstV, srcV) { \ + PUPPYPRINT_ADD_COUNTER(gPuppyCallCounter.matrix); \ + __auto_type _x = vec3_dot((mtx)[0], (srcV)); \ + __auto_type _y = vec3_dot((mtx)[1], (srcV)); \ + __auto_type _z = vec3_dot((mtx)[2], (srcV)); \ + (dstV)[0] = _x; \ + (dstV)[1] = _y; \ + (dstV)[2] = _z; \ +} + +#define linear_mtxf_mul_vec3f linear_mtxf_mul_vec3 +#define linear_mtxf_mul_vec3f_and_translate linear_mtxf_mul_vec3_and_translate +#define linear_mtxf_transpose_mul_vec3f linear_mtxf_transpose_mul_vec3 + + +// Angles and distances between vectors + +/// Finds the distance between two vectors +#define vec3_get_dist(from, to, dist) { \ + Vec3f _d; \ + vec3_diff(_d, (to), (from)); \ + *(dist) = vec3_mag((_d)); \ +} + +#define vec3f_get_dist vec3_get_dist +#define vec3s_get_dist vec3_get_dist + +/// Finds the horizontal distance between two vectors +#define vec3_get_lateral_dist(from, to, lateralDist) { \ + Vec3f _d; \ + vec3_diff(_d, (to), (from)); \ + *(lateralDist) = sqrtf(sqr(_d[0]) + sqr(_d[2])); \ +} + +#define vec3f_get_lateral_dist vec3_get_lateral_dist +#define vec3s_get_lateral_dist vec3_get_lateral_dist + +/// Finds the pitch between two vectors +#define vec3_get_pitch(from, to, pitch) { \ + Vec3f _d; \ + vec3_diff(_d, (to), (from)); \ + *(pitch) = atan2s(sqrtf(sqr(_d[0]) + sqr(_d[2])), _d[1]); \ +} + +#define vec3f_get_pitch vec3_get_pitch +#define vec3s_get_pitch vec3_get_pitch + +/// Finds the yaw between two vectors +#define vec3_get_yaw(from, to, yaw) { \ + f32 _dx = ((to)[0] - (from)[0]); \ + f32 _dz = ((to)[2] - (from)[2]); \ + *(yaw) = atan2s(_dz, _dx); \ +} + +#define vec3f_get_yaw vec3_get_yaw +#define vec3s_get_yaw vec3_get_yaw + +// Finds the distance, pitch, and yaw between two vectors +#define vec3_get_dist_and_angle(from, to, dist, pitch, yaw) { \ + Vec3f _d; \ + vec3f_diff(_d, (to), (from)); \ + f32 _xz = (sqr(_d[0]) + sqr(_d[2])); \ + *(dist) = sqrtf(_xz + sqr(_d[1])); \ + *(pitch) = atan2s(sqrtf(_xz), _d[1]); \ + *(yaw) = atan2s(_d[2], _d[0]); \ +} + +#define vec3f_get_dist_and_angle vec3_get_dist_and_angle +#define vec3s_get_dist_and_angle vec3_get_dist_and_angle + +// Constructs the 'to' point which is distance 'dist' away from the 'from' position, +// and has the angles pitch and yaw. +#define vec3_set_dist_and_angle(from, to, dist, pitch, yaw) { \ + f32 _dcos = ((dist) * coss(pitch)); \ + __auto_type _x = ((from)[0] + (_dcos * sins(yaw))); \ + __auto_type _y = ((from)[1] + ((dist) * sins(pitch))); \ + __auto_type _z = ((from)[2] + (_dcos * coss(yaw))); \ + (to)[0] = _x; \ + (to)[1] = _y; \ + (to)[2] = _z; \ +} + +#define vec3f_set_dist_and_angle vec3_set_dist_and_angle +#define vec3s_set_dist_and_angle vec3_set_dist_and_angle + + +// Matrices #define MAT4_VEC_DOT_PROD(R, A, B, row, col) { \ (R)[(row)][(col)] = ((A)[(row)][0] * (B)[0][(col)]); \ @@ -431,96 +623,10 @@ extern f32 gSineTable[]; ((u32 *)(mtx))[15] = FLOAT_ONE; \ } -#define NAME_INVMAG(v) v##_invmag - -/// Scale vector 'v' so it has length 1 -#define vec3_normalize(v) { \ - register f32 NAME_INVMAG(v) = vec3_mag((v)); \ - NAME_INVMAG(v) = (1.0f / MAX(NAME_INVMAG(v), NEAR_ZERO)); \ - vec3_mul_val((v), NAME_INVMAG(v)); \ -} - -#define vec3_normalize_max(v, max) { \ - register f32 v##_mag = vec3_mag(v); \ - v##_mag = MAX(v##_mag, NEAR_ZERO); \ - if (v##_mag > max) { \ - v##_mag = (max / v##_mag); \ - vec3_mul_val(v, v##_mag); \ - } \ -} - -#define ABS(x) (((x) > 0) ? (x) : -(x)) - -extern s32 roundf(f32); -// backwards compatibility -#define round_float(in) roundf(in) - -#define absf ABS -#define absi ABS -#define abss ABS - -#define FLT_IS_NONZERO(x) (absf(x) > NEAR_ZERO) - u16 random_u16(void); f32 random_float(void); s32 random_sign(void); -f32 min_3f( f32 a, f32 b, f32 c); -s32 min_3i( s32 a, s32 b, s32 c); -s32 min_3s( s16 a, s16 b, s16 c); -f32 max_3f( f32 a, f32 b, f32 c); -s32 max_3i( s32 a, s32 b, s32 c); -s32 max_3s( s16 a, s16 b, s16 c); -void min_max_3f(f32 a, f32 b, f32 c, f32 *min, f32 *max); -void min_max_3i(s32 a, s32 b, s32 c, s32 *min, s32 *max); -void min_max_3s(s16 a, s16 b, s16 c, s16 *min, s16 *max); - -void vec3f_copy (Vec3f dest, const Vec3f src); -void vec3i_copy (Vec3i dest, const Vec3i src); -void vec3s_copy (Vec3s dest, const Vec3s src); -void vec3s_to_vec3i(Vec3i dest, const Vec3s src); -void vec3s_to_vec3f(Vec3f dest, const Vec3s src); -void vec3i_to_vec3s(Vec3s dest, const Vec3i src); -void vec3i_to_vec3f(Vec3f dest, const Vec3i src); -void vec3f_to_vec3s(Vec3s dest, const Vec3f src); -void vec3f_to_vec3i(Vec3i dest, const Vec3f src); - -void vec3f_copy_y_off(Vec3f dest, Vec3f src, f32 yOff); - -void surface_normal_to_vec3f(Vec3f dest, struct Surface *surf); - -void vec3f_set(Vec3f dest, const f32 x, const f32 y, const f32 z); -void vec3i_set(Vec3i dest, const s32 x, const s32 y, const s32 z); -void vec3s_set(Vec3s dest, const s16 x, const s16 y, const s16 z); - -void vec3f_add (Vec3f dest, const Vec3f a ); -void vec3i_add (Vec3i dest, const Vec3i a ); -void vec3s_add (Vec3s dest, const Vec3s a ); -void vec3f_sum (Vec3f dest, const Vec3f a, const Vec3f b); -void vec3i_sum (Vec3i dest, const Vec3i a, const Vec3i b); -void vec3s_sum (Vec3s dest, const Vec3s a, const Vec3s b); -void vec3f_sub (Vec3f dest, const Vec3f a ); -void vec3i_sub (Vec3i dest, const Vec3i a ); -void vec3s_sub (Vec3s dest, const Vec3s a ); -void vec3f_diff(Vec3f dest, const Vec3f a, const Vec3f b); -void vec3i_diff(Vec3i dest, const Vec3i a, const Vec3i b); -void vec3s_diff(Vec3s dest, const Vec3s a, const Vec3s b); -void vec3f_mul (Vec3f dest, const Vec3f a ); -void vec3i_mul (Vec3i dest, const Vec3i a ); -void vec3s_mul (Vec3s dest, const Vec3s a ); -void vec3f_prod(Vec3f dest, const Vec3f a, const Vec3f b); -void vec3i_prod(Vec3i dest, const Vec3i a, const Vec3i b); -void vec3s_prod(Vec3s dest, const Vec3s a, const Vec3s b); -void vec3f_div (Vec3f dest, const Vec3f a ); -void vec3i_div (Vec3i dest, const Vec3i a ); -void vec3s_div (Vec3s dest, const Vec3s a ); -void vec3f_quot(Vec3f dest, const Vec3f a, const Vec3f b); -void vec3i_quot(Vec3i dest, const Vec3i a, const Vec3i b); -void vec3s_quot(Vec3s dest, const Vec3s a, const Vec3s b); - -f32 vec3f_dot( const Vec3f a, const Vec3f b); -void vec3f_cross(Vec3f dest, const Vec3f a, const 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); @@ -537,41 +643,17 @@ void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b); void mtxf_scale_vec3f(Mat4 dest, Mat4 mtx, Vec3f s); void mtxf_mul_vec3s(Mat4 mtx, Vec3s b); -extern void mtxf_to_mtx_fast(register s16 *dest, register float *src); -ALWAYS_INLINE void mtxf_to_mtx(register void *dest, register void *src) { +extern void mtxf_to_mtx_fast(s16 *dest, float *src); +ALWAYS_INLINE void mtxf_to_mtx(void *dest, void *src) { mtxf_to_mtx_fast((s16*)dest, (float*)src); // guMtxF2L(src, dest); } void mtxf_rotate_xy(Mtx *mtx, s16 angle); -void linear_mtxf_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v); -void linear_mtxf_mul_vec3f_and_translate(Mat4 m, Vec3f dst, Vec3f v); -void linear_mtxf_transpose_mul_vec3f(Mat4 m, Vec3f dst, Vec3f v); -void vec2f_get_lateral_dist( Vec2f from, Vec2f to, f32 *lateralDist ); -void vec3f_get_lateral_dist( Vec3f from, Vec3f to, f32 *lateralDist ); -void vec3f_get_lateral_dist_squared( Vec3f from, Vec3f to, f32 *lateralDist ); -void vec3f_get_dist( Vec3f from, Vec3f to, f32 *dist ); -void vec3f_get_dist_squared( Vec3f from, Vec3f to, f32 *dist ); -void vec3f_get_dist_and_yaw( Vec3f from, Vec3f to, f32 *dist, s16 *yaw); -void vec3f_get_pitch( Vec3f from, Vec3f to, s16 *pitch ); -void vec3f_get_yaw( Vec3f from, Vec3f to, s16 *yaw); -void vec3f_get_angle( Vec3f from, Vec3f to, s16 *pitch, s16 *yaw); -void vec3f_get_lateral_dist_and_pitch( Vec3f from, Vec3f to, f32 *lateralDist, s16 *pitch ); -void vec3f_get_lateral_dist_and_yaw( Vec3f from, Vec3f to, f32 *lateralDist, s16 *yaw); -void vec3f_get_lateral_dist_and_angle( Vec3f from, Vec3f to, f32 *lateralDist, s16 *pitch, s16 *yaw); -void vec3f_get_dist_and_lateral_dist_and_angle(Vec3f from, Vec3f to, f32 *dist, f32 *lateralDist, s16 *pitch, s16 *yaw); -void vec3f_get_dist_and_angle( Vec3f from, Vec3f to, f32 *dist, s16 *pitch, s16 *yaw); -void vec3s_get_dist_and_angle( Vec3s from, Vec3s to, s16 *dist, s16 *pitch, s16 *yaw); -void vec3f_to_vec3s_get_dist_and_angle( Vec3f from, Vec3s to, f32 *dist, s16 *pitch, s16 *yaw); -void vec3s_set_dist_and_angle( Vec3s from, Vec3s to, s16 dist, s16 pitch, s16 yaw); -void vec3f_set_dist_and_angle( Vec3f from, Vec3f to, f32 dist, s16 pitch, s16 yaw); - -s16 approach_angle(s16 current, s16 target, s16 inc); s16 approach_s16(s16 current, s16 target, s16 inc, s16 dec); s32 approach_s32(s32 current, s32 target, s32 inc, s32 dec); f32 approach_f32(f32 current, f32 target, f32 inc, f32 dec); -Bool32 approach_angle_bool(s16 *current, s16 target, s16 inc); Bool32 approach_s16_bool(s16 *current, s16 target, s16 inc, s16 dec); Bool32 approach_s32_bool(s32 *current, s32 target, s32 inc, s32 dec); Bool32 approach_f32_bool(f32 *current, f32 target, f32 inc, f32 dec); @@ -581,6 +663,8 @@ Bool32 approach_f32_bool(f32 *current, f32 target, f32 inc, f32 dec); #define approach_s16_symmetric_bool(current, target, inc) approach_s16_bool((current), (target), (inc), (inc)) #define approach_s32_symmetric_bool(current, target, inc) approach_s32_bool((current), (target), (inc), (inc)) #define approach_f32_symmetric_bool(current, target, inc) approach_f32_bool((current), (target), (inc), (inc)) +#define approach_angle approach_s16_symmetric +#define approach_angle_bool approach_s16_symmetric_bool s32 approach_f32_signed(f32 *current, f32 target, f32 inc); s32 approach_f32_asymptotic_bool(f32 *current, f32 target, f32 multiplier); f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier); diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index f2444fb7..a68362d6 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -248,7 +248,7 @@ static struct Surface *read_surface_data(TerrainData *vertexData, TerrainData ** Vec3t offset; s16 min, max; - vec3_prod_val(offset, (*vertexIndices), 3); + vec3_scale_dest(offset, (*vertexIndices), 3); vec3s_copy(v[0], (vertexData + offset[0])); vec3s_copy(v[1], (vertexData + offset[1])); @@ -265,7 +265,7 @@ static struct Surface *read_surface_data(TerrainData *vertexData, TerrainData ** } #endif mag = 1.0f / sqrtf(mag); - vec3_mul_val(n, mag); + vec3_scale(n, mag); struct Surface *surface = alloc_surface(dynamic); @@ -686,8 +686,9 @@ void load_object_collision_model(void) { PUPPYPRINT_GET_SNAPSHOT(); TerrainData *collisionData = o->collisionData; - f32 sqrLateralDist; - vec3f_get_lateral_dist_squared(&o->oPosVec, &gMarioObject->oPosVec, &sqrLateralDist); + Vec3f dist; + vec3_diff(dist, &o->oPosVec, &gMarioObject->oPosVec); + f32 sqrLateralDist = sqr(dist[0]) + sqr(dist[2]); f32 verticalMarioDiff = gMarioObject->oPosY - o->oPosY; diff --git a/src/game/behaviors/chain_chomp.inc.c b/src/game/behaviors/chain_chomp.inc.c index a23480d1..f3831896 100644 --- a/src/game/behaviors/chain_chomp.inc.c +++ b/src/game/behaviors/chain_chomp.inc.c @@ -104,12 +104,12 @@ static void chain_chomp_update_chain_segments(void) { // Cap distance to previous chain part (so that the tail follows the chomp) Vec3f offset; vec3f_diff(offset, segment->pos, prevSegment->pos); - vec3_normalize_max(offset, o->oChainChompMaxDistBetweenChainParts); + vec3_set_max_dist(offset, o->oChainChompMaxDistBetweenChainParts); // Cap distance to pivot (so that it stretches when the chomp moves far from the wooden post) vec3f_add(offset, prevSegment->pos); f32 maxTotalDist = o->oChainChompMaxDistFromPivotPerChainPart * (CHAIN_CHOMP_NUM_SEGMENTS - i); - vec3_normalize_max(offset, maxTotalDist); + vec3_set_max_dist(offset, maxTotalDist); vec3f_copy(segment->pos, offset); } @@ -365,7 +365,7 @@ static void chain_chomp_act_move(void) { f32 ratio = maxDistToPivot / o->oChainChompDistToPivot; o->oChainChompDistToPivot = maxDistToPivot; - vec3_mul_val(o->oChainChompSegments[0].pos, ratio); + vec3_scale(o->oChainChompSegments[0].pos, ratio); if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) { // Restrict chain chomp position diff --git a/src/game/behaviors/hoot.inc.c b/src/game/behaviors/hoot.inc.c index 48073fc2..cd407839 100644 --- a/src/game/behaviors/hoot.inc.c +++ b/src/game/behaviors/hoot.inc.c @@ -194,7 +194,8 @@ void hoot_action_loop(void) { void hoot_turn_to_home(void) { s16 pitchToHome, yawToHome; - vec3f_get_angle(&o->oPosVec, &o->oHomeVec, &pitchToHome, &yawToHome); + f32 distToHome; + vec3f_get_dist_and_angle(&o->oPosVec, &o->oHomeVec, &distToHome, &pitchToHome, &yawToHome); o->oMoveAngleYaw = approach_s16_symmetric(o->oMoveAngleYaw, yawToHome, 0x140); o->oMoveAnglePitch = approach_s16_symmetric(o->oMoveAnglePitch, -pitchToHome, 0x140); diff --git a/src/game/behaviors/intro_peach.inc.c b/src/game/behaviors/intro_peach.inc.c index 781938fe..cfe3d0a9 100644 --- a/src/game/behaviors/intro_peach.inc.c +++ b/src/game/behaviors/intro_peach.inc.c @@ -7,8 +7,9 @@ void intro_peach_set_pos_and_opacity(struct Object *obj, f32 targetOpacity, f32 increment) { Vec3f newPos; s16 focusPitch, focusYaw; + f32 dist; - vec3f_get_angle(gLakituState.pos, gLakituState.focus, &focusPitch, &focusYaw); + vec3f_get_dist_and_angle(gLakituState.pos, gLakituState.focus, &dist, &focusPitch, &focusYaw); vec3f_set_dist_and_angle(gLakituState.pos, newPos, obj->oIntroPeachDistToCamera, obj->oIntroPeachPitchFromFocus + focusPitch, obj->oIntroPeachYawFromFocus + focusYaw); diff --git a/src/game/behaviors/spawn_star.inc.c b/src/game/behaviors/spawn_star.inc.c index b3f6408d..84135dbe 100644 --- a/src/game/behaviors/spawn_star.inc.c +++ b/src/game/behaviors/spawn_star.inc.c @@ -40,7 +40,8 @@ void bhv_collect_star_loop(void) { void bhv_star_spawn_init(void) { s16 yaw; - vec3f_get_lateral_dist_and_yaw(&o->oPosVec, &o->oHomeVec, &o->oStarSpawnDisFromHome, &yaw); + vec3f_get_yaw(&o->oPosVec, &o->oHomeVec, &yaw); + vec3f_get_lateral_dist(&o->oPosVec, &o->oHomeVec, &o->oStarSpawnDisFromHome) o->oMoveAngleYaw = yaw; o->oVelY = (o->oHomeY - o->oPosY) / 30.0f; o->oForwardVel = o->oStarSpawnDisFromHome / 30.0f; diff --git a/src/game/camera.c b/src/game/camera.c index 9ef41f80..8cd629d0 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -3462,7 +3462,7 @@ void evaluate_cubic_spline(f32 u, Vec3f Q, Vec3f spline1, Vec3f spline2, Vec3f s register f32 su = sqr(u); register f32 hcu = (su * u) / 2.0f; - B[0] = cube(nu) / 6.0f; + B[0] = (nu * nu * nu) / 6.0f; B[1] = hcu - su + (2.0f / 3.0f); B[2] = -hcu + (su / 2.0f) + (u / 2.0f) + (1.0f / 6.0f); B[3] = hcu / 3.0f; diff --git a/src/game/gamecube_controller.c b/src/game/gamecube_controller.c index 1a44c7da..760c618b 100644 --- a/src/game/gamecube_controller.c +++ b/src/game/gamecube_controller.c @@ -1,4 +1,5 @@ #include "PR/os_internal.h" +#include "engine/math_util.h" #include "game_init.h" @@ -9,11 +10,6 @@ #define ARRLEN(x) ((s32)(sizeof(x) / sizeof(x[0]))) #define CHNL_ERR(format) (((format).rxsize & CHNL_ERR_MASK) >> 4) -#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) -#define S8_MAX __SCHAR_MAX__ -#define S8_MIN (-S8_MAX - 1) -#define CLAMP_S8( x) CLAMP((x), S8_MIN, S8_MAX) - #define CHNL_ERR_MASK 0xC0 /* Bit 6-7: channel errors */ typedef struct diff --git a/src/game/mario.c b/src/game/mario.c index b2603c0e..af267811 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1706,7 +1706,8 @@ s32 execute_mario_action(UNUSED struct Object *obj) { s32 inLoop = TRUE; // Updates once per frame: - vec3f_get_dist_and_lateral_dist_and_angle(gMarioState->prevPos, gMarioState->pos, &gMarioState->moveSpeed, &gMarioState->lateralSpeed, &gMarioState->movePitch, &gMarioState->moveYaw); + vec3f_get_dist_and_angle(gMarioState->prevPos, gMarioState->pos, &gMarioState->moveSpeed, &gMarioState->movePitch, &gMarioState->moveYaw); + vec3f_get_lateral_dist(gMarioState->prevPos, gMarioState->pos, &gMarioState->lateralSpeed); vec3f_copy(gMarioState->prevPos, gMarioState->pos); if (gMarioState->action) { diff --git a/src/game/mario_actions_moving.c b/src/game/mario_actions_moving.c index 902a1823..2c72df9d 100644 --- a/src/game/mario_actions_moving.c +++ b/src/game/mario_actions_moving.c @@ -1353,9 +1353,6 @@ void tilt_body_butt_slide(struct MarioState *m) { } void common_slide_action(struct MarioState *m, u32 endAction, u32 airAction, s32 animation) { - Vec3f pos; - - vec3f_copy(pos, m->pos); play_sound(SOUND_MOVING_TERRAIN_SLIDE + m->terrainSoundAddend, m->marioObj->header.gfx.cameraToObject); #if ENABLE_RUMBLE diff --git a/src/game/mario_actions_submerged.c b/src/game/mario_actions_submerged.c index 47ebaaac..6c8a7372 100644 --- a/src/game/mario_actions_submerged.c +++ b/src/game/mario_actions_submerged.c @@ -137,7 +137,7 @@ static void apply_water_current(struct MarioState *m, Vec3f step) { if (whirlpool != NULL) { strength = 0.0f; - vec3f_to_vec3s_get_dist_and_angle(m->pos, whirlpool->pos, &distance, &pitchToWhirlpool, &yawToWhirlpool); + vec3_get_dist_and_angle(m->pos, whirlpool->pos, &distance, &pitchToWhirlpool, &yawToWhirlpool); yawToWhirlpool -= (s16)(0x2000 * 1000.0f / (distance + 1000.0f)); diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 2f967341..5df500a4 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -476,9 +476,9 @@ void obj_init_animation(struct Object *obj, s32 animIndex) { void obj_apply_scale_to_transform(struct Object *obj) { Vec3f scale; vec3f_copy(scale, obj->header.gfx.scale); - vec3_mul_val(obj->transform[0], scale[0]); - vec3_mul_val(obj->transform[1], scale[1]); - vec3_mul_val(obj->transform[2], scale[2]); + vec3_scale(obj->transform[0], scale[0]); + vec3_scale(obj->transform[1], scale[1]); + vec3_scale(obj->transform[2], scale[2]); } void obj_copy_scale(struct Object *dst, struct Object *src) { diff --git a/src/game/puppycam2.c b/src/game/puppycam2.c index c6f9669e..bc9fc26c 100644 --- a/src/game/puppycam2.c +++ b/src/game/puppycam2.c @@ -223,7 +223,6 @@ s32 puppycam_move_spline(struct sPuppySpline splinePos[], struct sPuppySpline sp f32 tempProgress[2] = {0.0f, 0.0f}; f32 progChange = 0.0f; s32 i; - Vec3f prevPos; if (gPuppyCam.splineIndex == 65000) { gPuppyCam.splineIndex = index; @@ -236,7 +235,6 @@ s32 puppycam_move_spline(struct sPuppySpline splinePos[], struct sPuppySpline sp return TRUE; } } - vec3f_set(prevPos, gPuppyCam.pos[0], gPuppyCam.pos[1], gPuppyCam.pos[2]); for (i = 0; i < 4; i++) { vec3f_set(tempPoints[i], splinePos[gPuppyCam.splineIndex + i].pos[0], splinePos[gPuppyCam.splineIndex + i].pos[1], splinePos[gPuppyCam.splineIndex + i].pos[2]); @@ -680,7 +678,6 @@ static void puppycam_input_hold_preset2(f32 ivX) { // Another alternative control scheme. This one aims to mimic the parallel camera scheme down to the last bit from the original game. static void puppycam_input_hold_preset3(f32 ivX) { - f32 stickMag[2] = {gPlayer1Controller->rawStickX*0.65f, gPlayer1Controller->rawStickY*0.2f}; // Just in case it happens to be nonzero. gPuppyCam.yawAcceleration = 0; @@ -1374,7 +1371,7 @@ static void puppycam_collision(void) { vec3f_normalize(dirToCam); // Get the vector from mario's head to the camera plus the extra check dist Vec3f vecToCam; - vec3_prod_val(vecToCam, dirToCam, colCheckDist); + vec3_scale_dest(vecToCam, dirToCam, colCheckDist); dist[0] = find_surface_on_ray(target[0], vecToCam, &surf[0], hitpos[0], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL); dist[1] = find_surface_on_ray(target[1], vecToCam, &surf[1], hitpos[1], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL); @@ -1391,7 +1388,7 @@ static void puppycam_collision(void) { closestDist -= surfOffset; // Allow the camera to ride right up next to the wall (mario's wall radius is 50u so this is safe) closestDist = MAX(closestDist, 50); - vec3_mul_val(dirToCam, closestDist); + vec3_scale(dirToCam, closestDist); vec3_sum(gPuppyCam.pos, target[0], dirToCam); // If the camera is uncomfortably close to the wall, move it up a bit diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 9e33e9ad..934cc695 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -1123,7 +1123,7 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]); } if (node->objNode != NULL && node->objNode->header.gfx.sharedChild != NULL) { - vec3_prod_val(translation, node->translation, 0.25f); + vec3_scale_dest(translation, node->translation, 0.25f); mtxf_translate(mat, translation); mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix); diff --git a/src/game/skybox.c b/src/game/skybox.c index 490d3257..7485d383 100644 --- a/src/game/skybox.c +++ b/src/game/skybox.c @@ -61,7 +61,7 @@ struct Skybox { struct Skybox sSkyBoxInfo[2]; -typedef const Texture *const SkyboxTexture[80 * sqr(SKYBOX_SIZE)]; +typedef const Texture *const SkyboxTexture[80 * SKYBOX_SIZE * SKYBOX_SIZE]; extern SkyboxTexture bbh_skybox_ptrlist; extern SkyboxTexture bidw_skybox_ptrlist; @@ -304,7 +304,8 @@ Gfx *create_skybox_facing_camera(s8 player, s8 background, f32 fov, Vec3f pos, V //! the first frame, which causes a floating point divide by 0 fov = 90.0f; s16 yaw; - vec3f_get_angle(pos, focus, &sSkyBoxInfo[player].pitch, &yaw); + f32 dist; + vec3f_get_dist_and_angle(pos, focus, &dist, &sSkyBoxInfo[player].pitch, &yaw); sSkyBoxInfo[player].yaw = yaw; sSkyBoxInfo[player].scaledX = calculate_skybox_scaled_x(player, fov); sSkyBoxInfo[player].scaledY = calculate_skybox_scaled_y(player, fov);