triangleCapsuleIntersect method

OctreeData? triangleCapsuleIntersect(
  1. Capsule capsule,
  2. Triangle triangle
)

Implementation

OctreeData? triangleCapsuleIntersect(Capsule capsule, Triangle triangle) {
  Vector3 point1, point2;
  Line3 line1, line2;

  triangle.getPlane(_plane);

  num d1 = _plane.distanceToPoint(capsule.start) - capsule.radius;
  num d2 = _plane.distanceToPoint(capsule.end) - capsule.radius;

  if ((d1 > 0 && d2 > 0) || (d1 < -capsule.radius && d2 < -capsule.radius)) {
    return null;
  }

  num delta = Math.abs(d1 / (Math.abs(d1) + Math.abs(d2)));
  Vector3 intersectPoint = _v1.copy(capsule.start).lerp(capsule.end, delta);

  if (triangle.containsPoint(intersectPoint)) {
    return OctreeData(
        normal: _plane.normal.clone(), point: intersectPoint.clone(), depth: Math.abs(Math.min(d1, d2)));
  }

  num r2 = capsule.radius * capsule.radius;

  line1 = _line1.set(capsule.start, capsule.end);

  List<List<Vector3>> lines = [
    [triangle.a, triangle.b],
    [triangle.b, triangle.c],
    [triangle.c, triangle.a]
  ];

  for (int i = 0; i < lines.length; i++) {
    line2 = _line2.set(lines[i][0], lines[i][1]);

    List<Vector3> pt = capsule.lineLineMinimumPoints(line1, line2);
    point1 = pt[0];
    point2 = pt[1];
    if (point1.distanceToSquared(point2) < r2) {
      return OctreeData(
          normal: point1.clone().sub(point2).normalize(),
          point: point2.clone(),
          depth: capsule.radius - point1.distanceTo(point2));
    }
  }

  return null;
}