Use List instead of std::vector compute segment clipping in SAT algorithm

This commit is contained in:
Daniel Chappuis 2017-12-14 22:25:52 +01:00
parent 47869627d1
commit f2ee00ca68
4 changed files with 36 additions and 28 deletions

View File

@ -39,10 +39,10 @@ using namespace reactphysics3d;
* @param id The ID of the body * @param id The ID of the body
*/ */
RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, bodyindex id) RigidBody::RigidBody(const Transform& transform, CollisionWorld& world, bodyindex id)
: CollisionBody(transform, world, id), mInitMass(decimal(1.0)), : CollisionBody(transform, world, id), mArrayIndex(0), mInitMass(decimal(1.0)),
mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()), mCenterOfMassLocal(0, 0, 0), mCenterOfMassWorld(transform.getPosition()),
mIsGravityEnabled(true), mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)), mIsGravityEnabled(true), mLinearDamping(decimal(0.0)), mAngularDamping(decimal(0.0)),
mJointsList(nullptr), mArrayIndex(0) { mJointsList(nullptr) {
// Compute the inverse mass // Compute the inverse mass
mMassInverse = decimal(1.0) / mInitMass; mMassInverse = decimal(1.0) / mInitMass;

View File

@ -374,8 +374,8 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI
uint firstEdgeIndex = face.edgeIndex; uint firstEdgeIndex = face.edgeIndex;
uint edgeIndex = firstEdgeIndex; uint edgeIndex = firstEdgeIndex;
std::vector<Vector3> planesPoints; List<Vector3> planesPoints(mMemoryAllocator, 2);
std::vector<Vector3> planesNormals; List<Vector3> planesNormals(mMemoryAllocator, 2);
// For each adjacent edge of the separating face of the polyhedron // For each adjacent edge of the separating face of the polyhedron
do { do {
@ -393,15 +393,15 @@ bool SATAlgorithm::computeCapsulePolyhedronFaceContactPoints(uint referenceFaceI
Vector3 clipPlaneNormal = faceNormal.cross(edgeDirection); Vector3 clipPlaneNormal = faceNormal.cross(edgeDirection);
// Construct a clipping plane for each adjacent edge of the separating face of the polyhedron // Construct a clipping plane for each adjacent edge of the separating face of the polyhedron
planesPoints.push_back(polyhedron->getVertexPosition(edge.vertexIndex)); planesPoints.add(polyhedron->getVertexPosition(edge.vertexIndex));
planesNormals.push_back(clipPlaneNormal); planesNormals.add(clipPlaneNormal);
edgeIndex = edge.nextEdgeIndex; edgeIndex = edge.nextEdgeIndex;
} while(edgeIndex != firstEdgeIndex); } while(edgeIndex != firstEdgeIndex);
// First we clip the inner segment of the capsule with the four planes of the adjacent faces // First we clip the inner segment of the capsule with the four planes of the adjacent faces
std::vector<Vector3> clipSegment = clipSegmentWithPlanes(capsuleSegAPolyhedronSpace, capsuleSegBPolyhedronSpace, planesPoints, planesNormals); List<Vector3> clipSegment = clipSegmentWithPlanes(capsuleSegAPolyhedronSpace, capsuleSegBPolyhedronSpace, planesPoints, planesNormals, mMemoryAllocator);
// Project the two clipped points into the polyhedron face // Project the two clipped points into the polyhedron face
const Vector3 delta = faceNormal * (penetrationDepth - capsuleRadius); const Vector3 delta = faceNormal * (penetrationDepth - capsuleRadius);

View File

@ -222,27 +222,34 @@ decimal reactphysics3d::computePointToLineDistance(const Vector3& linePointA, co
// Clip a segment against multiple planes and return the clipped segment vertices // Clip a segment against multiple planes and return the clipped segment vertices
// This method implements the SutherlandHodgman clipping algorithm // This method implements the SutherlandHodgman clipping algorithm
std::vector<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB, List<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
const std::vector<Vector3>& planesPoints, const List<Vector3>& planesPoints,
const std::vector<Vector3>& planesNormals) { const List<Vector3>& planesNormals,
Allocator& allocator) {
assert(planesPoints.size() == planesNormals.size()); assert(planesPoints.size() == planesNormals.size());
std::vector<Vector3> inputVertices = {segA, segB}; List<Vector3> list1(allocator, 2);
std::vector<Vector3> outputVertices; List<Vector3> list2(allocator, 2);
List<Vector3>* inputVertices = &list1;
List<Vector3>* outputVertices = &list2;
inputVertices->add(segA);
inputVertices->add(segB);
// For each clipping plane // For each clipping plane
for (uint p=0; p<planesPoints.size(); p++) { for (uint p=0; p<planesPoints.size(); p++) {
// If there is no more vertices, stop // If there is no more vertices, stop
if (inputVertices.empty()) return inputVertices; if (inputVertices->size() == 0) return *inputVertices;
assert(inputVertices.size() == 2); assert(inputVertices->size() == 2);
outputVertices.clear(); outputVertices->clear();
Vector3& v1 = inputVertices[0]; Vector3& v1 = (*inputVertices)[0];
Vector3& v2 = inputVertices[1]; Vector3& v2 = (*inputVertices)[1];
decimal v1DotN = (v1 - planesPoints[p]).dot(planesNormals[p]); decimal v1DotN = (v1 - planesPoints[p]).dot(planesNormals[p]);
decimal v2DotN = (v2 - planesPoints[p]).dot(planesNormals[p]); decimal v2DotN = (v2 - planesPoints[p]).dot(planesNormals[p]);
@ -257,39 +264,40 @@ std::vector<Vector3> reactphysics3d::clipSegmentWithPlanes(const Vector3& segA,
decimal t = computePlaneSegmentIntersection(v1, v2, planesNormals[p].dot(planesPoints[p]), planesNormals[p]); decimal t = computePlaneSegmentIntersection(v1, v2, planesNormals[p].dot(planesPoints[p]), planesNormals[p]);
if (t >= decimal(0) && t <= decimal(1.0)) { if (t >= decimal(0) && t <= decimal(1.0)) {
outputVertices.push_back(v1 + t * (v2 - v1)); outputVertices->add(v1 + t * (v2 - v1));
} }
else { else {
outputVertices.push_back(v2); outputVertices->add(v2);
} }
} }
else { else {
outputVertices.push_back(v1); outputVertices->add(v1);
} }
// Add the second vertex // Add the second vertex
outputVertices.push_back(v2); outputVertices->add(v2);
} }
else { // If the second vertex is behind the clipping plane else { // If the second vertex is behind the clipping plane
// If the first vertex is in front of the clippling plane // If the first vertex is in front of the clippling plane
if (v1DotN >= decimal(0.0)) { if (v1DotN >= decimal(0.0)) {
outputVertices.push_back(v1); outputVertices->add(v1);
// The first point we keep is the intersection between the segment v1, v2 and the clipping plane // The first point we keep is the intersection between the segment v1, v2 and the clipping plane
decimal t = computePlaneSegmentIntersection(v1, v2, -planesNormals[p].dot(planesPoints[p]), -planesNormals[p]); decimal t = computePlaneSegmentIntersection(v1, v2, -planesNormals[p].dot(planesPoints[p]), -planesNormals[p]);
if (t >= decimal(0.0) && t <= decimal(1.0)) { if (t >= decimal(0.0) && t <= decimal(1.0)) {
outputVertices.push_back(v1 + t * (v2 - v1)); outputVertices->add(v1 + t * (v2 - v1));
} }
} }
} }
inputVertices = outputVertices; inputVertices = outputVertices;
outputVertices = p % 2 == 0 ? &list1 : &list2;
} }
return outputVertices; return *outputVertices;
} }
// Clip a polygon against multiple planes and return the clipped polygon vertices // Clip a polygon against multiple planes and return the clipped polygon vertices
@ -302,7 +310,6 @@ List<Vector3> reactphysics3d::clipPolygonWithPlanes(const List<Vector3>& polygon
uint nbMaxElements = polygonVertices.size() + planesPoints.size(); uint nbMaxElements = polygonVertices.size() + planesPoints.size();
List<Vector3> list1(allocator, nbMaxElements); List<Vector3> list1(allocator, nbMaxElements);
List<Vector3> list2(allocator, nbMaxElements); List<Vector3> list2(allocator, nbMaxElements);
List<decimal> dotProducts(allocator, nbMaxElements * 2);
const List<Vector3>* inputVertices = &polygonVertices; const List<Vector3>* inputVertices = &polygonVertices;
List<Vector3>* outputVertices = &list2; List<Vector3>* outputVertices = &list2;

View File

@ -112,9 +112,10 @@ decimal computePlaneSegmentIntersection(const Vector3& segA, const Vector3& segB
decimal computePointToLineDistance(const Vector3& linePointA, const Vector3& linePointB, const Vector3& point); decimal computePointToLineDistance(const Vector3& linePointA, const Vector3& linePointB, const Vector3& point);
/// Clip a segment against multiple planes and return the clipped segment vertices /// Clip a segment against multiple planes and return the clipped segment vertices
std::vector<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB, List<Vector3> clipSegmentWithPlanes(const Vector3& segA, const Vector3& segB,
const std::vector<Vector3>& planesPoints, const List<Vector3>& planesPoints,
const std::vector<Vector3>& planesNormals); const List<Vector3>& planesNormals,
Allocator& allocator);
/// Clip a polygon against multiple planes and return the clipped polygon vertices /// Clip a polygon against multiple planes and return the clipped polygon vertices
List<Vector3> clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints, List<Vector3> clipPolygonWithPlanes(const List<Vector3>& polygonVertices, const List<Vector3>& planesPoints,