From b013204b3fd155a803baf36e3f1834c4e8de9e4b Mon Sep 17 00:00:00 2001 From: "chappuis.daniel" Date: Sat, 28 Jan 2012 21:03:30 +0000 Subject: [PATCH] Allocate the ContactInfo into a memory pool for better efficiency git-svn-id: https://reactphysics3d.googlecode.com/svn/trunk@465 92aac97c-a6ce-11dd-a772-7fcde58d38e6 --- src/collision/CollisionDetection.cpp | 13 ++++++------- src/collision/CollisionDetection.h | 1 + src/collision/ContactInfo.cpp | 6 ++---- src/collision/ContactInfo.h | 5 +---- src/collision/narrowphase/EPA/EPAAlgorithm.cpp | 7 +++++-- src/collision/narrowphase/EPA/EPAAlgorithm.h | 8 +++++--- src/collision/narrowphase/GJK/GJKAlgorithm.cpp | 16 ++++++++++------ src/collision/narrowphase/GJK/GJKAlgorithm.h | 5 +++-- .../narrowphase/NarrowPhaseAlgorithm.cpp | 4 ++-- src/collision/narrowphase/NarrowPhaseAlgorithm.h | 9 +++++---- .../narrowphase/SphereVsSphereAlgorithm.cpp | 10 ++++++---- .../narrowphase/SphereVsSphereAlgorithm.h | 5 +++-- src/constraint/Contact.cpp | 2 +- 13 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index e61df8b4..e6598186 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -41,14 +41,12 @@ using namespace std; // Constructor CollisionDetection::CollisionDetection(PhysicsWorld* world) - : world(world), narrowPhaseGJKAlgorithm(*this), narrowPhaseSphereVsSphereAlgorithm(*this), - memoryPoolContacts(NB_MAX_CONTACTS), memoryPoolOverlappingPairs(NB_MAX_COLLISION_PAIRS) { + : world(world), memoryPoolContacts(NB_MAX_CONTACTS), memoryPoolOverlappingPairs(NB_MAX_COLLISION_PAIRS), + memoryPoolContactInfos(NB_MAX_CONTACTS), narrowPhaseGJKAlgorithm(*this, memoryPoolContactInfos), + narrowPhaseSphereVsSphereAlgorithm(*this, memoryPoolContactInfos) { // Create the broad-phase algorithm that will be used (Sweep and Prune with AABB) broadPhaseAlgorithm = new SweepAndPruneAlgorithm(*this); - - // Create the narrow-phase algorithm that will be used - //narrowPhaseAlgorithm = new GJKAlgorithm(*this); } // Destructor @@ -133,8 +131,9 @@ bool CollisionDetection::computeNarrowPhase() { // Create a new contact Contact* contact = new(memoryPoolContacts.allocateObject()) Contact(body1, body2, contactInfo); - // Free the contact info memory - delete contactInfo; + // Delete and remove the contact info from the memory pool + contactInfo->ContactInfo::~ContactInfo(); + memoryPoolContactInfos.freeObject(contactInfo); // Add the contact to the contact cache of the corresponding overlapping pair (*it).second->addContact(contact); diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index bcd5091e..0a67a8e9 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -65,6 +65,7 @@ class CollisionDetection { SphereVsSphereAlgorithm narrowPhaseSphereVsSphereAlgorithm; // Narrow-phase Sphere vs Sphere algorithm MemoryPool memoryPoolContacts; // Memory pool for the contacts MemoryPool memoryPoolOverlappingPairs; // Memory pool for the overlapping pairs + MemoryPool memoryPoolContactInfos; // Memory pool for the contact info void computeBroadPhase(); // Compute the broad-phase collision detection bool computeNarrowPhase(); // Compute the narrow-phase collision detection diff --git a/src/collision/ContactInfo.cpp b/src/collision/ContactInfo.cpp index 1e0ca080..fa3e0226 100644 --- a/src/collision/ContactInfo.cpp +++ b/src/collision/ContactInfo.cpp @@ -31,9 +31,7 @@ using namespace reactphysics3d; // Constructor ContactInfo::ContactInfo(const Vector3& normal, decimal penetrationDepth, - const Vector3& localPoint1, const Vector3& localPoint2, - const Transform& transform1, const Transform& transform2) - : normal(normal), penetrationDepth(penetrationDepth), localPoint1(localPoint1), localPoint2(localPoint2), - worldPoint1(transform1 * localPoint1), worldPoint2(transform2 * localPoint2) { + const Vector3& localPoint1, const Vector3& localPoint2) + : normal(normal), penetrationDepth(penetrationDepth), localPoint1(localPoint1), localPoint2(localPoint2) { } diff --git a/src/collision/ContactInfo.h b/src/collision/ContactInfo.h index 6c5c4995..db4d4a59 100644 --- a/src/collision/ContactInfo.h +++ b/src/collision/ContactInfo.h @@ -47,12 +47,9 @@ struct ContactInfo { const decimal penetrationDepth; // Penetration depth of the contact const Vector3 localPoint1; // Contact point of body 1 in local space of body 1 const Vector3 localPoint2; // Contact point of body 2 in local space of body 2 - const Vector3 worldPoint1; // Contact point of body 1 in world space - const Vector3 worldPoint2; // Contact point of body 2 in world space ContactInfo(const Vector3& normal, decimal penetrationDepth, - const Vector3& localPoint1, const Vector3& localPoint2, - const Transform& transform1, const Transform& transform2); // Constructor + const Vector3& localPoint1, const Vector3& localPoint2); // Constructor }; } // End of the ReactPhysics3D namespace diff --git a/src/collision/narrowphase/EPA/EPAAlgorithm.cpp b/src/collision/narrowphase/EPA/EPAAlgorithm.cpp index c7c958ec..3a2a7ba1 100644 --- a/src/collision/narrowphase/EPA/EPAAlgorithm.cpp +++ b/src/collision/narrowphase/EPA/EPAAlgorithm.cpp @@ -32,7 +32,8 @@ using namespace reactphysics3d; // Constructor -EPAAlgorithm::EPAAlgorithm() { +EPAAlgorithm::EPAAlgorithm(MemoryPool& memoryPoolContactInfos) + : memoryPoolContactInfos(memoryPoolContactInfos) { } @@ -374,7 +375,9 @@ bool EPAAlgorithm::computePenetrationDepthAndContactPoints(Simplex simplex, cons Vector3 normal = v.getUnit(); decimal penetrationDepth = v.length(); assert(penetrationDepth > 0.0); - contactInfo = new ContactInfo(normal, penetrationDepth, pALocal, pBLocal, transform1, transform2); + + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(normal, penetrationDepth, pALocal, pBLocal); return true; } diff --git a/src/collision/narrowphase/EPA/EPAAlgorithm.h b/src/collision/narrowphase/EPA/EPAAlgorithm.h index 8adf0bbd..34db26b2 100644 --- a/src/collision/narrowphase/EPA/EPAAlgorithm.h +++ b/src/collision/narrowphase/EPA/EPAAlgorithm.h @@ -32,6 +32,7 @@ #include "../../ContactInfo.h" #include "../../../mathematics/mathematics.h" #include "TriangleEPA.h" +#include "../../../memory/MemoryPool.h" #include // ReactPhysics3D namespace @@ -72,16 +73,17 @@ class TriangleComparison { */ class EPAAlgorithm { private: + MemoryPool& memoryPoolContactInfos; // Reference to the memory pool for contact infos TriangleComparison triangleComparison; // Triangle comparison operator - + void addFaceCandidate(TriangleEPA* triangle, TriangleEPA** heap, uint& nbTriangles, decimal upperBoundSquarePenDepth); // Add a triangle face in the candidate triangle heap int isOriginInTetrahedron(const Vector3& p1, const Vector3& p2, const Vector3& p3, const Vector3& p4) const; // Decide if the origin is in the tetrahedron public: - EPAAlgorithm(); // Constructor - ~EPAAlgorithm(); // Destructor + EPAAlgorithm(MemoryPool& memoryPoolContactInfos); // Constructor + ~EPAAlgorithm(); // Destructor bool computePenetrationDepthAndContactPoints(Simplex simplex, const Collider* collider1, const Transform& transform1, const Collider* collider2, const Transform& transform2, diff --git a/src/collision/narrowphase/GJK/GJKAlgorithm.cpp b/src/collision/narrowphase/GJK/GJKAlgorithm.cpp index 46cc1a0e..a73c1b6f 100644 --- a/src/collision/narrowphase/GJK/GJKAlgorithm.cpp +++ b/src/collision/narrowphase/GJK/GJKAlgorithm.cpp @@ -41,8 +41,8 @@ using namespace reactphysics3d; // Constructor -GJKAlgorithm::GJKAlgorithm(CollisionDetection& collisionDetection) - :NarrowPhaseAlgorithm(collisionDetection) { +GJKAlgorithm::GJKAlgorithm(CollisionDetection& collisionDetection, MemoryPool& memoryPoolContactInfos) + :NarrowPhaseAlgorithm(collisionDetection, memoryPoolContactInfos), algoEPA(memoryPoolContactInfos) { } @@ -133,7 +133,8 @@ bool GJKAlgorithm::testCollision(const Collider* collider1, const Transform& tra // Reject the contact if the penetration depth is negative (due too numerical errors) if (penetrationDepth <= 0.0) return false; - contactInfo = new ContactInfo(normal, penetrationDepth, pA, pB, transform1, transform2); + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(normal, penetrationDepth, pA, pB); // There is an intersection, therefore we return true return true; @@ -161,7 +162,8 @@ bool GJKAlgorithm::testCollision(const Collider* collider1, const Transform& tra // Reject the contact if the penetration depth is negative (due too numerical errors) if (penetrationDepth <= 0.0) return false; - contactInfo = new ContactInfo(normal, penetrationDepth, pA, pB, transform1, transform2); + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(normal, penetrationDepth, pA, pB); // There is an intersection, therefore we return true return true; @@ -187,7 +189,8 @@ bool GJKAlgorithm::testCollision(const Collider* collider1, const Transform& tra // Reject the contact if the penetration depth is negative (due too numerical errors) if (penetrationDepth <= 0.0) return false; - contactInfo = new ContactInfo(normal, penetrationDepth, pA, pB, transform1, transform2); + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(normal, penetrationDepth, pA, pB); // There is an intersection, therefore we return true return true; @@ -221,7 +224,8 @@ bool GJKAlgorithm::testCollision(const Collider* collider1, const Transform& tra // Reject the contact if the penetration depth is negative (due too numerical errors) if (penetrationDepth <= 0.0) return false; - contactInfo = new ContactInfo(normal, penetrationDepth, pA, pB, transform1, transform2); + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(normal, penetrationDepth, pA, pB); // There is an intersection, therefore we return true return true; diff --git a/src/collision/narrowphase/GJK/GJKAlgorithm.h b/src/collision/narrowphase/GJK/GJKAlgorithm.h index 6a1f770e..32efa084 100644 --- a/src/collision/narrowphase/GJK/GJKAlgorithm.h +++ b/src/collision/narrowphase/GJK/GJKAlgorithm.h @@ -66,8 +66,9 @@ class GJKAlgorithm : public NarrowPhaseAlgorithm { ContactInfo*& contactInfo, Vector3& v); // Compute the penetration depth for enlarged objects public : - GJKAlgorithm(CollisionDetection& collisionDetection); // Constructor - ~GJKAlgorithm(); // Destructor + GJKAlgorithm(CollisionDetection& collisionDetection, + MemoryPool& memoryPoolContactInfos); // Constructor + ~GJKAlgorithm(); // Destructor virtual bool testCollision(const Collider* collider1, const Transform& transform1, const Collider* collider2, const Transform& transform2, diff --git a/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp b/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp index db5819b6..88405521 100644 --- a/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp +++ b/src/collision/narrowphase/NarrowPhaseAlgorithm.cpp @@ -30,8 +30,8 @@ using namespace reactphysics3d; // Constructor -NarrowPhaseAlgorithm::NarrowPhaseAlgorithm(CollisionDetection& collisionDetection) - :collisionDetection(collisionDetection), currentOverlappingPair(0) { +NarrowPhaseAlgorithm::NarrowPhaseAlgorithm(CollisionDetection& collisionDetection, MemoryPool& memoryPool) + :collisionDetection(collisionDetection), memoryPoolContactInfos(memoryPool), currentOverlappingPair(0) { } diff --git a/src/collision/narrowphase/NarrowPhaseAlgorithm.h b/src/collision/narrowphase/NarrowPhaseAlgorithm.h index 891f1ff2..9bb62f89 100644 --- a/src/collision/narrowphase/NarrowPhaseAlgorithm.h +++ b/src/collision/narrowphase/NarrowPhaseAlgorithm.h @@ -47,12 +47,13 @@ class CollisionDetection; */ class NarrowPhaseAlgorithm { protected : - CollisionDetection& collisionDetection; // Reference to the collision detection object - OverlappingPair* currentOverlappingPair; // Overlapping pair of the bodies currently tested for collision + CollisionDetection& collisionDetection; // Reference to the collision detection object + MemoryPool& memoryPoolContactInfos; // Reference to the memory pool for contact infos + OverlappingPair* currentOverlappingPair; // Overlapping pair of the bodies currently tested for collision public : - NarrowPhaseAlgorithm(CollisionDetection& collisionDetection); // Constructor - virtual ~NarrowPhaseAlgorithm(); // Destructor + NarrowPhaseAlgorithm(CollisionDetection& collisionDetection, MemoryPool& memoryPool); // Constructor + virtual ~NarrowPhaseAlgorithm(); // Destructor void setCurrentOverlappingPair(OverlappingPair* overlappingPair); // Set the current overlapping pair of bodies virtual bool testCollision(const Collider* collider1, const Transform& transform1, diff --git a/src/collision/narrowphase/SphereVsSphereAlgorithm.cpp b/src/collision/narrowphase/SphereVsSphereAlgorithm.cpp index f5b1a93a..ead002a6 100644 --- a/src/collision/narrowphase/SphereVsSphereAlgorithm.cpp +++ b/src/collision/narrowphase/SphereVsSphereAlgorithm.cpp @@ -31,8 +31,8 @@ using namespace reactphysics3d; // Constructor -SphereVsSphereAlgorithm::SphereVsSphereAlgorithm(CollisionDetection& collisionDetection) - :NarrowPhaseAlgorithm(collisionDetection) { +SphereVsSphereAlgorithm::SphereVsSphereAlgorithm(CollisionDetection& collisionDetection, MemoryPool& memoryPoolContactInfos) + :NarrowPhaseAlgorithm(collisionDetection, memoryPoolContactInfos) { } @@ -62,8 +62,10 @@ bool SphereVsSphereAlgorithm::testCollision(const Collider* collider1, const Tra Vector3 intersectionOnBody1 = sphereCollider1->getRadius() * centerSphere2InBody1LocalSpace.getUnit(); Vector3 intersectionOnBody2 = sphereCollider2->getRadius() * centerSphere1InBody2LocalSpace.getUnit(); decimal penetrationDepth = sumRadius - std::sqrt(squaredDistanceBetweenCenters); - contactInfo = new ContactInfo(vectorBetweenCenters.getUnit(), penetrationDepth, intersectionOnBody1, - intersectionOnBody2, transform1, transform2); + + // Create the contact info object + contactInfo = new (memoryPoolContactInfos.allocateObject()) ContactInfo(vectorBetweenCenters.getUnit(), penetrationDepth, + intersectionOnBody1, intersectionOnBody2); return true; } diff --git a/src/collision/narrowphase/SphereVsSphereAlgorithm.h b/src/collision/narrowphase/SphereVsSphereAlgorithm.h index f4d0b8dc..03d33af8 100644 --- a/src/collision/narrowphase/SphereVsSphereAlgorithm.h +++ b/src/collision/narrowphase/SphereVsSphereAlgorithm.h @@ -45,8 +45,9 @@ class SphereVsSphereAlgorithm : public NarrowPhaseAlgorithm { protected : public : - SphereVsSphereAlgorithm(CollisionDetection& collisionDetection); // Constructor - virtual ~SphereVsSphereAlgorithm(); // Destructor + SphereVsSphereAlgorithm(CollisionDetection& collisionDetection, + MemoryPool& memoryPoolContactInfos); // Constructor + virtual ~SphereVsSphereAlgorithm(); // Destructor virtual bool testCollision(const Collider* collider1, const Transform& transform1, const Collider* collider2, const Transform& transform2, diff --git a/src/constraint/Contact.cpp b/src/constraint/Contact.cpp index d8526059..085d6390 100644 --- a/src/constraint/Contact.cpp +++ b/src/constraint/Contact.cpp @@ -33,7 +33,7 @@ using namespace std; Contact::Contact(Body* const body1, Body* const body2, const ContactInfo* contactInfo) : Constraint(body1, body2, 3, true, CONTACT), normal(contactInfo->normal), penetrationDepth(contactInfo->penetrationDepth), localPointOnBody1(contactInfo->localPoint1), localPointOnBody2(contactInfo->localPoint2), - worldPointOnBody1(contactInfo->worldPoint1), worldPointOnBody2(contactInfo->worldPoint2) { + worldPointOnBody1(body1->getTransform() * contactInfo->localPoint1), worldPointOnBody2(body2->getTransform() * contactInfo->localPoint2) { assert(penetrationDepth > 0.0); // Compute the auxiliary lower and upper bounds