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.subVectors(b, a);
  _edge2.subVectors(c, a);
  _normal.crossVectors(_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)
  var 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.subVectors(origin, a);
  var DdQxE2 = sign * direction.dot(_edge2.crossVectors(_diff, _edge2));

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

  var 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.
  var QdN = -sign * _diff.dot(_normal);

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

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