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; }
void Brush::restore(const Brush& brushTemplate, bool checkId) { if (checkId) assert(uniqueId() == brushTemplate.uniqueId()); Utility::deleteAll(m_faces); const FaceList templateFaces = brushTemplate.faces(); for (size_t i = 0; i < templateFaces.size(); i++) { Face* face = new Face(m_worldBounds, m_forceIntegerFacePoints, *templateFaces[i]); face->setBrush(this); m_faces.push_back(face); } rebuildGeometry(); }