I'm implementing Quake player collision using PM_RecursiveHullCheck. Most walls work fine, but walls with normals around (0, 1, 0) behave as if they're pushed backwards - collision happens, but only after the player has already entered the wall. I calculate a bounding box offset (plane_normal[i] >= 0 ? clip_maxs[i] : clip_mins[i]) * plane_normal[i] but currently don't use it. The original Quake code has no offset calculation. Should I be applying this offset to the plane distance? Why would only Y-axis normals be affected?
// PM_RecursiveHullCheck - the collision detection function
int PM_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3 p1, vec3 p2, pmtrace_t *trace){
clipnode_t *node;
plane_t *plane;
float t1, t2;
if (num < 0) {
if (num != CONTENTS_SOLID) {
trace->allsolid = 0;
if (num == CONTENTS_EMPTY)
trace->inopen = 1;
else
trace->inwater = 1;
} else
trace->startsolid = 1;
return 1;
}
node = hull->clipnodes + num;
plane = hull->planes + node->planenum;
vec3 plane_normal;
plane_normal[0] = plane->normal.x;
plane_normal[1] = plane->normal.y;
plane_normal[2] = plane->normal.z;
float dist = plane->dist;
if (plane->type < 3) {
t1 = p1[plane->type] - dist; // Not using offset here
t2 = p2[plane->type] - dist;
} else {
t1 = glm_vec_dot(plane_normal, p1) - dist;
t2 = glm_vec_dot(plane_normal, p2) - dist;
}
if (t1 >= 0 && t2 >= 0)
return PM_RecursiveHullCheck(hull, node->children[0], p1f, p2f, p1, p2, trace);
if (t1 < 0 && t2 < 0)
return PM_RecursiveHullCheck(hull, node->children[1], p1f, p2f, p1, p2, trace);
// ... rest of function
}
// Hull setup
player.mins = {-16, -16, -24};
player.maxs = {16, 16, 32};
player.player_hull->clipnodes = world.tree->clipnodes;
player.player_hull->planes = world.tree->planes;
player.player_hull->clip_mins = player.mins;
player.player_hull->clip_maxs = player.maxs;