Skip to main content
GameDev.net gamedev.net
🔒 Locked

Quake BSP collision: walls with normal (0,1,0) are offset backwards, allowing player to pass through

Started by redC Feb 12 at 11:45 PM 1 replies 500+ views
Original Post
redC
redC

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;
JoeJ
JoeJ

redC said:
The original Quake code has no offset calculation. Should I be applying this offset to the plane distance?

Not sure what you exactly mean with the bounding box offset, but adding any kind of offset to plane distance sounds like a bad idea.

If it would work to add arbitrary offsets to bsp planes, there would be no need for any collision specific data at all, since we could just add various offsets to the visual bsp to represent various player sizes.
But we can't do this because shifting planes would change the geometry, so our static bsp would longer represent this new geometry precisely, causing errors.

No idea why you have issues only with planes on Y axis, but maybe this conclusion is just coincidence and no hint on the cause of the bug.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.