From 4c655bfdc0d69c14029672f7d93a85c90f7e4047 Mon Sep 17 00:00:00 2001 From: Arceveti <73617174+Arceveti@users.noreply.github.com> Date: Sat, 4 Sep 2021 09:59:30 -0700 Subject: [PATCH] Automatically get optimal collision distance --- README.md | 1 + include/config.h | 2 ++ include/object_constants.h | 3 ++ src/engine/surface_load.c | 35 +++++++++++++++++-- .../behaviors/falling_rising_platform.inc.c | 3 ++ 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5402a3cd..4e02802f 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ This is a fork of the ultrasm64 repo by CrashOveride which includes the followin - Platform Displacement 2 by Arthurtilly * - Water Surface Type patch by thecozies - Rounded corners by FramePerfection, merged by Cheezepin +- Automatically calculate the optimal collision distance for an object based on its vertices, by Kaze * **Common Hack Changes:** - Better extended boundaries by anonymous_moose diff --git a/include/config.h b/include/config.h index bc73998d..4790cfa1 100644 --- a/include/config.h +++ b/include/config.h @@ -102,6 +102,8 @@ #define MULTILANG (0 || VERSION_EU) // Enables Puppy Camera 2, a rewritten camera that can be freely configured and modified. //#define PUPPYCAM +// Automatically calculate the optimal collision distance for an object based on its vertices. +#define AUTO_COLLISION_DISTANCE // HACKER QOL diff --git a/include/object_constants.h b/include/object_constants.h index 807ef5e9..cca7c870 100644 --- a/include/object_constants.h +++ b/include/object_constants.h @@ -44,6 +44,9 @@ #define OBJ_FLAG_COMPUTE_ANGLE_TO_MARIO (1 << 13) // 0x00002000 #define OBJ_FLAG_PERSISTENT_RESPAWN (1 << 14) // 0x00004000 #define OBJ_FLAG_8000 (1 << 15) // 0x00008000 +#ifdef AUTO_COLLISION_DISTANCE +#define OBJ_FLAG_DONT_CALC_COLL_DIST (1 << 16) // 0x00010000 +#endif #define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000 /* oHeldState */ diff --git a/src/engine/surface_load.c b/src/engine/surface_load.c index 9571c518..601b8a54 100644 --- a/src/engine/surface_load.c +++ b/src/engine/surface_load.c @@ -779,6 +779,30 @@ void load_object_surfaces(TerrainData **data, TerrainData *vertexData) { } } +#ifdef AUTO_COLLISION_DISTANCE +// From Kaze +static void get_optimal_coll_dist(struct Object *o) { + register f32 thisVertDist, maxDist = 0.0f; + Vec3f v; + TerrainData *collisionData = gCurrentObject->collisionData; + o->oFlags |= OBJ_FLAG_DONT_CALC_COLL_DIST; + collisionData++; + register u32 vertsLeft = *(collisionData); + collisionData++; + // vertices = *data; + while (vertsLeft) { + v[0] = *(collisionData + 0) * o->header.gfx.scale[0]; + v[1] = *(collisionData + 1) * o->header.gfx.scale[1]; + v[2] = *(collisionData + 2) * o->header.gfx.scale[2]; + thisVertDist = ((v[0] * v[0]) + (v[1] * v[1]) + (v[2] * v[2])); + if (thisVertDist > maxDist) maxDist = thisVertDist; + collisionData += 3; + vertsLeft--; + } + o->oCollisionDistance = (sqrtf(maxDist) + 100.0f); +} +#endif + /** * Transform an object's vertices, reload them, and render the object. */ @@ -790,7 +814,6 @@ void load_object_collision_model(void) { TerrainData *collisionData = gCurrentObject->collisionData; f32 marioDist = gCurrentObject->oDistanceToMario; - f32 tangibleDist = gCurrentObject->oCollisionDistance; // On an object's first frame, the distance is set to 19000.0f. // If the distance hasn't been updated, update it now. @@ -798,14 +821,20 @@ void load_object_collision_model(void) { marioDist = dist_between_objects(gCurrentObject, gMarioObject); } +#ifdef AUTO_COLLISION_DISTANCE + if (!(gCurrentObject->oFlags & OBJ_FLAG_DONT_CALC_COLL_DIST)) { + get_optimal_coll_dist(gCurrentObject); + } +#endif + // If the object collision is supposed to be loaded more than the // drawing distance of 4000, extend the drawing range. - if (gCurrentObject->oCollisionDistance > 4000.0f) { + if (gCurrentObject->oCollisionDistance > gCurrentObject->oDrawingDistance) { gCurrentObject->oDrawingDistance = gCurrentObject->oCollisionDistance; } // Update if no Time Stop, in range, and in the current room. - if (!(gTimeStopState & TIME_STOP_ACTIVE) && marioDist < tangibleDist + if (!(gTimeStopState & TIME_STOP_ACTIVE) && marioDist < gCurrentObject->oCollisionDistance && !(gCurrentObject->activeFlags & ACTIVE_FLAG_IN_DIFFERENT_ROOM)) { collisionData++; transform_object_vertices(&collisionData, vertexData); diff --git a/src/game/behaviors/falling_rising_platform.inc.c b/src/game/behaviors/falling_rising_platform.inc.c index faddc2f4..35359690 100644 --- a/src/game/behaviors/falling_rising_platform.inc.c +++ b/src/game/behaviors/falling_rising_platform.inc.c @@ -3,6 +3,9 @@ void bhv_squishable_platform_loop(void) { o->header.gfx.scale[1] = (sins(o->oBitfsPlatformTimer) + 1.0) * 0.3 + 0.4; o->oBitfsPlatformTimer += 0x80; +#ifdef AUTO_COLLISION_DISTANCE + o->oFlags &= ~OBJ_FLAG_DONT_CALC_COLL_DIST; +#endif } void bhv_bitfs_sinking_platform_loop(void) {