intersectTriangle method

Vector3? intersectTriangle(
  1. Vector3 a,
  2. Vector3 b,
  3. Vector3 c,
  4. bool backfaceCulling,
  5. Vector3 target,
)

Implementation

Vector3? intersectTriangle(Vector3 a, Vector3 b, Vector3 c, bool backfaceCulling, Vector3 target) {
  final _edge1 = Vector3.zero();
  final _edge2 = Vector3.zero();
  final _normal = Vector3.zero();
  final _diff = Vector3.zero();

  _edge1.sub2(b, a);
  _edge2.sub2(c, a);
  _normal.cross2(_edge1, _edge2);

  // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
  // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
  //   |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
  //   |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
  //   |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
  double DdN = direction.dot(_normal);
  int sign;

  if (DdN > 0) {
    if (backfaceCulling) return null;
    sign = 1;
  } else if (DdN < 0) {
    sign = -1;
    DdN = -DdN;
  } else {
    return null;
  }

  _diff.sub2(origin, a);
  final DdQxE2 = sign * direction.dot(_edge2.cross2(_diff, _edge2));

  // b1 < 0, no intersection
  if (DdQxE2 < 0) {
    return null;
  }

  final DdE1xQ = sign * direction.dot(_edge1.cross(_diff));

  // b2 < 0, no intersection
  if (DdE1xQ < 0) {
    return null;
  }

  // b1+b2 > 1, no intersection
  if (DdQxE2 + DdE1xQ > DdN) {
    return null;
  }

  // Line intersects triangle, check if ray does.
  final QdN = -sign * _diff.dot(_normal);

  // t < 0, no intersection
  if (QdN < 0) {
    return null;
  }

  // Ray intersects triangle.
  return at(QdN / DdN, target);
}