Automatically get optimal collision distance

This commit is contained in:
Arceveti
2021-09-04 09:59:30 -07:00
parent 5be32f1c24
commit 4c655bfdc0
5 changed files with 41 additions and 3 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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) {