raycast method

  1. @override
bool raycast(
  1. RayCastOutput output,
  2. RayCastInput input,
  3. Transform xf,
  4. int childIndex,
)
override

Cast a ray against a child shape.

output is the ray-cast results. input the ray-cast input parameters. transform to be applied to the shape. childIndex the child shape index Returns true if the child shape is hit.

Implementation

@override
bool raycast(
  RayCastOutput output,
  RayCastInput input,
  Transform xf,
  int childIndex,
) {
  final v1 = vertex1;
  final v2 = vertex2;
  final xfq = xf.q;
  final xfp = xf.p;

  // Put the ray into the edge's frame of reference.
  var tempX = input.p1.x - xfp.x;
  var tempY = input.p1.y - xfp.y;
  final p1x = xfq.cos * tempX + xfq.sin * tempY;
  final p1y = -xfq.sin * tempX + xfq.cos * tempY;

  tempX = input.p2.x - xfp.x;
  tempY = input.p2.y - xfp.y;
  final p2x = xfq.cos * tempX + xfq.sin * tempY;
  final p2y = -xfq.sin * tempX + xfq.cos * tempY;

  final dx = p2x - p1x;
  final dy = p2y - p1y;

  final normal = Vector2(v2.y - v1.y, v1.x - v2.x);
  normal.normalize();

  tempX = v1.x - p1x;
  tempY = v1.y - p1y;
  final numerator = normal.x * tempX + normal.y * tempY;
  final denominator = normal.x * dx + normal.y * dy;

  if (denominator == 0.0) {
    return false;
  }

  final t = numerator / denominator;
  if (t < 0.0 || 1.0 < t) {
    return false;
  }

  final qx = p1x + t * dx;
  final qy = p1y + t * dy;

  final rx = v2.x - v1.x;
  final ry = v2.y - v1.y;
  final rr = rx * rx + ry * ry;
  if (rr == 0.0) {
    return false;
  }
  tempX = qx - v1.x;
  tempY = qy - v1.y;
  final s = (tempX * rx + tempY * ry) / rr;
  if (s < 0.0 || 1.0 < s) {
    return false;
  }

  output.fraction = t;
  if (numerator > 0.0) {
    output.normal.x = -xfq.cos * normal.x + xfq.sin * normal.y;
    output.normal.y = -xfq.sin * normal.x - xfq.cos * normal.y;
  } else {
    output.normal.x = xfq.cos * normal.x - xfq.sin * normal.y;
    output.normal.y = xfq.sin * normal.x + xfq.cos * normal.y;
  }
  return true;
}