bool Brush::intersectsBrush(const Brush& brush) const { if (!bounds().intersects(brush.bounds())) return false; // separating axis theorem // http://www.geometrictools.com/Documentation/MethodOfSeparatingAxes.pdf FaceList::const_iterator faceIt, faceEnd; const VertexList& myVertices = vertices(); const FaceList& theirFaces = brush.faces(); for (faceIt = theirFaces.begin(), faceEnd = theirFaces.end(); faceIt != faceEnd; ++faceIt) { const Face& theirFace = **faceIt; const Vec3f& origin = theirFace.vertices().front()->position; const Vec3f& direction = theirFace.boundary().normal; if (vertexStatusFromRay(origin, direction, myVertices) == PointStatus::PSAbove) return false; } const VertexList& theirVertices = brush.vertices(); for (faceIt = m_faces.begin(), faceEnd = m_faces.end(); faceIt != faceEnd; ++faceIt) { const Face& myFace = **faceIt; const Vec3f& origin = myFace.vertices().front()->position; const Vec3f& direction = myFace.boundary().normal; if (vertexStatusFromRay(origin, direction, theirVertices) == PointStatus::PSAbove) return false; } const EdgeList& myEdges = edges(); const EdgeList& theirEdges = brush.edges(); EdgeList::const_iterator myEdgeIt, myEdgeEnd, theirEdgeIt, theirEdgeEnd; for (myEdgeIt = myEdges.begin(), myEdgeEnd = myEdges.end(); myEdgeIt != myEdgeEnd; ++myEdgeIt) { const Edge& myEdge = **myEdgeIt; for (theirEdgeIt = theirEdges.begin(), theirEdgeEnd = theirEdges.end(); theirEdgeIt != theirEdgeEnd; ++theirEdgeIt) { const Edge& theirEdge = **theirEdgeIt; const Vec3f myEdgeVec = myEdge.vector(); const Vec3f theirEdgeVec = theirEdge.vector(); const Vec3f& origin = myEdge.start->position; const Vec3f direction = crossed(myEdgeVec, theirEdgeVec); PointStatus::Type myStatus = vertexStatusFromRay(origin, direction, myVertices); if (myStatus != PointStatus::PSInside) { PointStatus::Type theirStatus = vertexStatusFromRay(origin, direction, theirVertices); if (theirStatus != PointStatus::PSInside) { if (myStatus != theirStatus) return false; } } } } return true; }