bool ICollisionSystem::Intersection(sf::Shape& theMovingShape, sf::Shape& theOtherShape, sf::Vector2f& theMinimumTranslation) { //Exit if either shape is empty; if(theMovingShape.getPointCount()==0 || theOtherShape.getPointCount()==0) return false; //Variables std::vector<sf::Vector2f> anAxes; Uint32 anIndex; sf::Vector2f anSmallestAxis; double anOverlap=std::numeric_limits<double>::max(); Uint32 anMovingPointCount=theMovingShape.getPointCount(); Uint32 anOtherPointCount=theOtherShape.getPointCount(); sf::Vector2f anPointA, anPointB; //Axes for this object. for(anIndex=0;anIndex<anMovingPointCount-1;++anIndex) { anPointA=theMovingShape.getPoint(anIndex); anPointB=theMovingShape.getPoint(anIndex+1); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); } anPointA=theMovingShape.getPoint(anMovingPointCount-1); anPointB=theMovingShape.getPoint(0); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); //Axes for other object. for(anIndex=0;anIndex<theOtherShape.getPointCount()-1;++anIndex) { anPointA=theOtherShape.getPoint(anIndex); anPointB=theOtherShape.getPoint(anIndex+1); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); } anPointA=theOtherShape.getPoint(anOtherPointCount-1); anPointB=theOtherShape.getPoint(0); anAxes.push_back(NormalizeVector(sf::Vector2f(anPointB.y - anPointA.y, -(anPointB.x - anPointA.x)))); for(anIndex=0;anIndex<anAxes.size();++anIndex) { float anMinA, anMaxA, anMinB, anMaxB; // ... project the points of both OBBs onto the axis ... ProjectOntoAxis(theMovingShape,anAxes[anIndex], anMinA, anMaxA); ProjectOntoAxis(theOtherShape,anAxes[anIndex], anMinB, anMaxB); // ... and check whether the outermost projected points of both OBBs overlap. // If this is not the case, the Seperating Axis Theorem states that there can be no collision between the rectangles if(!((anMinB<=anMaxA)&&(anMaxB>=anMinA))) { return false; } double o; if(anMinB<=anMaxA) o=anMaxA-anMinB; else o=anMaxB-anMinA; if(o<anOverlap) { anSmallestAxis=anAxes[anIndex]; anOverlap=o; } } theMinimumTranslation=anSmallestAxis; theMinimumTranslation*=(float)anOverlap; return true; }
sf::ConvexShape toConvexShape(const sf::Shape& shape) { const unsigned int size = shape.getPointCount(); sf::ConvexShape convexShape; // Adapt shape properties convexShape.setFillColor(shape.getFillColor()); convexShape.setOutlineColor(shape.getOutlineColor()); convexShape.setOutlineThickness(shape.getOutlineThickness()); convexShape.setPointCount(size); // Adapt transform properties convexShape.setPosition(shape.getPosition()); convexShape.setRotation(shape.getRotation()); convexShape.setScale(shape.getScale()); convexShape.setOrigin(shape.getOrigin()); // Adapt texture properties convexShape.setTexture(shape.getTexture()); convexShape.setTextureRect(shape.getTextureRect()); for (unsigned int i = 0; i < size; ++i) { convexShape.setPoint(i, shape.getPoint(i)); } return convexShape; }
void ICollisionSystem::ProjectOntoAxis(const sf::Shape& theShape, const sf::Vector2f& theAxis, float& theMin, float& theMax) { sf::Vector2f anPoint=theShape.getTransform().transformPoint(theShape.getPoint(0)); GQE::Uint32 anPointCount=theShape.getPointCount(); theMin = (anPoint.x*theAxis.x+anPoint.y*theAxis.y); theMax = theMin; for (int j = 1; j<anPointCount; j++) { anPoint=theShape.getTransform().transformPoint(theShape.getPoint(j)); float Projection = (anPoint.x*theAxis.x+anPoint.y*theAxis.y); if (Projection<theMin) theMin=Projection; if (Projection>theMax) theMax=Projection; } }
bool TrackChunk::collidesWith(const sf::Shape &shape) const{ bg::model::ring<sf::Vector2f> ring; for (std::size_t i=0; i<shape.getPointCount(); ++i) bg::append(ring, shape.getTransform().transformPoint(shape.getPoint(i))); return bg::intersects(ring, m_points); }
static sf::Vector2f Shape_point(sf::Shape const& s, unsigned idx) { if (idx >= s.getPointCount()) throw "point index of shape out of range"; return s.getPoint(idx); }