예제 #1
0
        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;
        }
예제 #2
0
        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();
        }