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