Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ifdef several collision changes from vanilla + improved debug free move #794

Open
wants to merge 26 commits into
base: develop/2.4.0
Choose a base branch
from

Conversation

Arceveti
Copy link
Collaborator

Makes several collision changes from vanilla no longer enforced.

Added defines:

  • DISABLE_CEILING_BONKS
  • ROUNDED_WALL_CORNERS
  • FIX_EXPOSED_CEILINGS

Also:

  • Removed add_ceil_margin. It's a leftover from the original patch and was supposed to be a bandaid fix for exposed ceilings by making them slightly smaller, but due to a typo it had no effect in HackerSM64.
  • Removed COLLISION_FLAG_RETURN_FIRST. This was supposed to allow calling find_floor/find_ceil with/without sorting, but there aren't any use cases that are worth keeping an additional check in those functions.
  • Small console tested optimizations for find_floor and find_ceil.
  • Improved debug free move (holding B allows phasing through surfaces, and the camera no longer gets stuck on floors or ceilings)

@Arceveti Arceveti added enhancement New feature or request performance Issue or feature related to game performance labels Apr 29, 2024
@Arceveti Arceveti added this to the 2.3 milestone Apr 29, 2024
@Arceveti Arceveti requested review from FazanaJ and thecozies April 29, 2024 04:56
@@ -49,7 +50,11 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil);

