diff --git a/enhancements/platform_displacement_2.diff b/enhancements/platform_displacement_2.diff index 9a3bfaf0..e492e9f4 100644 --- a/enhancements/platform_displacement_2.diff +++ b/enhancements/platform_displacement_2.diff @@ -22,7 +22,7 @@ index 0000000..6bf33a8 + UNUSED f32 floorHeight; + if ((platform = o->platform) != NULL) +- apply_platform_displacement(0, platform); -++ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosX, &o->oFaceAngleYaw, platform); +++ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosVec, &o->oFaceAngleYaw, platform); + o->oBowserUnk10E = 0; + cur_obj_update_floor_and_walls(); + cur_obj_call_action_function(sBowserActions); @@ -312,7 +312,7 @@ index 97cba2a..410e612 100644 - if ((platform = o->platform) != NULL) - apply_platform_displacement(FALSE, platform); + if ((platform = o->platform) != NULL) { -+ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosX, &o->oFaceAngleYaw, platform); ++ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosVec, &o->oFaceAngleYaw, platform); + } o->oBowserUnk10E = 0; cur_obj_update_floor_and_walls(); @@ -1648,7 +1648,7 @@ index 0000000..97cba2a + if ((o->oTimer & 1) == 0 && o->oTimer < 14) { + sp22 = D_8032F698[o->oBehParams2ndByte].unk3 + (gDebugInfo[4][1] << 8); + sp1C = -(o->oTimer / 2) * 290 + 1740; -+ vec3f_copy(sp24, &o->oPosX); ++ vec3f_copy(sp24, &o->oPosVec); + o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 + 5296) * sp1C; + o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 + 5296) * sp1C; + o->oPosY = 307.0f; @@ -1656,7 +1656,7 @@ index 0000000..97cba2a + o->oPosX = D_8032F698[o->oBehParams2ndByte].unk1 + sins(sp22 - 5296) * sp1C; + o->oPosZ = D_8032F698[o->oBehParams2ndByte].unk2 + coss(sp22 - 5296) * sp1C; + spawn_mist_particles_variable(4, 0, 100); -+ vec3f_copy(&o->oPosX, sp24); ++ vec3f_copy(&o->oPosVec, sp24); + } + cur_obj_move_using_fvel_and_gravity(); + if (o->oTimer > 300) @@ -1922,7 +1922,7 @@ index 0000000..f47808d + UNUSED f32 floorHeight; + if ((platform = o->platform) != NULL) +- apply_platform_displacement(0, platform); -++ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosX, &o->oFaceAngleYaw, platform); +++ apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosVec, &o->oFaceAngleYaw, platform); + o->oBowserUnk10E = 0; + cur_obj_update_floor_and_walls(); + cur_obj_call_action_function(sBowserActions); diff --git a/src/engine/math_util.c b/src/engine/math_util.c index 7e4632d6..d0987ad3 100644 --- a/src/engine/math_util.c +++ b/src/engine/math_util.c @@ -112,15 +112,23 @@ void vec3f_cross(Vec3f dest, Vec3f a, Vec3f b) { /// Scale vector 'dest' so it has length 1 void vec3f_normalize(Vec3f dest) { - f32 size = sqrtf(dest[0] * dest[0] + dest[1] * dest[1] + dest[2] * dest[2]); - register f32 invsqrt; - if (size > 0.01f) { - - invsqrt = 1.0f / size; + f32 mag = sqrtf(sqr(dest[0] + sqr(dest[1]) + sqr(dest[2])); + if (mag > __FLT_EPSILON__) { + register f32 invsqrt = 1.0f / mag; + vec3_mul_val(dest, invsqrt); + } else { + dest[0] = 0; + dest[1] = 1; + dest[2] = 0; + } +} + +/// Scale vector 'dest' so it has length -1 +void vec3f_normalize_negative(Vec3f dest) { + f32 mag = sqrtf(sqr(dest[0] + sqr(dest[1]) + sqr(dest[2])); + if (mag > __FLT_EPSILON__) { + register f32 invsqrt = -1.0f / mag; vec3_mul_val(dest, invsqrt); - /*dest[0] *= invsqrt; - dest[1] *= invsqrt; - dest[2] *= invsqrt;*/ } else { dest[0] = 0; dest[1] = 1; @@ -130,7 +138,7 @@ void vec3f_normalize(Vec3f dest) { #pragma GCC diagnostic pop struct CopyMe { - f32 x; f32 y; f32 z; f32 w; + f32 x; f32 y; f32 z; f32 w; f32 x1; f32 y1; f32 z1; f32 w1; f32 x2; f32 y2; f32 z2; f32 w2; f32 x3; f32 y3; f32 z3; f32 w3; @@ -209,14 +217,6 @@ void mtxf_rot_trans_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src) { ((u32 *) dest)[15] = 0x3F800000; } -f32 lookAtCalc(f32 sqrtsqrt) { - f32 calc = sqrtf(sqrtsqrt); - if (calc == 0) - calc = 0.00000000001; - - return -1.0 / calc; -} - /** * Set mtx to a look-at matrix for the camera. The resulting transformation * transforms the world as if there exists a camera at position 'from' pointed @@ -224,78 +224,36 @@ f32 lookAtCalc(f32 sqrtsqrt) { * angle allows a bank rotation of the camera. */ void mtxf_lookat(Mat4 mtx, Vec3f from, Vec3f to, s32 roll) { - register f32 invLength; - f32 dx; - f32 dz; - f32 xColY; - f32 yColY; - f32 zColY; - f32 xColZ; - f32 yColZ; - f32 zColZ; - f32 xColX; - f32 yColX; - f32 zColX; - f32 calc; - - dx = to[0] - from[0]; - dz = to[2] - from[2]; - - invLength = lookAtCalc(dx * dx + dz * dz); + 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)); + invLength = -(1.0f / MAX(invLength, NEAR_ZERO)); dx *= invLength; dz *= invLength; - - yColY = coss(roll); - xColY = sins(roll) * dz; - zColY = -sins(roll) * dx; - - xColZ = to[0] - from[0]; - yColZ = to[1] - from[1]; - zColZ = to[2] - from[2]; - - invLength = lookAtCalc(xColZ * xColZ + yColZ * yColZ + zColZ * zColZ); - xColZ *= invLength; - yColZ *= invLength; - zColZ *= invLength; - - xColX = yColY * zColZ - zColY * yColZ; - yColX = zColY * xColZ - xColY * zColZ; - zColX = xColY * yColZ - yColY * xColZ; - - invLength = -lookAtCalc(xColX * xColX + yColX * yColX + zColX * zColX); - - xColX *= invLength; - yColX *= invLength; - zColX *= invLength; - - xColY = yColZ * zColX - zColZ * yColX; - yColY = zColZ * xColX - xColZ * zColX; - zColY = xColZ * yColX - yColZ * xColX; - - invLength = -lookAtCalc(xColY * xColY + yColY * yColY + zColY * zColY); - xColY *= invLength; - yColY *= invLength; - zColY *= invLength; - - mtx[0][0] = xColX; - mtx[1][0] = yColX; - mtx[2][0] = zColX; - mtx[3][0] = -(from[0] * xColX + from[1] * yColX + from[2] * zColX); - - mtx[0][1] = xColY; - mtx[1][1] = yColY; - mtx[2][1] = zColY; - mtx[3][1] = -(from[0] * xColY + from[1] * yColY + from[2] * zColY); - - mtx[0][2] = xColZ; - mtx[1][2] = yColZ; - mtx[2][2] = zColZ; - mtx[3][2] = -(from[0] * xColZ + from[1] * yColZ + from[2] * zColZ); - - mtx[0][3] = 0; - mtx[1][3] = 0; - mtx[2][3] = 0; - mtx[3][3] = 1; + f32 sr = sins(roll); + colY[1] = coss(roll); + colY[0] = ( sr * dz); + colY[2] = (-sr * dx); + vec3_diff(colZ, to, from); + vec3_normalize_negative(colZ); + vec3f_cross(colX, colY, colZ); + vec3f_normalize(colX); + vec3f_cross(colY, colZ, colX); + vec3f_normalize(colY); + mtx[0][0] = colX[0]; + mtx[1][0] = colX[1]; + mtx[2][0] = colX[2]; + mtx[0][1] = colY[0]; + mtx[1][1] = colY[1]; + mtx[2][1] = colY[2]; + mtx[0][2] = colZ[0]; + mtx[1][2] = colZ[1]; + mtx[2][2] = colZ[2]; + mtx[3][0] = -vec3_dot(from, colX); + mtx[3][1] = -vec3_dot(from, colY); + mtx[3][2] = -vec3_dot(from, colZ); + MTXF_END(mtx); } /** @@ -375,7 +333,7 @@ void mtxf_rotate_xyz_and_translate(Mat4 dest, Vec3f b, Vec3s c) { void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s32 angle) { register s32 i; register f32 *temp, *temp2; - temp = dest; + temp = (f32 *)dest; for (i = 0; i < 16; i++) { *temp = 0; temp++; @@ -388,8 +346,8 @@ void mtxf_billboard(Mat4 dest, Mat4 mtx, Vec3f position, s32 angle) { dest[2][3] = 0; ((u32 *) dest)[15] = 0x3F800000; - temp = dest; - temp2 = mtx; + temp = (f32 *)dest; + temp2 = (f32 *)mtx; for (i = 0; i < 3; i++) { temp[12] = temp2[0] * position[0] + temp2[4] * position[1] + temp2[8] * position[2] + temp2[12]; temp++; @@ -448,14 +406,10 @@ void mtxf_align_terrain_normal(Mat4 dest, Vec3f upDir, Vec3f pos, s32 yaw) { * 'radius' is the distance from each triangle vertex to the center */ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s32 yaw, f32 radius) { - struct Surface *sp74; - Vec3f point0; - Vec3f point1; - Vec3f point2; + struct Surface *floor; + Vec3f point0, point1, point2; Vec3f forward; - Vec3f xColumn; - Vec3f yColumn; - Vec3f zColumn; + Vec3f xColumn, yColumn, zColumn; f32 avgY; f32 minY = -radius * 3; @@ -466,9 +420,9 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s32 yaw, f32 radius) { point2[0] = pos[0] + radius * sins(yaw + 0xD555); point2[2] = pos[2] + radius * coss(yaw + 0xD555); - point0[1] = find_floor(point0[0], pos[1] + 150, point0[2], &sp74); - point1[1] = find_floor(point1[0], pos[1] + 150, point1[2], &sp74); - point2[1] = find_floor(point2[0], pos[1] + 150, point2[2], &sp74); + point0[1] = find_floor(point0[0], pos[1] + 150, point0[2], &floor); + point1[1] = find_floor(point1[0], pos[1] + 150, point1[2], &floor); + point2[1] = find_floor(point2[0], pos[1] + 150, point2[2], &floor); if (point0[1] - pos[1] < minY) { point0[1] = pos[1]; @@ -491,20 +445,11 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s32 yaw, f32 radius) { vec3f_normalize(xColumn); vec3f_cross(zColumn, xColumn, yColumn); vec3f_normalize(zColumn); - - mtx[0][0] = xColumn[0]; - mtx[0][1] = xColumn[1]; - mtx[0][2] = xColumn[2]; + vec3_copy(mtx[0], xColumn); + vec3_copy(mtx[1], yColumn); + vec3_copy(mtx[2], zColumn); mtx[3][0] = pos[0]; - - mtx[1][0] = yColumn[0]; - mtx[1][1] = yColumn[1]; - mtx[1][2] = yColumn[2]; mtx[3][1] = (avgY < pos[1]) ? pos[1] : avgY; - - mtx[2][0] = zColumn[0]; - mtx[2][1] = zColumn[1]; - mtx[2][2] = zColumn[2]; mtx[3][2] = pos[2]; mtx[0][3] = 0; @@ -522,20 +467,16 @@ void mtxf_align_terrain_triangle(Mat4 mtx, Vec3f pos, s32 yaw, f32 radius) { * then a. */ void mtxf_mul(Mat4 dest, Mat4 a, Mat4 b) { - register f32 entry0; - register f32 entry1; - register f32 entry2; - register f32 *temp = a; - register f32 *temp2 = dest; + register Vec3f entry; + register f32 *temp = (f32 *)a; + register f32 *temp2 = (f32 *)dest; register f32 *temp3; register s32 i; for (i = 0; i < 16; i++) { - entry0 = temp[0]; - entry1 = temp[1]; - entry2 = temp[2]; - temp3 = b; + vec3_copy(entry, temp); + temp3 = (f32 *)b; for (; (i & 3) !=3; i++) { - *temp2 = entry0 * temp3[0] + entry1 * temp3[4] + entry2 * temp3[8]; + *temp2 = entry[0] * temp3[0] + entry[1] * temp3[4] + entry[2] * temp3[8]; temp2++; temp3++; } @@ -551,8 +492,8 @@ 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) { - register f32 *temp = dest; - register f32 *temp2 = mtx; + register f32 *temp = (f32 *)dest; + register f32 *temp2 = (f32 *)mtx; register s32 i; for (i = 0; i < 4; i++) { temp[0] = temp2[0] * s[0]; @@ -573,7 +514,7 @@ void mtxf_mul_vec3s(Mat4 mtx, Vec3s b) { register f32 x = b[0]; register f32 y = b[1]; register f32 z = b[2]; - register f32 *temp2 = mtx; + register f32 *temp2 = (f32 *)mtx; register s32 i; register s16 *c = b; for (i = 0; i < 3; i++) { @@ -636,7 +577,7 @@ void mtxf_to_mtx(void *dest, void *src) { void mtxf_rotate_xy(Mtx *mtx, s32 angle) { register s32 i = coss(angle) * 65536; register s32 j = sins(angle) * 65536; - register f32 *temp = mtx; + register f32 *temp = (f32 *)mtx; register s32 k; for (k = 0; k < 16; k++) { *temp = 0; @@ -672,11 +613,11 @@ void mtxf_rotate_xy(Mtx *mtx, s32 angle) { */ void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, register Mat4 camMtx) { register s32 i; - register f32 *temp = dest; - register f32 *temp2 = camMtx; + register f32 *temp = (f32 *)dest; + register f32 *temp2 = (f32 *)camMtx; f32 y[3]; register f32 *x = y; - register f32 *temp3 = objMtx; + register f32 *temp3 = (f32 *)objMtx; for (i = 0; i < 3; i++) { *x = (temp3[12] - temp2[12]); @@ -690,7 +631,6 @@ void get_pos_from_transform_mtx(Vec3f dest, Mat4 objMtx, register Mat4 camMtx) { temp++; temp2 += 4; } - } diff --git a/src/engine/math_util.h b/src/engine/math_util.h index 41c403e2..0b08c90c 100644 --- a/src/engine/math_util.h +++ b/src/engine/math_util.h @@ -5,6 +5,10 @@ #include "types.h" +#define NEAR_ZERO 0.00001f +#define NEARER_ZERO 0.000001f +#define NEAR_ONE 0.99999f + /** * 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. @@ -124,6 +128,32 @@ extern f32 gSineTable[]; (dst)[2] = (((a)[0] * (b)[1]) - ((a)[1] * (b)[0])); \ } +/** + * | ? ? ? 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_vec3f((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)); \ +} + #define vec2_set(dst, x, y) { \ (dst)[0] = (x); \ (dst)[1] = (y); \ @@ -340,11 +370,68 @@ extern f32 gSineTable[]; #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 RAYCAST_FIND_FLOOR (0x1) -#define RAYCAST_FIND_WALL (0x2) -#define RAYCAST_FIND_CEIL (0x4) -#define RAYCAST_FIND_WATER (0x8) -#define RAYCAST_FIND_ALL (0xFFFFFFFF) +#define MAT4_VEC_DOT_PROD(R, A, B, row, col) { \ + (R)[(row)][(col)] = ((A)[(row)][0] * (B)[0][(col)]); \ + (R)[(row)][(col)] += ((A)[(row)][1] * (B)[1][(col)]); \ + (R)[(row)][(col)] += ((A)[(row)][2] * (B)[2][(col)]); \ +} +#define MAT4_DOT_PROD(R, A, B, row, col) { \ + (R)[(row)][(col)] = ((A)[(row)][0] * (B)[0][(col)]); \ + (R)[(row)][(col)] += ((A)[(row)][1] * (B)[1][(col)]); \ + (R)[(row)][(col)] += ((A)[(row)][2] * (B)[2][(col)]); \ + (R)[(row)][(col)] += ((A)[(row)][3] * (B)[3][(col)]); \ +} + +#define MAT4_MULTIPLY(R, A, B) { \ + MAT4_DOT_PROD((R), (A), (B), 0, 0); \ + MAT4_DOT_PROD((R), (A), (B), 0, 1); \ + MAT4_DOT_PROD((R), (A), (B), 0, 2); \ + MAT4_DOT_PROD((R), (A), (B), 0, 3); \ + MAT4_DOT_PROD((R), (A), (B), 1, 0); \ + MAT4_DOT_PROD((R), (A), (B), 1, 1); \ + MAT4_DOT_PROD((R), (A), (B), 1, 2); \ + MAT4_DOT_PROD((R), (A), (B), 1, 3); \ + MAT4_DOT_PROD((R), (A), (B), 2, 0); \ + MAT4_DOT_PROD((R), (A), (B), 2, 1); \ + MAT4_DOT_PROD((R), (A), (B), 2, 2); \ + MAT4_DOT_PROD((R), (A), (B), 2, 3); \ + MAT4_DOT_PROD((R), (A), (B), 3, 0); \ + MAT4_DOT_PROD((R), (A), (B), 3, 1); \ + MAT4_DOT_PROD((R), (A), (B), 3, 2); \ + MAT4_DOT_PROD((R), (A), (B), 3, 3); \ +} + +#define MTXF_END(mtx) { \ + (mtx)[0][3] = 0.0f; \ + (mtx)[1][3] = 0.0f; \ + (mtx)[2][3] = 0.0f; \ + (mtx)[3][3] = 1.0f; \ +} + +#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)); \ +} + +/// Scale vector 'v' so it has length -1 +#define vec3_normalize_negative(v) { \ + register f32 v##_invmag = vec3_mag((v)); \ + v##_invmag = -(1.0f / MAX(v##_invmag, NEAR_ZERO)); \ + vec3_mul_val((v), v##_invmag); \ +} + +#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); \ + } \ +} s32 min_3i(s32 a0, s32 a1, s32 a2); f32 min_3f(f32 a0, f32 a1, f32 a2); diff --git a/src/engine/surface_collision.h b/src/engine/surface_collision.h index 8982e2d5..bd1ebd36 100644 --- a/src/engine/surface_collision.h +++ b/src/engine/surface_collision.h @@ -19,6 +19,12 @@ #define SURFACE_YAW(s) (atan2s(((s)->normal.z), ((s)->normal.x))) +#define RAYCAST_FIND_FLOOR (1 << 0) +#define RAYCAST_FIND_WALL (1 << 1) +#define RAYCAST_FIND_CEIL (1 << 2) +#define RAYCAST_FIND_WATER (1 << 3) +#define RAYCAST_FIND_ALL (0xFFFFFFFF) + struct WallCollisionData { /*0x00*/ f32 x, y, z; diff --git a/src/game/behaviors/bowser.inc.c b/src/game/behaviors/bowser.inc.c index 884dc87f..61e175fe 100644 --- a/src/game/behaviors/bowser.inc.c +++ b/src/game/behaviors/bowser.inc.c @@ -1537,12 +1537,11 @@ s8 sBowserHealth[] = { 1, 1, 3 }; void bowser_free_update(void) { struct Surface *floor; struct Object *platform; - UNUSED f32 floorHeight; #ifdef PLATFORM_DISPLACEMENT_2 s16 tmpOFaceAngleYaw = (s16) o->oFaceAngleYaw; if ((platform = o->platform) != NULL) { // NOTE: This function was at one point using '&o->oFaceAngleYaw', which is a s32 address. Should tmpOFaceAngleYaw be using the first 16 bits instead, or was that a bug? - apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosX, &tmpOFaceAngleYaw, platform); + apply_platform_displacement(&sBowserDisplacementInfo, &o->oPosVec, &tmpOFaceAngleYaw, platform); o->oFaceAngleYaw = tmpOFaceAngleYaw; } #else @@ -1561,7 +1560,7 @@ void bowser_free_update(void) { o->oAction = BOWSER_ACT_JUMP_ONTO_STAGE; } // Check floor height and platform - floorHeight = find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); + find_floor(o->oPosX, o->oPosY, o->oPosZ, &floor); if ((floor != NULL) && (floor->object != NULL)) { o->platform = floor->object; } else { diff --git a/src/game/behaviors/bowser_falling_platform.inc.c b/src/game/behaviors/bowser_falling_platform.inc.c index f1c66117..685f0aa9 100644 --- a/src/game/behaviors/bowser_falling_platform.inc.c +++ b/src/game/behaviors/bowser_falling_platform.inc.c @@ -62,7 +62,7 @@ void falling_bowser_plat_act_fall(void) { if ((o->oTimer & 1) == 0 && o->oTimer < 14) { angle = sBowserFallingPlatform[o->oBehParams2ndByte].angle + (gDebugInfo[4][1] << 8); val = -(o->oTimer / 2) * 290 + 1740; - vec3f_copy(pos, &o->oPosX); + vec3f_copy(pos, &o->oPosVec); o->oPosX = sBowserFallingPlatform[o->oBehParams2ndByte].posX + sins(angle + 0x14B0) * val; o->oPosZ = sBowserFallingPlatform[o->oBehParams2ndByte].posZ + coss(angle + 0x14B0) * val; o->oPosY = 307.0f; @@ -70,7 +70,7 @@ void falling_bowser_plat_act_fall(void) { o->oPosX = sBowserFallingPlatform[o->oBehParams2ndByte].posX + sins(angle - 0x14B0) * val; o->oPosZ = sBowserFallingPlatform[o->oBehParams2ndByte].posZ + coss(angle - 0x14B0) * val; spawn_mist_particles_variable(4, 0, 100); - vec3f_copy(&o->oPosX, pos); + vec3f_copy(&o->oPosVec, pos); } cur_obj_move_using_fvel_and_gravity(); if (o->oTimer > 300) { diff --git a/src/game/behaviors/grand_star.inc.c b/src/game/behaviors/grand_star.inc.c index 4fa2ec99..a71c3a88 100644 --- a/src/game/behaviors/grand_star.inc.c +++ b/src/game/behaviors/grand_star.inc.c @@ -4,23 +4,21 @@ s32 arc_to_goal_pos(Vec3f a0, Vec3f a1, f32 yVel, f32 gravity) { f32 dx = a0[0] - a1[0]; f32 dz = a0[2] - a1[2]; f32 planarDist = sqrtf(sqr(dx) + sqr(dz)); - s32 time; o->oMoveAngleYaw = atan2s(dz, dx); o->oVelY = yVel; o->oGravity = gravity; - time = -2.0f / o->oGravity * yVel - 1.0f; + s32 time = -2.0f / o->oGravity * yVel - 1.0f; o->oForwardVel = planarDist / time; return time; } void grand_star_zero_velocity(void) { - o->oGravity = 0.0f; - o->oVelY = 0.0f; + o->oGravity = 0.0f; + o->oVelY = 0.0f; o->oForwardVel = 0.0f; } void bhv_grand_star_loop(void) { - Vec3f dest = { 0.0f, 0.0f, 0.0f }; if (o->oAction == 0) { if (o->oTimer == 0) { obj_set_angle(o, 0, 0, 0); @@ -34,7 +32,7 @@ void bhv_grand_star_loop(void) { if (o->oTimer == 0) { cur_obj_play_sound_2(SOUND_GENERAL_GRAND_STAR); cutscene_object(CUTSCENE_STAR_SPAWN, o); - o->oGrandStarArcTime = arc_to_goal_pos(dest, &o->oPosX, 80.0f, -2.0f); + o->oGrandStarArcTime = arc_to_goal_pos(gVec3fZero, &o->oPosVec, 80.0f, -2.0f); } cur_obj_move_using_fvel_and_gravity(); if (o->oSubAction == 0) { diff --git a/src/game/behaviors/king_bobomb.inc.c b/src/game/behaviors/king_bobomb.inc.c index 199a1cb6..43c3c260 100644 --- a/src/game/behaviors/king_bobomb.inc.c +++ b/src/game/behaviors/king_bobomb.inc.c @@ -226,7 +226,7 @@ void king_bobomb_act_5(void) { // bobomb returns home if (o->oPosY < o->oHomeY) o->oVelY = 100.0f; else { - arc_to_goal_pos(&o->oHomeX, &o->oPosX, 100.0f, -4.0f); + arc_to_goal_pos(&o->oPosVec, &o->oPosVec, 100.0f, -4.0f); o->oSubAction++; } break; diff --git a/src/game/behaviors/sl_snowman_wind.inc.c b/src/game/behaviors/sl_snowman_wind.inc.c index f5059973..a9d41b2e 100644 --- a/src/game/behaviors/sl_snowman_wind.inc.c +++ b/src/game/behaviors/sl_snowman_wind.inc.c @@ -12,11 +12,11 @@ void bhv_sl_snowman_wind_loop(void) { o->oDistanceToMario = 0; // Check if Mario is within 1000 units of the center of the bridge, and ready to speak. - vec3f_copy(tempPos, &o->oPosX); + vec3f_copy(tempPos, &o->oPosVec); obj_set_pos(o, 1100, 3328, 1164); // Position is in the middle of the ice bridge if (cur_obj_can_mario_activate_textbox(1000.0f, 30.0f, 0x7FFF)) o->oSubAction++; - vec3f_copy(&o->oPosX, tempPos); + vec3f_copy(&o->oPosVec, tempPos); // Mario has come close, begin dialog. } else if (o->oSubAction == SL_SNOWMAN_WIND_ACT_TALKING) { diff --git a/src/game/behaviors/whomp.inc.c b/src/game/behaviors/whomp.inc.c index a4e4dd1b..f98de7d8 100644 --- a/src/game/behaviors/whomp.inc.c +++ b/src/game/behaviors/whomp.inc.c @@ -146,12 +146,12 @@ void king_whomp_on_ground(void) { if (o->oHealth == 0) o->oAction = 8; else { - vec3f_copy(pos, &o->oPosX); - vec3f_copy(&o->oPosX, &gMarioObject->oPosX); + vec3f_copy(pos, &o->oPosVec); + vec3f_copy(&o->oPosVec, &gMarioObject->oPosVec); spawn_mist_particles_variable(0, 0, 100.0f); spawn_triangle_break_particles(20, MODEL_DIRT_ANIMATION, 3.0f, 4); cur_obj_shake_screen(SHAKE_POS_SMALL); - vec3f_copy(&o->oPosX, pos); + vec3f_copy(&o->oPosVec, pos); } o->oSubAction++; } diff --git a/src/game/object_helpers.c b/src/game/object_helpers.c index 7f6e9bb6..f65557a9 100644 --- a/src/game/object_helpers.c +++ b/src/game/object_helpers.c @@ -1704,8 +1704,7 @@ void cur_obj_move_using_fvel_and_gravity(void) { cur_obj_move_using_vel_and_gravity(); //! No terminal velocity } -void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, - f32 dforward) { +void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f32 dy, f32 dforward) { f32 facingZ = coss(other->oMoveAngleYaw); f32 facingX = sins(other->oMoveAngleYaw); @@ -1720,12 +1719,9 @@ void obj_set_pos_relative(struct Object *obj, struct Object *other, f32 dleft, f } s16 cur_obj_angle_to_home(void) { - s16 angle; f32 dx = o->oHomeX - o->oPosX; f32 dz = o->oHomeZ - o->oPosZ; - - angle = atan2s(dz, dx); - return angle; + return atan2s(dz, dx); } void obj_set_gfx_pos_at_obj_pos(struct Object *obj1, struct Object *obj2) { @@ -1747,26 +1743,16 @@ void obj_translate_local(struct Object *obj, s16 posIndex, s16 localTranslateInd f32 dy = obj->rawData.asF32[localTranslateIndex + 1]; f32 dz = obj->rawData.asF32[localTranslateIndex + 2]; - obj->rawData.asF32[posIndex + 0] += - obj->transform[0][0] * dx + obj->transform[1][0] * dy + obj->transform[2][0] * dz; - obj->rawData.asF32[posIndex + 1] += - obj->transform[0][1] * dx + obj->transform[1][1] * dy + obj->transform[2][1] * dz; - obj->rawData.asF32[posIndex + 2] += - obj->transform[0][2] * dx + obj->transform[1][2] * dy + obj->transform[2][2] * dz; + obj->rawData.asF32[posIndex + 0] += obj->transform[0][0] * dx + obj->transform[1][0] * dy + obj->transform[2][0] * dz; + obj->rawData.asF32[posIndex + 1] += obj->transform[0][1] * dx + obj->transform[1][1] * dy + obj->transform[2][1] * dz; + obj->rawData.asF32[posIndex + 2] += obj->transform[0][2] * dx + obj->transform[1][2] * dy + obj->transform[2][2] * dz; } void obj_build_transform_from_pos_and_angle(struct Object *obj, s16 posIndex, s16 angleIndex) { Vec3f translate; + vec3_copy(translate, &obj->rawData.asF32[posIndex]); Vec3s rotation; - - translate[0] = obj->rawData.asF32[posIndex + 0]; - translate[1] = obj->rawData.asF32[posIndex + 1]; - translate[2] = obj->rawData.asF32[posIndex + 2]; - - rotation[0] = obj->rawData.asS32[angleIndex + 0]; - rotation[1] = obj->rawData.asS32[angleIndex + 1]; - rotation[2] = obj->rawData.asS32[angleIndex + 2]; - + vec3_copy(rotation, &obj->rawData.asS32[angleIndex]); mtxf_rotate_zxy_and_translate(obj->transform, translate, rotation); } @@ -1790,9 +1776,7 @@ void obj_build_transform_relative_to_parent(struct Object *obj) { obj_apply_scale_to_transform(obj); mtxf_mul(obj->transform, obj->transform, parent->transform); - obj->oPosX = obj->transform[3][0]; - obj->oPosY = obj->transform[3][1]; - obj->oPosZ = obj->transform[3][2]; + vec3_copy(&obj->oPosVec, obj->transform[3]); obj->header.gfx.throwMatrix = &obj->transform; @@ -1802,10 +1786,7 @@ void obj_build_transform_relative_to_parent(struct Object *obj) { void obj_create_transform_from_self(struct Object *obj) { obj->oFlags &= ~OBJ_FLAG_TRANSFORM_RELATIVE_TO_PARENT; obj->oFlags |= OBJ_FLAG_SET_THROW_MATRIX_FROM_TRANSFORM; - - obj->transform[3][0] = obj->oPosX; - obj->transform[3][1] = obj->oPosY; - obj->transform[3][2] = obj->oPosZ; + vec3_copy(obj->transform[3], &obj->oPosVec); } void cur_obj_rotate_move_angle_using_vel(void) { diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index de90361b..8096accc 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -350,13 +350,14 @@ void geo_append_display_list(void *displayList, s32 layer) { } } -void incrementMatStack() { +void inc_mat_stack() { Mtx *mtx = alloc_display_list(sizeof(*mtx)); gMatStackIndex++; mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]); gMatStackFixed[gMatStackIndex] = mtx; } -void appendDLandReturn(struct GraphNodeDisplayList *node) { + +void append_dl_and_return(struct GraphNodeDisplayList *node) { if (node->displayList != NULL) { geo_append_display_list(node->displayList, node->node.flags >> 8); } @@ -513,7 +514,7 @@ void geo_process_camera(struct GraphNodeCamera *node) { mtxf_lookat(cameraTransform, node->pos, node->focus, node->roll); mtxf_mul(gMatStack[gMatStackIndex + 1], cameraTransform, gMatStack[gMatStackIndex]); - incrementMatStack(); + inc_mat_stack(); if (node->fnNode.node.children != 0) { gCurGraphNodeCamera = node; node->matrixPtr = &gMatStack[gMatStackIndex]; @@ -536,8 +537,8 @@ void geo_process_translation_rotation(struct GraphNodeTranslationRotation *node) vec3_copy(translation, node->translation); mtxf_rotate_zxy_and_translate(mtxf, translation, node->rotation); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -552,8 +553,8 @@ void geo_process_translation(struct GraphNodeTranslation *node) { vec3_copy(translation, node->translation); mtxf_rotate_zxy_and_translate(mtxf, translation, gVec3sZero); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -566,8 +567,8 @@ void geo_process_rotation(struct GraphNodeRotation *node) { mtxf_rotate_zxy_and_translate(mtxf, gVec3fZero, node->rotation); mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, gMatStack[gMatStackIndex]); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -580,8 +581,8 @@ void geo_process_scale(struct GraphNodeScale *node) { vec3f_set(scaleVec, node->scale, node->scale, node->scale); mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], scaleVec); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -594,16 +595,16 @@ void geo_process_billboard(struct GraphNodeBillboard *node) { Vec3f translation; vec3_copy(translation, node->translation); - mtxf_billboard(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex], translation, gCurGraphNodeCamera->roll); + mtxf_billboard(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex], translation, gCurGraphNodeCamera->roll); if (gCurGraphNodeHeldObject != NULL) { - mtxf_scale_vec3f(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex+1], gCurGraphNodeHeldObject->objNode->header.gfx.scale); + mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], gCurGraphNodeHeldObject->objNode->header.gfx.scale); } else if (gCurGraphNodeObject != NULL) { - mtxf_scale_vec3f(gMatStack[gMatStackIndex+1], gMatStack[gMatStackIndex+1], gCurGraphNodeObject->scale); + mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], gCurGraphNodeObject->scale); } - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -612,7 +613,7 @@ void geo_process_billboard(struct GraphNodeBillboard *node) { * parent node. It processes its children if it has them. */ void geo_process_display_list(struct GraphNodeDisplayList *node) { - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); gMatStackIndex++; } @@ -622,8 +623,7 @@ void geo_process_display_list(struct GraphNodeDisplayList *node) { */ void geo_process_generated_list(struct GraphNodeGenerated *node) { if (node->fnNode.func != NULL) { - Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, - (struct AllocOnlyPool *) gMatStack[gMatStackIndex]); + Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, (struct AllocOnlyPool *) gMatStack[gMatStackIndex]); if (list != NULL) { geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), GET_GRAPH_NODE_LAYER(node->fnNode.node.flags)); @@ -710,8 +710,8 @@ void geo_process_animated_part(struct GraphNodeAnimatedPart *node) { rotation[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; } mtxf_rot_trans_mul(rotation, translation, gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex]); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -750,8 +750,8 @@ void geo_process_bone(struct GraphNodeBone *node) { rotation[2] = gCurAnimData[retrieve_animation_index(gCurrAnimFrame, &gCurrAnimAttribute)]; } mtxf_rot_trans_mul(rotation, translation, gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex]); - incrementMatStack(); - appendDLandReturn(((struct GraphNodeDisplayList *)node)); + inc_mat_stack(); + append_dl_and_return(((struct GraphNodeDisplayList *)node)); } /** @@ -833,8 +833,8 @@ void geo_process_shadow(struct GraphNodeShadow *node) { Gfx *shadowList = create_shadow_below_xyz(shadowPos[0], shadowPos[1], shadowPos[2], shadowScale, node->shadowSolidity, node->shadowType); if (shadowList != NULL) { mtxf_translate(mtxf, shadowPos); - mtxf_mul(gMatStack[gMatStackIndex+1], mtxf, *gCurGraphNodeCamera->matrixPtr); - incrementMatStack(); + mtxf_mul(gMatStack[gMatStackIndex + 1], mtxf, *gCurGraphNodeCamera->matrixPtr); + inc_mat_stack(); geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), ((gShadowFlags & (SHADOW_FLAG_WATER_BOX | SHADOW_FLAG_WATER_SURFACE | SHADOW_FLAG_ICE_CARPET)) ? LAYER_TRANSPARENT : LAYER_TRANSPARENT_DECAL)); gMatStackIndex--; } @@ -919,12 +919,8 @@ s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { } // Check whether the object is horizontally in view - if (matrix[3][0] > (hScreenEdge + cullingRadius)) { - return FALSE; - } - if (matrix[3][0] < (-hScreenEdge - cullingRadius)) { - return FALSE; - } + if (matrix[3][0] > ( hScreenEdge + cullingRadius)) return FALSE; + if (matrix[3][0] < (-hScreenEdge - cullingRadius)) return FALSE; return TRUE; } @@ -956,7 +952,7 @@ void geo_process_object(struct Object *node) { if (obj_is_in_view(&node->header.gfx, gMatStack[gMatStackIndex])) { gMatStackIndex--; - incrementMatStack(); + inc_mat_stack(); if (node->header.gfx.sharedChild != NULL) { #ifdef VISUAL_DEBUG if (hitboxView) { @@ -1032,30 +1028,27 @@ void geo_process_held_object(struct GraphNodeHeldObject *node) { } if (node->objNode != NULL && node->objNode->header.gfx.sharedChild != NULL) { s32 hasAnimation = (node->objNode->header.gfx.node.flags & GRAPH_RENDER_HAS_ANIMATION) != 0; - - translation[0] = node->translation[0] / 4.0f; - translation[1] = node->translation[1] / 4.0f; - translation[2] = node->translation[2] / 4.0f; + vec3_quot_val(translation, node->translation, 4.0f); mtxf_translate(mat, translation); mtxf_copy(gMatStack[gMatStackIndex + 1], *gCurGraphNodeObject->throwMatrix); - gMatStack[gMatStackIndex + 1][3][0] = gMatStack[gMatStackIndex][3][0]; - gMatStack[gMatStackIndex + 1][3][1] = gMatStack[gMatStackIndex][3][1]; - gMatStack[gMatStackIndex + 1][3][2] = gMatStack[gMatStackIndex][3][2]; - mtxf_mul(gMatStack[gMatStackIndex + 1], mat, gMatStack[gMatStackIndex + 1]); + vec3_copy(gMatStack[gMatStackIndex + 1][3], gMatStack[gMatStackIndex][3]); + Mat4 temp; + mtxf_copy(temp, gMatStack[gMatStackIndex + 1]); + mtxf_mul(gMatStack[gMatStackIndex + 1], mat, temp); mtxf_scale_vec3f(gMatStack[gMatStackIndex + 1], gMatStack[gMatStackIndex + 1], node->objNode->header.gfx.scale); if (node->fnNode.func != NULL) { node->fnNode.func(GEO_CONTEXT_HELD_OBJ, &node->fnNode.node, (struct AllocOnlyPool *) gMatStack[gMatStackIndex + 1]); } - incrementMatStack(); - gGeoTempState.type = gCurAnimType; - gGeoTempState.enabled = gCurAnimEnabled; - gGeoTempState.frame = gCurrAnimFrame; + inc_mat_stack(); + gGeoTempState.type = gCurAnimType; + gGeoTempState.enabled = gCurAnimEnabled; + gGeoTempState.frame = gCurrAnimFrame; gGeoTempState.translationMultiplier = gCurAnimTranslationMultiplier; - gGeoTempState.attribute = gCurrAnimAttribute; - gGeoTempState.data = gCurAnimData; - gCurAnimType = 0; - gCurGraphNodeHeldObject = (void *) node; + gGeoTempState.attribute = gCurrAnimAttribute; + gGeoTempState.data = gCurAnimData; + gCurAnimType = 0; + gCurGraphNodeHeldObject = (void *) node; if (node->objNode->header.gfx.animInfo.curAnim != NULL) { geo_set_animation_globals(&node->objNode->header.gfx.animInfo, hasAnimation); } @@ -1144,9 +1137,9 @@ void geo_process_node_and_siblings(struct GraphNode *firstNode) { * to set up the projection and draw display lists. */ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor) { - #if PUPPYPRINT_DEBUG +#if PUPPYPRINT_DEBUG OSTime first = osGetTime(); - #endif +#endif if (node->node.flags & GRAPH_RENDER_ACTIVE) { Mtx *initialMatrix; @@ -1156,7 +1149,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor) initialMatrix = alloc_display_list(sizeof(*initialMatrix)); gMatStackIndex = 0; gCurAnimType = 0; - vec3s_set(viewport->vp.vtrans, node->x * 4, node->y * 4, 511); + vec3s_set(viewport->vp.vtrans, node->x * 4, node->y * 4, 511); vec3s_set(viewport->vp.vscale, node->width * 4, node->height * 4, 511); if (b != NULL) { clear_frame_buffer(clearColor); @@ -1174,7 +1167,7 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor) gMatStackFixed[gMatStackIndex] = initialMatrix; gSPViewport(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(viewport)); gSPMatrix(gDisplayListHead++, VIRTUAL_TO_PHYSICAL(gMatStackFixed[gMatStackIndex]), - G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); + (G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH)); gCurGraphNodeRoot = node; if (node->node.children != NULL) { geo_process_node_and_siblings(node->node.children);