You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Clean up gotos from find_wall_collisions_from_list (#288)
This commit is contained in:
@@ -14,18 +14,36 @@
|
||||
* WALLS *
|
||||
**************************************************/
|
||||
|
||||
#define CALC_OFFSET(vert, next_step) { \
|
||||
if (FLT_IS_NONZERO((vert)[1])) { \
|
||||
v = (v2[1] / (vert)[1]); \
|
||||
if ((v < 0.0f) || (v > 1.0f)) next_step;\
|
||||
d00 = (((vert)[0] * v) - v2[0]); \
|
||||
d01 = (((vert)[2] * v) - v2[2]); \
|
||||
invDenom = sqrtf(sqr(d00) + sqr(d01)); \
|
||||
offset = (invDenom - margin_radius); \
|
||||
if (offset > 0.0f) next_step; \
|
||||
goto check_collision; \
|
||||
} \
|
||||
next_step; \
|
||||
static s32 check_wall_vw(f32 d00, f32 d01, f32 d11, f32 d20, f32 d21, f32 invDenom) {
|
||||
f32 v = ((d11 * d20) - (d01 * d21)) * invDenom;
|
||||
if (v < 0.0f || v > 1.0f) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
f32 w = ((d00 * d21) - (d01 * d20)) * invDenom;
|
||||
if (w < 0.0f || w > 1.0f || v + w > 1.0f) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
s32 check_wall_edge(Vec3f vert, Vec3f v2, f32 *d00, f32 *d01, f32 *invDenom, f32 *offset, f32 margin_radius) {
|
||||
if (FLT_IS_NONZERO(vert[1])) {
|
||||
f32 v = (v2[1] / vert[1]);
|
||||
if (v < 0.0f || v > 1.0f) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*d00 = ((vert[0] * v) - v2[0]);
|
||||
*d01 = ((vert[2] * v) - v2[2]);
|
||||
*invDenom = sqrtf(sqr(*d00) + sqr(*d01));
|
||||
*offset = (*invDenom - margin_radius);
|
||||
|
||||
return (*offset > 0.0f);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,16 +52,15 @@
|
||||
*/
|
||||
static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, struct WallCollisionData *data) {
|
||||
const f32 corner_threshold = -0.9f;
|
||||
register struct Surface *surf;
|
||||
register f32 offset;
|
||||
register f32 radius = data->radius;
|
||||
struct Surface *surf;
|
||||
f32 offset;
|
||||
f32 radius = data->radius;
|
||||
|
||||
Vec3f pos = { data->x, data->y + data->offsetY, data->z };
|
||||
Vec3f v0, v1, v2;
|
||||
register f32 d00, d01, d11, d20, d21;
|
||||
register f32 invDenom;
|
||||
register f32 v, w;
|
||||
register TerrainData type = SURFACE_DEFAULT;
|
||||
f32 d00, d01, d11, d20, d21;
|
||||
f32 invDenom;
|
||||
TerrainData type = SURFACE_DEFAULT;
|
||||
s32 numCols = 0;
|
||||
|
||||
// Max collision radius = 200
|
||||
@@ -79,11 +96,14 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, struc
|
||||
}
|
||||
|
||||
// Dot of normal and pos, + origin offset
|
||||
offset = (surf->normal.x * pos[0]) + (surf->normal.y * pos[1]) + (surf->normal.z * pos[2]) + surf->originOffset;
|
||||
offset = (surf->normal.x * pos[0])
|
||||
+ (surf->normal.y * pos[1])
|
||||
+ (surf->normal.z * pos[2])
|
||||
+ surf->originOffset;
|
||||
|
||||
// Exclude surfaces outside of the radius.
|
||||
if (offset < -radius || offset > radius) continue;
|
||||
|
||||
|
||||
vec3_diff(v0, surf->vertex2, surf->vertex1);
|
||||
vec3_diff(v1, surf->vertex3, surf->vertex1);
|
||||
vec3_diff(v2, pos, surf->vertex1);
|
||||
@@ -96,38 +116,48 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, struc
|
||||
d21 = vec3_dot(v2, v1);
|
||||
|
||||
invDenom = (d00 * d11) - (d01 * d01);
|
||||
if (FLT_IS_NONZERO(invDenom)) invDenom = 1.0f / invDenom;
|
||||
if (FLT_IS_NONZERO(invDenom)) {
|
||||
invDenom = 1.0f / invDenom;
|
||||
}
|
||||
|
||||
v = ((d11 * d20) - (d01 * d21)) * invDenom;
|
||||
if (v < 0.0f || v > 1.0f) goto edge_1_2;
|
||||
if (check_wall_vw(d00, d01, d11, d20, d21, invDenom)) {
|
||||
if (offset < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
w = ((d00 * d21) - (d01 * d20)) * invDenom;
|
||||
if (w < 0.0f || w > 1.0f || v + w > 1.0f) goto edge_1_2;
|
||||
// Edge 1-2
|
||||
if (check_wall_edge(v0, v2, &d00, &d01, &invDenom, &offset, margin_radius)) {
|
||||
// Edge 1-3
|
||||
if (check_wall_edge(v1, v2, &d00, &d01, &invDenom, &offset, margin_radius)) {
|
||||
vec3_diff(v1, surf->vertex3, surf->vertex2);
|
||||
vec3_diff(v2, pos, surf->vertex2);
|
||||
// Edge 2-3
|
||||
if (check_wall_edge(v1, v2, &d00, &d01, &invDenom, &offset, margin_radius)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos[0] += surf->normal.x * (radius - offset);
|
||||
pos[2] += surf->normal.z * (radius - offset);
|
||||
goto hasCollision;
|
||||
// Check collision
|
||||
if (FLT_IS_NONZERO(invDenom)) {
|
||||
invDenom = (offset / invDenom);
|
||||
}
|
||||
|
||||
edge_1_2:
|
||||
if (offset < 0) continue;
|
||||
CALC_OFFSET(v0, goto edge_1_3);
|
||||
// Update pos
|
||||
pos[0] += (d00 *= invDenom);
|
||||
pos[2] += (d01 *= invDenom);
|
||||
margin_radius += 0.01f;
|
||||
|
||||
edge_1_3:
|
||||
CALC_OFFSET(v1, goto edge_2_3);
|
||||
if ((d00 * surf->normal.x) + (d01 * surf->normal.z) < (corner_threshold * offset)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Update pos
|
||||
pos[0] += surf->normal.x * (radius - offset);
|
||||
pos[2] += surf->normal.z * (radius - offset);
|
||||
}
|
||||
|
||||
edge_2_3:
|
||||
vec3_diff(v1, surf->vertex3, surf->vertex2);
|
||||
vec3_diff(v2, pos, surf->vertex2);
|
||||
CALC_OFFSET(v1, continue);
|
||||
|
||||
check_collision:
|
||||
if (FLT_IS_NONZERO(invDenom)) invDenom = (offset / invDenom);
|
||||
pos[0] += (d00 *= invDenom);
|
||||
pos[2] += (d01 *= invDenom);
|
||||
margin_radius += 0.01f;
|
||||
if ((d00 * surf->normal.x) + (d01 * surf->normal.z) < (corner_threshold * offset)) continue;
|
||||
|
||||
hasCollision:
|
||||
// Has collision
|
||||
if (data->numWalls < MAX_REFERENCED_WALLS) {
|
||||
data->walls[data->numWalls++] = surf;
|
||||
}
|
||||
@@ -137,11 +167,11 @@ static s32 find_wall_collisions_from_list(struct SurfaceNode *surfaceNode, struc
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data->x = pos[0];
|
||||
data->z = pos[2];
|
||||
return numCols;
|
||||
}
|
||||
#undef CALC_OFFSET
|
||||
|
||||
/**
|
||||
* Formats the position and wall search for find_wall_collisions.
|
||||
|
||||
Reference in New Issue
Block a user