raycastAABB static method

RaycastHit<AABB>? raycastAABB(
  1. Ray ray,
  2. AABB aabb
)

Implementation

static RaycastHit<AABB>? raycastAABB(Ray ray, AABB aabb) {
  final invDirX = 1 / ray.direction.x;
  final invDirY = 1 / ray.direction.y;

  final t1 =
      invDirX >= 0 ? (aabb.left - ray.origin.x) * invDirX : (aabb.right - ray.origin.x) * invDirX;
  final t2 =
      invDirX >= 0 ? (aabb.right - ray.origin.x) * invDirX : (aabb.left - ray.origin.x) * invDirX;

  final ty1 =
      invDirY >= 0 ? (aabb.top - ray.origin.y) * invDirY : (aabb.bottom - ray.origin.y) * invDirY;
  final ty2 =
      invDirY >= 0 ? (aabb.bottom - ray.origin.y) * invDirY : (aabb.top - ray.origin.y) * invDirY;

  if (t1 > ty2 || ty1 > t2) return null;

  final tMin = math.max(t1, ty1);
  final tMax = math.min(t2, ty2);

  final t = tMin >= 0 ? tMin : (tMax >= 0 ? tMax : null);
  if (t == null) return null;

  double nx, ny;
  if (t == t1) {
    nx = invDirX >= 0 ? -1 : 1;
    ny = 0;
  } else if (t == ty1) {
    nx = 0;
    ny = invDirY >= 0 ? -1 : 1;
  } else if (t == t2) {
    nx = invDirX >= 0 ? 1 : -1;
    ny = 0;
  } else {
    nx = 0;
    ny = invDirY >= 0 ? 1 : -1;
  }

  return RaycastHit<AABB>(
    object: aabb,
    point: Vec2(
      ray.origin.x + ray.direction.x * t,
      ray.origin.y + ray.direction.y * t,
    ),
    normal: Vec2(nx, ny),
    distance: t,
  );
}