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) {
  // Compute the offset origin, edges, and normal.

  // from http://www.geometrictools.com/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h

  _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);
}