From 30af76dfaf51b0fc4cbb67bec9398706566d0c2f Mon Sep 17 00:00:00 2001 From: Daniel Chappuis Date: Mon, 21 Sep 2020 13:52:23 +0200 Subject: [PATCH] Small optimization of clipPolygonWithPlanes() function --- CMakeLists.txt | 2 +- include/reactphysics3d/containers/Array.h | 10 ++-- .../mathematics/mathematics_functions.h | 53 ++++++++++++------- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b396a6d..6688ba44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,6 +121,7 @@ set (REACTPHYSICS3D_HEADERS "include/reactphysics3d/collision/CollisionCallback.h" "include/reactphysics3d/collision/OverlapCallback.h" "include/reactphysics3d/mathematics/mathematics.h" + "include/reactphysics3d/mathematics/mathematics_common.h" "include/reactphysics3d/mathematics/mathematics_functions.h" "include/reactphysics3d/mathematics/Matrix2x2.h" "include/reactphysics3d/mathematics/Matrix3x3.h" @@ -220,7 +221,6 @@ set (REACTPHYSICS3D_SOURCES "src/components/SliderJointComponents.cpp" "src/collision/CollisionCallback.cpp" "src/collision/OverlapCallback.cpp" - "src/mathematics/mathematics_functions.cpp" "src/mathematics/Matrix2x2.cpp" "src/mathematics/Matrix3x3.cpp" "src/mathematics/Quaternion.cpp" diff --git a/include/reactphysics3d/containers/Array.h b/include/reactphysics3d/containers/Array.h index 6b450256..f79ac094 100755 --- a/include/reactphysics3d/containers/Array.h +++ b/include/reactphysics3d/containers/Array.h @@ -387,17 +387,19 @@ class Array { /// Remove an element from the array at a given index and replace it by the last one of the array (if any) /// Append another array at the end of the current one - void addRange(const Array& array) { + void addRange(const Array& array, uint32 startIndex = 0) { + + assert(startIndex <= array.size()); // If we need to allocate more memory - if (mSize + array.size() > mCapacity) { + if (mSize + (array.size() - startIndex) > mCapacity) { // Allocate memory - reserve(mSize + array.size()); + reserve(mSize + array.size() - startIndex); } // Add the elements of the array to the current one - for(uint32 i=0; i(mBuffer + mSize)) T(array[i]); mSize++; diff --git a/include/reactphysics3d/mathematics/mathematics_functions.h b/include/reactphysics3d/mathematics/mathematics_functions.h index fb333658..4f0e45bb 100755 --- a/include/reactphysics3d/mathematics/mathematics_functions.h +++ b/include/reactphysics3d/mathematics/mathematics_functions.h @@ -330,32 +330,37 @@ RP3D_FORCE_INLINE Array clipSegmentWithPlanes(const Vector3& segA, cons // Clip a polygon against multiple planes and return the clipped polygon vertices // This method implements the Sutherland–Hodgman clipping algorithm RP3D_FORCE_INLINE void clipPolygonWithPlanes(const Array& polygonVertices, const Array& planesPoints, - const Array& planesNormals, Array& outClippedPolygonVertices, - MemoryAllocator& allocator) { + const Array& planesNormals, Array& outClippedPolygonVertices, + MemoryAllocator& allocator) { assert(planesPoints.size() == planesNormals.size()); - const uint32 nbMaxElements = polygonVertices.size() + planesPoints.size(); - Array inputVertices(allocator, nbMaxElements); + const uint32 nbPlanesPoints = planesPoints.size(); + + const uint32 nbMaxElements = polygonVertices.size() * 2 * nbPlanesPoints; + Array vertices(allocator, nbMaxElements * nbPlanesPoints); outClippedPolygonVertices.reserve(nbMaxElements); - inputVertices.addRange(polygonVertices); + vertices.addRange(polygonVertices); + + uint32 currentPolygonStartIndex = 0; + uint32 nbInputVertices = polygonVertices.size(); // For each clipping plane - const uint32 nbPlanesPoints = planesPoints.size(); for (uint32 p=0; p < nbPlanesPoints; p++) { - outClippedPolygonVertices.clear(); + uint32 nextNbInputVertices = 0; - const uint32 nbInputVertices = inputVertices.size(); - uint32 vStart = nbInputVertices - 1; + uint32 vStart = currentPolygonStartIndex + nbInputVertices - 1; + + const decimal planeNormalDotPlanePoint = planesNormals[p].dot(planesPoints[p]); // For each edge of the polygon - for (uint vEnd = 0; vEnd& polygonVertic if (v1DotN < decimal(0.0)) { // The second 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]); + const decimal t = computePlaneSegmentIntersection(v1, v2, planeNormalDotPlanePoint, planesNormals[p]); if (t >= decimal(0) && t <= decimal(1.0)) { - outClippedPolygonVertices.add(v1 + t * (v2 - v1)); + vertices.add(v1 + t * (v2 - v1)); + nextNbInputVertices++; } else { - outClippedPolygonVertices.add(v2); + vertices.add(v2); + nextNbInputVertices++; } } // Add the second vertex - outClippedPolygonVertices.add(v2); + vertices.add(v2); + nextNbInputVertices++; } else { // If the second vertex is behind the clipping plane @@ -386,13 +394,15 @@ RP3D_FORCE_INLINE void clipPolygonWithPlanes(const Array& polygonVertic if (v1DotN >= decimal(0.0)) { // 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]); + const decimal t = computePlaneSegmentIntersection(v1, v2, -planeNormalDotPlanePoint, -planesNormals[p]); if (t >= decimal(0.0) && t <= decimal(1.0)) { - outClippedPolygonVertices.add(v1 + t * (v2 - v1)); + vertices.add(v1 + t * (v2 - v1)); + nextNbInputVertices++; } else { - outClippedPolygonVertices.add(v1); + vertices.add(v1); + nextNbInputVertices++; } } } @@ -400,8 +410,11 @@ RP3D_FORCE_INLINE void clipPolygonWithPlanes(const Array& polygonVertic vStart = vEnd; } - inputVertices = outClippedPolygonVertices; + currentPolygonStartIndex += nbInputVertices; + nbInputVertices = nextNbInputVertices; } + + outClippedPolygonVertices.addRange(vertices, currentPolygonStartIndex); } // Project a point onto a plane that is given by a point and its unit length normal