Example #1
0
bool Mesh::verify_same_direction(Mesh::Face current_face, Point3D vertices[],
    Point3D& point, Vector3D& normal)
{
  bool is_same_direction = false;
  // Make sure the intersect face is pointing to the same direction
  for (unsigned int i = 0; i < current_face.size(); i++) {
    is_same_direction =
        ((vertices[(i + 1) % current_face.size()] - vertices[i]).cross(
            point - vertices[i]).dot(normal)) >= 0;
    if (!is_same_direction) {
      break;
    }
  }
  return is_same_direction;
}
Example #2
0
bool Mesh::faceIntersection(
    const Ray& ray, HitRecord* hitRecord, const Mesh::Face& face) {
  // Get a point on the plane
  Vector3D norm;
  double t;
  {
    const auto& p0 = m_verts[face[0]];
    const auto& p1 = m_verts[face[1]];
    const auto& p2 = m_verts[face[face.size()-1]];
    norm = (p1 - p0).cross(p2 - p0);
    auto rayNorm = ray.dir.dot(norm);

    // Parallel
    if (isZero(rayNorm)) return false;

    t = (p0 - ray.start).dot(norm) / rayNorm;
    // No intersection
    if (t < 0 || isZero(t)) {
      return false;
    }
  }

  // Intersection point
  auto planePt = ray.at(t);
  // Now check if planePt is "left" of everything
  for (size_t i = 0; i < face.size(); ++i) {
    // Go over points in order
    const auto& p1 = m_verts[face[i]];
    const auto& p2 = m_verts[face[(i + 1) % face.size()]];
    // from p1 to p2
    const auto side = p2 - p1;
    // cross from p1 to plane pt and dot against normal
    auto k = norm.dot(side.cross(planePt - p1));
    if (!isZero(k) && k < 0) {
      // Zero means on the side; negative means opposite dir from norm
      return false;
    }
  }

  // Update if this is a better t value
  return hitRecord->update(norm, planePt, t);
}