// Finds the ceiling from a vec3f and a minimum height (with 3 unit vertical buffer).
ALWAYS_INLINE f32 find_mario_ceil(Vec3f pos, f32 height, struct Surface **ceil) {
return find_ceil(pos[0], MAX(height, pos[1]) + 3.0f, pos[2], ceil);
#ifdef FIX_EXPOSED_CEILINGS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an ugly way to do this, id rather you just have height = MAX(height, pos[1]) + 3.0f; in an ifdef

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, but I moved the + 3.0f outside the ifdef since vanilla also has the offset.

@@ -1135,7 +1137,7 @@ void mode_8_directions_camera(struct Camera *c) {
}
#ifdef PARALLEL_LAKITU_CAM
// extra functionality
else if (gPlayer1Controller->buttonPressed & U_JPAD) {
else if ((gPlayer1Controller->buttonPressed & U_JPAD) && (gMarioState->action != ACT_DEBUG_FREE_MOVE)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should not really have camera-specific behavior for debug free move, just wasting code and perf considering that no final release will have it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree since the camera interference is extremely annoying in practice, however idk if this is the best way to fix it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what interference? this code is only when dpad up is being pressed. just dont press dpad up? its so pointless

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

D-Pad Up is used to move up in debug free mode (and enter the mode in the first place), that's pretty damn important.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i forgor

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check should also be applied to D_JPAD actually

@@ -6,6 +6,7 @@
#include "surface_collision.h"
#include "types.h"


Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arceveti moment

Copy link
Collaborator

@gheskett gheskett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly smaller formatting things here, the actual logic behind most of this is too messy for me to actually follow along with.

* Also properly handles simultaneous collisions with multiple walls (eg. concave wall corners or narrow tunnels).
*/
#define ROUNDED_WALL_CORNERS
/**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Comment on lines 149 to 159

/**
* Improves the handling of convex wall corners by rounding wall collision at triangle edges to close the seams.
* Also properly handles simultaneous collisions with multiple walls (eg. concave wall corners or narrow tunnels).
*/
#define ROUNDED_WALL_CORNERS
/**
* Fixes an issue where entering an area above a ceiling without an intermediate floor would count as hitting a ceiling.
* NOTE: This may allow Mario to clip through the wall on the deck of the the rocking JRB ship.
*/
#define FIX_EXPOSED_CEILINGS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make more sense to throw these into config_collision.h? Argument could be made for ceiling bonks too but that one's debatable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved those two

@@ -257,6 +257,7 @@ enum SurfaceFlags {
SURFACE_FLAGS_NONE = (0 << 0), // 0x0000
SURFACE_FLAG_DYNAMIC = (1 << 0), // 0x0001
SURFACE_FLAG_NO_CAM_COLLISION = (1 << 1), // 0x0002
SURFACE_FLAG_X_PROJECTION = (1 << 3), // 0x0008
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why skip a number?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how it was in vanilla, this just restores it. Should it be changed to (1 << 2)?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it just makes more sense

/**************************************************
* WALLS *
**************************************************/

static s32 check_wall_vw(f32 d00, f32 d01, f32 d11, f32 d20, f32 d21, f32 invDenom) {
#ifdef ROUNDED_WALL_CORNERS
static s32 check_wall_triangle_vw(f32 d00, f32 d01, f32 d11, f32 d20, f32 d21, f32 invDenom) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is old so won't enforce the change, but these variable names in general are not great.

src/engine/surface_collision.c Show resolved Hide resolved
Comment on lines 354 to 364
if (ceil->flags & SURFACE_FLAG_NO_CAM_COLLISION) continue;
} else {
// If we are not checking for the camera, ignore camera only ceilings.
if (ceil->type == SURFACE_CAMERA_BOUNDARY) continue;
}

// Check that the point is within the triangle bounds
if (!check_within_ceil_triangle_bounds(x, z, surf, 1.5f)) continue;
// Exclude all ceilings below the check height.
if (y > ceil->upperY) continue;

// Find the height of the ceil at the given location
height = get_surface_height_at_location(x, z, surf);

// Exclude ceilings above the previous lowest ceiling
if (height > *pheight) continue;
// Check that the point is within the triangle bounds.
if (!check_within_ceil_triangle_bounds(x, z, ceil)) continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Inlining continue/break/return is fine if it's part of a consistent and repetitive code block, but otherwise it's terrible coding practice. Anything that significantly impacts processing in that way needs to be more explicit (i.e. have its own line, ideally with a comment if it's not braindead obvious).

Calling this one a nitpick since it's mostly not new code, but I still do not like it in general.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed most of these to be on their own lines (except for some of the repetitive ones like the vanilla wall collisions or the check floor/ceil triangle bounds functions).

Comment on lines 369 to 373
// Exclude ceiling heights that are:
if (
(ceilHeight < y) || // Lower than the check height.
(ceilHeight >= lowestCeilHeight) // Higher than the previous lowest ceiling.
) continue;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except not for this one, this just looks bad lol

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if you mean the if statement or the continue here, but I put the continue on its own line here too.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically the continue; the if statement itself doesn't bother me

@@ -394,10 +436,11 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
}

// To prevent accidentally leaving the floor tangible, stop checking for it.
gCollisionFlags &= ~(COLLISION_FLAG_RETURN_FIRST | COLLISION_FLAG_EXCLUDE_DYNAMIC | COLLISION_FLAG_INCLUDE_INTANGIBLE);
gCollisionFlags &= ~(COLLISION_FLAG_EXCLUDE_DYNAMIC | COLLISION_FLAG_INCLUDE_INTANGIBLE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, have these been profiled? Seems like there's more than I realized.

Comment on lines +586 to 596
if (checkCollisions) {
if ((ceilHeight - floorHeight) < 160.0f) {
return FALSE;
}
if ((floor != NULL) && (pos[1] < floorHeight)) {
pos[1] = floorHeight;
}
if (ceil != NULL && pos[1] + 160.0f > ceilHeight) {
if ((ceil != NULL) && ((pos[1] + 160.0f) > ceilHeight) && (pos[1] < ceilHeight)) {
pos[1] = ceilHeight - 160.0f;
}
vec3f_copy(m->pos, pos);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I preferred the general look of the old way better, generally not a fan of holding the entire function captive to an early return in the event somebody wanted to add logic onto this for example.

Comment on lines 105 to 107
COLLISION_FLAG_CAMERA = (1 << 1),
COLLISION_FLAG_INCLUDE_INTANGIBLE = (1 << 2),
COLLISION_FLAG_EXCLUDE_DYNAMIC = (1 << 3),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason these skip (1 << 0)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, either a typo or there used to be a flag there that was removed. I moved exclude dynamic to be (1 << 0).

@gheskett gheskett modified the milestones: 2.3, 2.4 Jul 4, 2024
@gheskett gheskett changed the base branch from develop/2.3.0 to develop/2.4.0 July 4, 2024 07:08
@gheskett gheskett linked an issue Sep 5, 2024 that may be closed by this pull request
@gheskett gheskett added the high priority Important, non-critical issue or feature / high priority label Sep 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request high priority Important, non-critical issue or feature / high priority performance Issue or feature related to game performance
Projects
Status: In progress
Development

Successfully merging this pull request may close these issues.

Steep slopes can be easily clipped through (JRB ship)
3 participants