intersectsOBB method

dynamic intersectsOBB(
  1. dynamic obb, {
  2. dynamic epsilon = Math.epsilon,
})

Reference: OBB-OBB Intersection in Real-Time Collision Detection by Christer Ericson (chapter 4.4.1)

Implementation

intersectsOBB(obb, {epsilon = Math.epsilon}) {
  // prepare data structures (the code uses the same nomenclature like the reference)

  a.c = center;
  a.e[0] = halfSize.x;
  a.e[1] = halfSize.y;
  a.e[2] = halfSize.z;
  rotation.extractBasis(a.u[0], a.u[1], a.u[2]);

  b.c = obb.center;
  b.e[0] = obb.halfSize.x;
  b.e[1] = obb.halfSize.y;
  b.e[2] = obb.halfSize.z;
  obb.rotation.extractBasis(b.u[0], b.u[1], b.u[2]);

  // compute rotation matrix expressing b in a's coordinate frame

  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      R[i][j] = a.u[i].dot(b.u[j]);
    }
  }

  // compute translation vector

  v1.subVectors(b.c, a.c);

  // bring translation into a's coordinate frame

  t[0] = v1.dot(a.u[0]);
  t[1] = v1.dot(a.u[1]);
  t[2] = v1.dot(a.u[2]);

  // compute common subexpressions. Add in an epsilon term to
  // counteract arithmetic errors when two edges are parallel and
  // their cross product is (near) null

  for (var i = 0; i < 3; i++) {
    for (var j = 0; j < 3; j++) {
      absR[i][j] = Math.abs(R[i][j]) + epsilon;
    }
  }

  var ra, rb;

  // test axes L = A0, L = A1, L = A2

  for (var i = 0; i < 3; i++) {
    ra = a.e[i];
    rb = b.e[0] * absR[i][0] + b.e[1] * absR[i][1] + b.e[2] * absR[i][2];
    if (Math.abs(t[i]) > ra + rb) return false;
  }

  // test axes L = B0, L = B1, L = B2

  for (var i = 0; i < 3; i++) {
    ra = a.e[0] * absR[0][i] + a.e[1] * absR[1][i] + a.e[2] * absR[2][i];
    rb = b.e[i];
    if (Math.abs(t[0] * R[0][i] + t[1] * R[1][i] + t[2] * R[2][i]) > ra + rb) return false;
  }

  // test axis L = A0 x B0

  ra = a.e[1] * absR[2][0] + a.e[2] * absR[1][0];
  rb = b.e[1] * absR[0][2] + b.e[2] * absR[0][1];
  if (Math.abs(t[2] * R[1][0] - t[1] * R[2][0]) > ra + rb) return false;

  // test axis L = A0 x B1

  ra = a.e[1] * absR[2][1] + a.e[2] * absR[1][1];
  rb = b.e[0] * absR[0][2] + b.e[2] * absR[0][0];
  if (Math.abs(t[2] * R[1][1] - t[1] * R[2][1]) > ra + rb) return false;

  // test axis L = A0 x B2

  ra = a.e[1] * absR[2][2] + a.e[2] * absR[1][2];
  rb = b.e[0] * absR[0][1] + b.e[1] * absR[0][0];
  if (Math.abs(t[2] * R[1][2] - t[1] * R[2][2]) > ra + rb) return false;

  // test axis L = A1 x B0

  ra = a.e[0] * absR[2][0] + a.e[2] * absR[0][0];
  rb = b.e[1] * absR[1][2] + b.e[2] * absR[1][1];
  if (Math.abs(t[0] * R[2][0] - t[2] * R[0][0]) > ra + rb) return false;

  // test axis L = A1 x B1

  ra = a.e[0] * absR[2][1] + a.e[2] * absR[0][1];
  rb = b.e[0] * absR[1][2] + b.e[2] * absR[1][0];
  if (Math.abs(t[0] * R[2][1] - t[2] * R[0][1]) > ra + rb) return false;

  // test axis L = A1 x B2

  ra = a.e[0] * absR[2][2] + a.e[2] * absR[0][2];
  rb = b.e[0] * absR[1][1] + b.e[1] * absR[1][0];
  if (Math.abs(t[0] * R[2][2] - t[2] * R[0][2]) > ra + rb) return false;

  // test axis L = A2 x B0

  ra = a.e[0] * absR[1][0] + a.e[1] * absR[0][0];
  rb = b.e[1] * absR[2][2] + b.e[2] * absR[2][1];
  if (Math.abs(t[1] * R[0][0] - t[0] * R[1][0]) > ra + rb) return false;

  // test axis L = A2 x B1

  ra = a.e[0] * absR[1][1] + a.e[1] * absR[0][1];
  rb = b.e[0] * absR[2][2] + b.e[2] * absR[2][0];
  if (Math.abs(t[1] * R[0][1] - t[0] * R[1][1]) > ra + rb) return false;

  // test axis L = A2 x B2

  ra = a.e[0] * absR[1][2] + a.e[1] * absR[0][2];
  rb = b.e[0] * absR[2][1] + b.e[1] * absR[2][0];
  if (Math.abs(t[1] * R[0][2] - t[0] * R[1][2]) > ra + rb) return false;

  // since no separating axis is found, the OBBs must be intersecting

  return true;
}