diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dcdce53..f492ada6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,7 +121,6 @@ SET (REACTPHYSICS3D_HEADERS "src/collision/HalfEdgeStructure.h" "src/collision/CollisionDetection.h" "src/collision/ContactManifold.h" - "src/collision/ContactManifoldSet.h" "src/collision/MiddlePhaseTriangleCallback.h" "src/constraint/BallAndSocketJoint.h" "src/constraint/ContactPoint.h" @@ -216,7 +215,6 @@ SET (REACTPHYSICS3D_SOURCES "src/collision/HalfEdgeStructure.cpp" "src/collision/CollisionDetection.cpp" "src/collision/ContactManifold.cpp" - "src/collision/ContactManifoldSet.cpp" "src/collision/MiddlePhaseTriangleCallback.cpp" "src/constraint/BallAndSocketJoint.cpp" "src/constraint/ContactPoint.cpp" diff --git a/src/body/CollisionBody.cpp b/src/body/CollisionBody.cpp index 7b5e4d1c..e7023f3a 100644 --- a/src/body/CollisionBody.cpp +++ b/src/body/CollisionBody.cpp @@ -40,8 +40,7 @@ using namespace reactphysics3d; * @param id ID of the body */ CollisionBody::CollisionBody(CollisionWorld& world, Entity entity, bodyindex id) - : Body(entity, id), mType(BodyType::DYNAMIC), - mContactManifoldsList(nullptr), mWorld(world) { + : Body(entity, id), mType(BodyType::DYNAMIC), mWorld(world) { #ifdef IS_PROFILING_ACTIVE mProfiler = nullptr; @@ -51,7 +50,7 @@ CollisionBody::CollisionBody(CollisionWorld& world, Entity entity, bodyindex id) // Destructor CollisionBody::~CollisionBody() { - assert(mContactManifoldsList == nullptr); + } // Add a collision shape to the body. Note that you can share a collision @@ -198,23 +197,6 @@ void CollisionBody::removeAllCollisionShapes() { } } -// Reset the contact manifold lists -void CollisionBody::resetContactManifoldsList() { - - // Delete the linked list of contact manifolds of that body - ContactManifoldListElement* currentElement = mContactManifoldsList; - while (currentElement != nullptr) { - ContactManifoldListElement* nextElement = currentElement->getNext(); - - // Delete the current element - currentElement->~ContactManifoldListElement(); - mWorld.mMemoryManager.release(MemoryManager::AllocationType::Pool, currentElement, sizeof(ContactManifoldListElement)); - - currentElement = nextElement; - } - mContactManifoldsList = nullptr; -} - // Return the current position and orientation /** * @return The current transformation of the body that transforms the local-space @@ -283,9 +265,6 @@ void CollisionBody::setIsActive(bool isActive) { mWorld.mCollisionDetection.removeProxyCollisionShape(proxyShape); } } - - // Reset the contact manifold list of the body - resetContactManifoldsList(); } RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body, diff --git a/src/body/CollisionBody.h b/src/body/CollisionBody.h index 44b338f2..152b3ec9 100644 --- a/src/body/CollisionBody.h +++ b/src/body/CollisionBody.h @@ -71,9 +71,6 @@ class CollisionBody : public Body { /// Type of body (static, kinematic or dynamic) BodyType mType; - /// First element of the linked list of contact manifolds involving this body - ContactManifoldListElement* mContactManifoldsList; - /// Reference to the world the body belongs to CollisionWorld& mWorld; @@ -86,9 +83,6 @@ class CollisionBody : public Body { // -------------------- Methods -------------------- // - /// Reset the contact manifold lists - void resetContactManifoldsList(); - /// Remove all the collision shapes void removeAllCollisionShapes(); @@ -140,9 +134,6 @@ class CollisionBody : public Body { /// Remove a collision shape from the body virtual void removeCollisionShape(ProxyShape *proxyShape); - /// Return the first element of the linked list of contact manifolds involving this body - const ContactManifoldListElement* getContactManifoldsList() const; - /// Return true if a point is inside the collision body bool testPointInside(const Vector3& worldPoint) const; @@ -201,15 +192,6 @@ inline BodyType CollisionBody::getType() const { return mType; } -// Return the first element of the linked list of contact manifolds involving this body -/** - * @return A pointer to the first element of the linked-list with the contact - * manifolds of this body - */ -inline const ContactManifoldListElement* CollisionBody::getContactManifoldsList() const { - return mContactManifoldsList; -} - /// Test if the collision body overlaps with a given AABB /** * @param worldAABB The AABB (in world-space coordinates) that will be used to test overlap diff --git a/src/body/RigidBody.cpp b/src/body/RigidBody.cpp index 0595bd2e..43eea1ab 100644 --- a/src/body/RigidBody.cpp +++ b/src/body/RigidBody.cpp @@ -109,9 +109,6 @@ void RigidBody::setType(BodyType type) { // Awake the body setIsSleeping(false); - // Remove all the contacts with this body - resetContactManifoldsList(); - // Ask the broad-phase to test again the collision shapes of the body for collision // detection (as if the body has moved) askForBroadPhaseCollisionCheck(); diff --git a/src/collision/CollisionCallback.cpp b/src/collision/CollisionCallback.cpp index e6ee5ba3..aa7bab8a 100644 --- a/src/collision/CollisionCallback.cpp +++ b/src/collision/CollisionCallback.cpp @@ -42,6 +42,9 @@ CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* assert(pair != nullptr); + + // TODO : Rework how to report contacts + /* const ContactManifoldSet& manifoldSet = pair->getContactManifoldSet(); // For each contact manifold in the set of manifolds in the pair @@ -61,11 +64,14 @@ CollisionCallback::CollisionCallbackInfo::CollisionCallbackInfo(OverlappingPair* contactManifold = contactManifold->getNext(); } + */ } // Destructor CollisionCallback::CollisionCallbackInfo::~CollisionCallbackInfo() { + // TODO : Rework how to report contacts + /* // Release memory allocator for the contact manifold list elements ContactManifoldListElement* element = contactManifoldElements; while (element != nullptr) { @@ -79,5 +85,6 @@ CollisionCallback::CollisionCallbackInfo::~CollisionCallbackInfo() { element = nextElement; } + */ } diff --git a/src/collision/CollisionDetection.cpp b/src/collision/CollisionDetection.cpp index 9587f6cb..9f2e588b 100644 --- a/src/collision/CollisionDetection.cpp +++ b/src/collision/CollisionDetection.cpp @@ -187,9 +187,6 @@ void CollisionDetection::computeMiddlePhase() { OverlappingPair* pair = it->second; - // Make all the contact manifolds and contact points of the pair obsolete - pair->makeContactsObsolete(); - // Make all the last frame collision info obsolete pair->makeLastFrameCollisionInfosObsolete(); @@ -420,9 +417,6 @@ void CollisionDetection::computeNarrowPhase() { // Reduce the number of contact points in the manifolds reducePotentialContactManifolds(mOverlappingPairs); - // Add all the contact manifolds (between colliding bodies) to the bodies - addAllContactManifoldsToBodies(); - // Report contacts to the user reportAllContacts(); @@ -499,8 +493,7 @@ void CollisionDetection::createContacts() { // We create a new contact manifold ContactManifold contactManifold(contactPair.body1Entity, contactPair.body2Entity, contactPair.proxyShape1Entity, - contactPair.proxyShape2Entity, contactPointsIndex, nbContactPoints, - mMemoryManager.getPoolAllocator(), mWorld->mConfig); + contactPair.proxyShape2Entity, contactPointsIndex, nbContactPoints); // Add the contact manifold mCurrentContactManifolds->add(contactManifold); @@ -697,19 +690,6 @@ void CollisionDetection::removeProxyCollisionShape(ProxyShape* proxyShape) { mBroadPhaseSystem.removeProxyCollisionShape(proxyShape); } -void CollisionDetection::addAllContactManifoldsToBodies() { - - RP3D_PROFILE("CollisionDetection::addAllContactManifoldsToBodies()", mProfiler); - - // For each overlapping pairs in contact during the narrow-phase - for (auto it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ++it) { - - // Add all the contact manifolds of the pair into the list of contact manifolds - // of the two bodies involved in the contact - addContactManifoldToBody(it->second); - } -} - // Ray casting method void CollisionDetection::raycast(RaycastCallback* raycastCallback, const Ray& ray, @@ -724,42 +704,6 @@ void CollisionDetection::raycast(RaycastCallback* raycastCallback, mBroadPhaseSystem.raycast(ray, rayCastTest, raycastWithCategoryMaskBits); } -// Add a contact manifold to the linked list of contact manifolds of the two bodies involved -// in the corresponding contact -void CollisionDetection::addContactManifoldToBody(OverlappingPair* pair) { - - assert(pair != nullptr); - - CollisionBody* body1 = pair->getShape1()->getBody(); - CollisionBody* body2 = pair->getShape2()->getBody(); - const ContactManifoldSet& manifoldSet = pair->getContactManifoldSet(); - - // For each contact manifold in the set of manifolds in the pair - ContactManifold* contactManifold = manifoldSet.getContactManifolds(); - while (contactManifold != nullptr) { - - assert(contactManifold->getNbContactPoints() > 0); - - // Add the contact manifold at the beginning of the linked - // list of contact manifolds of the first body - ContactManifoldListElement* listElement1 = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, - sizeof(ContactManifoldListElement))) - ContactManifoldListElement(contactManifold, - body1->mContactManifoldsList); - body1->mContactManifoldsList = listElement1; - - // Add the contact manifold at the beginning of the linked - // list of the contact manifolds of the second body - ContactManifoldListElement* listElement2 = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, - sizeof(ContactManifoldListElement))) - ContactManifoldListElement(contactManifold, - body2->mContactManifoldsList); - body2->mContactManifoldsList = listElement2; - - contactManifold = contactManifold->getNext(); - } -} - /// Convert the potential contact into actual contacts void CollisionDetection::processPotentialContacts(NarrowPhaseInfoBatch& narrowPhaseInfoBatch, bool updateLastFrameInfo) { @@ -775,22 +719,6 @@ void CollisionDetection::processPotentialContacts(NarrowPhaseInfoBatch& narrowPh narrowPhaseInfoBatch.lastFrameCollisionInfos[i]->isValid = true; } - // ----- START OLD ----- // - - if (narrowPhaseInfoBatch.isColliding[i]) { - - assert(narrowPhaseInfoBatch.contactPoints[i].size() > 0); - - // Transfer the contact points from the narrow phase info to the overlapping pair - // TOOD : COMMENT THIS - narrowPhaseInfoBatch.overlappingPairs[i]->addPotentialContactPoints(narrowPhaseInfoBatch, i); - - // Remove the contacts points from the narrow phase info object. - //narrowPhaseInfoBatch.resetContactPoints(i); - } - - // ----- END OLD ----- // - // Add the potential contacts for (uint j=0; j < narrowPhaseInfoBatch.contactPoints[i].size(); j++) { @@ -914,67 +842,8 @@ void CollisionDetection::processPotentialContacts(NarrowPhaseInfoBatch& narrowPh // Clear the obsolete manifolds and contact points and reduce the number of contacts points of the remaining manifolds void CollisionDetection::reducePotentialContactManifolds(const OverlappingPairMap& overlappingPairs) { - /* - // TODO : DELETE THIS - std::cout << "_______________ RECAP POTENTIAL CONTACTS___________________" << std::endl; - std::cout << "ContactPairs :" << std::endl; - for (uint i=0; i < mCurrentContactPairs->size(); i++) { - - ContactPair& pair = (*mCurrentContactPairs)[i]; - std::cout << " PairId : (" << pair.pairId.first << ", " << pair.pairId.second << std::endl; - std::cout << " Index : " << i << std::endl; - std::cout << " >>Manifolds : " << std::endl; - for (uint j=0; j < pair.potentialContactManifoldsIndices.size(); j++) { - - std::cout << " >>Manifold Index : " << pair.potentialContactManifoldsIndices[j] << std::endl; - } - } - std::cout << "PotentialContactManifolds :" << std::endl; - for (uint i=0; i < mPotentialContactManifolds.size(); i++) { - - ContactManifoldInfo& manifold = mPotentialContactManifolds[i]; - std::cout << " PairId : (" << manifold.pairId.first << ", " << manifold.pairId.second << std::endl; - std::cout << " Index : " << i << std::endl; - std::cout << " >>PotentialContactPoints : " << std::endl; - for (uint j=0; j < manifold.potentialContactPointsIndices.size(); j++) { - std::cout << " >>Contact Point Index : " << manifold.potentialContactPointsIndices[j] << std::endl; - } - } - std::cout << "PotentialContactPoints :" << std::endl; - for (uint i=0; i < mPotentialContactPoints.size(); i++) { - - ContactPointInfo& contactPoint = mPotentialContactPoints[i]; - std::cout << " Index : " << i << std::endl; - std::cout << " Point : (" << contactPoint.localPoint1.x << ", " << contactPoint.localPoint1.y << ", " << contactPoint.localPoint1.z << std::endl; - } - std::cout << "PotentialContactPoints :" << std::endl; - for (auto it = mCurrentMapPairIdToContactPairIndex->begin(); it != mCurrentMapPairIdToContactPairIndex->end(); ++it) { - - OverlappingPair::OverlappingPairId pairId = it->first; - uint index = it->second; - std::cout << " PairId : " << pairId.first << ", " << pairId.second << std::endl; - std::cout << " ContactPair Index : " << index << std::endl; - } - */ - RP3D_PROFILE("CollisionDetection::reducePotentialContactManifolds()", mProfiler); - // ----- OLD ----- // - - // For each overlapping pairs in contact during the narrow-phase - for (auto it = overlappingPairs.begin(); it != overlappingPairs.end(); ++it) { - - OverlappingPair* pair = it->second; - - // Clear the obsolete contact manifolds and contact points - pair->clearObsoleteManifoldsAndContactPoints(); - - // Reduce the contact manifolds and contact points if there are too many of them - pair->reduceContactManifolds(); - } - - // ----- OLD ----- // - // Reduce the number of potential contact manifolds in a contact pair for (uint i=0; i < mCurrentContactPairs->size(); i++) { @@ -1236,6 +1105,8 @@ void CollisionDetection::reportAllContacts() { RP3D_PROFILE("CollisionDetection::reportAllContacts()", mProfiler); + // TODO : Rework how we report contacts + /* // For each overlapping pairs in contact during the narrow-phase for (auto it = mOverlappingPairs.begin(); it != mOverlappingPairs.end(); ++it) { @@ -1250,6 +1121,7 @@ void CollisionDetection::reportAllContacts() { mWorld->mEventListener->newContact(collisionInfo); } } + */ } // Compute the middle-phase collision detection between two proxy shapes @@ -1499,6 +1371,8 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body // Reduce the number of contact points in the manifolds reducePotentialContactManifolds(overlappingPairs); + // TODO : Rework how we report contacts + /* // For each overlapping pair for (auto it = overlappingPairs.begin(); it != overlappingPairs.end(); ++it) { @@ -1515,6 +1389,7 @@ void CollisionDetection::testCollision(CollisionBody* body1, CollisionBody* body pair->~OverlappingPair(); mMemoryManager.release(MemoryManager::AllocationType::Pool, pair, sizeof(OverlappingPair)); } + */ } // Test and report collisions between a body and all the others bodies of the world @@ -1594,6 +1469,8 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c // Reduce the number of contact points in the manifolds reducePotentialContactManifolds(overlappingPairs); + // TODO : Rework how we report contacts + /* // For each overlapping pair for (auto it = overlappingPairs.begin(); it != overlappingPairs.end(); ++it) { @@ -1610,6 +1487,7 @@ void CollisionDetection::testCollision(CollisionBody* body, CollisionCallback* c pair->~OverlappingPair(); mMemoryManager.release(MemoryManager::AllocationType::Pool, pair, sizeof(OverlappingPair)); } + */ } // Test and report collisions between all shapes of the world @@ -1673,6 +1551,8 @@ void CollisionDetection::testCollision(CollisionCallback* callback) { // Reduce the number of contact points in the manifolds reducePotentialContactManifolds(overlappingPairs); + // TODO : Rework how we report contacts + /* // For each overlapping pair for (auto it = overlappingPairs.begin(); it != overlappingPairs.end(); ++it) { @@ -1689,6 +1569,7 @@ void CollisionDetection::testCollision(CollisionCallback* callback) { pair->~OverlappingPair(); mMemoryManager.release(MemoryManager::AllocationType::Pool, pair, sizeof(OverlappingPair)); } + */ } // Return the world event listener diff --git a/src/collision/CollisionDetection.h b/src/collision/CollisionDetection.h index 8f950e67..4829db37 100644 --- a/src/collision/CollisionDetection.h +++ b/src/collision/CollisionDetection.h @@ -193,13 +193,6 @@ class CollisionDetection { bool testNarrowPhaseCollision(NarrowPhaseInput& narrowPhaseInput, bool stopFirstContactFound, bool reportContacts, MemoryAllocator& allocator); - /// Add a contact manifold to the linked list of contact manifolds of the two bodies - /// involved in the corresponding contact. - void addContactManifoldToBody(OverlappingPair* pair); - - /// Add all the contact manifold of colliding pairs to their bodies - void addAllContactManifoldsToBodies(); - /// Compute the concave vs convex middle-phase algorithm for a given pair of bodies void computeConvexVsConcaveMiddlePhase(OverlappingPair* pair, MemoryAllocator& allocator, NarrowPhaseInput& narrowPhaseInput); diff --git a/src/collision/ContactManifold.cpp b/src/collision/ContactManifold.cpp index 8a69ed7d..4c4d7526 100644 --- a/src/collision/ContactManifold.cpp +++ b/src/collision/ContactManifold.cpp @@ -30,30 +30,15 @@ using namespace reactphysics3d; -// Constructor -// TODO : REMOVE THIS CONSTRUCTOR -ContactManifold::ContactManifold(ProxyShape* shape1, ProxyShape* shape2, - MemoryAllocator& memoryAllocator, const WorldSettings& worldSettings) - : mMemoryAllocator(memoryAllocator), mContactPointsIndex(0), mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), - mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0), - mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false), - mNext(nullptr), mPrevious(nullptr), mIsObsolete(false), - mWorldSettings(worldSettings), bodyEntity1(0, 0), bodyEntity2(0, 0), proxyShapeEntity1(0, 0), proxyShapeEntity2(0, 0) { - -} - // Constructor // TODO : REMOVE worldSettings from this constructor ContactManifold::ContactManifold(Entity bodyEntity1, Entity bodyEntity2, Entity proxyShapeEntity1, Entity proxyShapeEntity2, - uint contactPointsIndex, int8 nbContactPoints, MemoryAllocator& allocator, const WorldSettings& worldSettings) - :mMemoryAllocator(allocator), mContactPointsIndex(0), bodyEntity1(bodyEntity1), bodyEntity2(bodyEntity2), + uint contactPointsIndex, int8 nbContactPoints) + :mContactPointsIndex(0), bodyEntity1(bodyEntity1), bodyEntity2(bodyEntity2), proxyShapeEntity1(proxyShapeEntity1), proxyShapeEntity2(proxyShapeEntity2), mFrictionImpulse1(0), mFrictionImpulse2(0), - mFrictionTwistImpulse(0), mIsAlreadyInIsland(false), mWorldSettings(worldSettings) { + mFrictionTwistImpulse(0), mIsAlreadyInIsland(false) { - mContactPoints = nullptr; - mNext = nullptr; - mPrevious = nullptr; mContactPointsIndex = contactPointsIndex; mNbContactPoints = nbContactPoints; } @@ -61,348 +46,4 @@ ContactManifold::ContactManifold(Entity bodyEntity1, Entity bodyEntity2, Entity // Destructor ContactManifold::~ContactManifold() { - // Delete all the contact points - ContactPoint* contactPoint = mContactPoints; - while(contactPoint != nullptr) { - - ContactPoint* nextContactPoint = contactPoint->getNext(); - - // Delete the contact point - contactPoint->~ContactPoint(); - mMemoryAllocator.release(contactPoint, sizeof(ContactPoint)); - - contactPoint = nextContactPoint; - } -} - -// Remove a contact point -void ContactManifold::removeContactPoint(ContactPoint* contactPoint) { - - assert(mNbContactPoints > 0); - assert(mContactPoints != nullptr); - assert(contactPoint != nullptr); - - ContactPoint* previous = contactPoint->getPrevious(); - ContactPoint* next = contactPoint->getNext(); - - if (previous != nullptr) { - previous->setNext(next); - } - else { - mContactPoints = next; - } - - if (next != nullptr) { - next->setPrevious(previous); - } - - // Delete the contact point - contactPoint->~ContactPoint(); - mMemoryAllocator.release(contactPoint, sizeof(ContactPoint)); - - mNbContactPoints--; - assert(mNbContactPoints >= 0); -} - -// Return the largest depth of all the contact points -decimal ContactManifold::getLargestContactDepth() const { - decimal largestDepth = 0.0f; - - assert(mNbContactPoints > 0); - - ContactPoint* contactPoint = mContactPoints; - while(contactPoint != nullptr){ - decimal depth = contactPoint->getPenetrationDepth(); - if (depth > largestDepth) { - largestDepth = depth; - } - - contactPoint = contactPoint->getNext(); - } - - return largestDepth; -} - -// Add a contact point -void ContactManifold::addContactPoint(const ContactPointInfo* contactPointInfo) { - - // For each contact point in the manifold - bool isSimilarPointFound = false; - ContactPoint* oldContactPoint = mContactPoints; - while (oldContactPoint != nullptr) { - - assert(oldContactPoint != nullptr); - - // If the new contact point is similar (very close) to the old contact point - if (oldContactPoint->isSimilarWithContactPoint(contactPointInfo)) { - - // Replace (update) the old contact point with the new one - oldContactPoint->update(contactPointInfo); - isSimilarPointFound = true; - break; - } - - oldContactPoint = oldContactPoint->getNext(); - } - - // If we have not found a similar contact point - if (!isSimilarPointFound) { - - // Create the new contact point - ContactPoint* contactPoint = new (mMemoryAllocator.allocate(sizeof(ContactPoint))) ContactPoint(contactPointInfo, mWorldSettings); - - // Add the new contact point into the manifold - contactPoint->setNext(mContactPoints); - contactPoint->setPrevious(nullptr); - if (mContactPoints != nullptr) { - mContactPoints->setPrevious(contactPoint); - } - - mContactPoints = contactPoint; - - mNbContactPoints++; - } - - // The old manifold is no longer obsolete - mIsObsolete = false; -} - -// Set to true to make the manifold obsolete -void ContactManifold::setIsObsolete(bool isObsolete, bool setContactPoints) { - mIsObsolete = isObsolete; - - if (setContactPoints) { - ContactPoint* contactPoint = mContactPoints; - while (contactPoint != nullptr) { - contactPoint->setIsObsolete(isObsolete); - - contactPoint = contactPoint->getNext(); - } - } -} - -// Clear the obsolete contact points -void ContactManifold::clearObsoleteContactPoints() { - - assert(mContactPoints != nullptr); - - // For each contact point of the manifold - ContactPoint* contactPoint = mContactPoints; - while (contactPoint != nullptr) { - - ContactPoint* nextContactPoint = contactPoint->getNext(); - - // If the contact point is obsolete - if (contactPoint->getIsObsolete()) { - - // Remove the contact point - removeContactPoint(contactPoint); - } - - contactPoint = nextContactPoint; - } - - assert(mNbContactPoints > 0); - assert(mContactPoints != nullptr); -} - -// Reduce the number of contact points of the currently computed manifold -// This is based on the technique described by Dirk Gregorius in his -// "Contacts Creation" GDC presentation. This method will reduce the number of -// contact points to a maximum of 4 points (but it can be less). -// TODO : REMOVE THIS METHOD -void ContactManifold::reduce(const Transform& shape1ToWorldTransform) { - - assert(mContactPoints != nullptr); - - // The following algorithm only works to reduce to a maximum of 4 contact points - assert(MAX_CONTACT_POINTS_IN_MANIFOLD == 4); - - // If there are too many contact points in the manifold - if (mNbContactPoints > MAX_CONTACT_POINTS_IN_MANIFOLD) { - - uint nbReducedPoints = 0; - - ContactPoint* pointsToKeep[MAX_CONTACT_POINTS_IN_MANIFOLD]; - for (int i=0; igetNormal(); - - // Compute a search direction - const Vector3 searchDirection(1, 1, 1); - ContactPoint* element = mContactPoints; - pointsToKeep[0] = element; - decimal maxDotProduct = searchDirection.dot(element->getLocalPointOnShape1()); - element = element->getNext(); - nbReducedPoints = 1; - while(element != nullptr) { - - decimal dotProduct = searchDirection.dot(element->getLocalPointOnShape1()); - if (dotProduct > maxDotProduct) { - maxDotProduct = dotProduct; - pointsToKeep[0] = element; - } - element = element->getNext(); - } - assert(pointsToKeep[0] != nullptr); - assert(nbReducedPoints == 1); - - // Compute the second contact point we need to keep. - // The second point we keep is the one farthest away from the first point. - - decimal maxDistance = decimal(0.0); - element = mContactPoints; - while(element != nullptr) { - - if (element == pointsToKeep[0]) { - element = element->getNext(); - continue; - } - - decimal distance = (pointsToKeep[0]->getLocalPointOnShape1() - element->getLocalPointOnShape1()).lengthSquare(); - if (distance >= maxDistance) { - maxDistance = distance; - pointsToKeep[1] = element; - nbReducedPoints = 2; - } - element = element->getNext(); - } - assert(pointsToKeep[1] != nullptr); - assert(nbReducedPoints == 2); - - // Compute the third contact point we need to keep. - // The second point is the one producing the triangle with the larger area - // with first and second point. - - // We compute the most positive or most negative triangle area (depending on winding) - ContactPoint* thirdPointMaxArea = nullptr; - ContactPoint* thirdPointMinArea = nullptr; - decimal minArea = decimal(0.0); - decimal maxArea = decimal(0.0); - bool isPreviousAreaPositive = true; - element = mContactPoints; - while(element != nullptr) { - - if (element == pointsToKeep[0] || element == pointsToKeep[1]) { - element = element->getNext(); - continue; - } - - const Vector3 newToFirst = pointsToKeep[0]->getLocalPointOnShape1() - element->getLocalPointOnShape1(); - const Vector3 newToSecond = pointsToKeep[1]->getLocalPointOnShape1() - element->getLocalPointOnShape1(); - - // Compute the triangle area - decimal area = newToFirst.cross(newToSecond).dot(contactNormalShape1Space); - - if (area >= maxArea) { - maxArea = area; - thirdPointMaxArea = element; - } - if (area <= minArea) { - minArea = area; - thirdPointMinArea = element; - } - element = element->getNext(); - } - assert(minArea <= decimal(0.0)); - assert(maxArea >= decimal(0.0)); - if (maxArea > (-minArea)) { - isPreviousAreaPositive = true; - pointsToKeep[2] = thirdPointMaxArea; - nbReducedPoints = 3; - } - else { - isPreviousAreaPositive = false; - pointsToKeep[2] = thirdPointMinArea; - nbReducedPoints = 3; - } - - // Compute the 4th point by choosing the triangle that add the most - // triangle area to the previous triangle and has opposite sign area (opposite winding) - - decimal largestArea = decimal(0.0); // Largest area (positive or negative) - element = mContactPoints; - - if (nbReducedPoints == 3) { - - // For each remaining point - while(element != nullptr) { - - if (element == pointsToKeep[0] || element == pointsToKeep[1] || element == pointsToKeep[2]) { - element = element->getNext(); - continue; - } - - // For each edge of the triangle made by the first three points - for (uint i=0; i<3; i++) { - - uint edgeVertex1Index = i; - uint edgeVertex2Index = i < 2 ? i + 1 : 0; - - const Vector3 newToFirst = pointsToKeep[edgeVertex1Index]->getLocalPointOnShape1() - element->getLocalPointOnShape1(); - const Vector3 newToSecond = pointsToKeep[edgeVertex2Index]->getLocalPointOnShape1() - element->getLocalPointOnShape1(); - - // Compute the triangle area - decimal area = newToFirst.cross(newToSecond).dot(contactNormalShape1Space); - - // We are looking at the triangle with maximal area (positive or negative). - // If the previous area is positive, we are looking at negative area now. - // If the previous area is negative, we are looking at the positive area now. - if (isPreviousAreaPositive && area <= largestArea) { - largestArea = area; - pointsToKeep[3] = element; - nbReducedPoints = 4; - } - else if (!isPreviousAreaPositive && area >= largestArea) { - largestArea = area; - pointsToKeep[3] = element; - nbReducedPoints = 4; - } - } - - element = element->getNext(); - } - } - - // Delete the contact points we do not want to keep from the linked list - element = mContactPoints; - ContactPoint* previousElement = nullptr; - while(element != nullptr) { - - bool deletePoint = true; - - // Skip the points we want to keep - for (uint i=0; igetNext(); - deletePoint = false; - } - } - - if (deletePoint) { - - ContactPoint* contactPointToDelete = element; - element = element->getNext(); - - removeContactPoint(contactPointToDelete); - } - } - - assert(nbReducedPoints > 0 && nbReducedPoints <= 4); - mNbContactPoints = nbReducedPoints; - } } diff --git a/src/collision/ContactManifold.h b/src/collision/ContactManifold.h index e124e34f..f72f65dc 100644 --- a/src/collision/ContactManifold.h +++ b/src/collision/ContactManifold.h @@ -40,44 +40,6 @@ class CollisionBody; class ContactPoint; class PoolAllocator; -// Structure ContactManifoldListElement -/** - * This structure represents a single element of a linked list of contact manifolds - */ -struct ContactManifoldListElement { - - private: - - // -------------------- Attributes -------------------- // - - /// Pointer to a contact manifold with contact points - ContactManifold* mContactManifold; - - /// Next element of the list - ContactManifoldListElement* mNext; - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ContactManifoldListElement(ContactManifold* contactManifold, - ContactManifoldListElement* next) - :mContactManifold(contactManifold), mNext(next) { - - } - - /// Return the contact manifold - ContactManifold* getContactManifold() { - return mContactManifold; - } - - /// Return the next element in the linked-list - ContactManifoldListElement* getNext() { - return mNext; - } -}; - // Class ContactManifold /** * This class represents a set of contact points between two bodies that @@ -103,9 +65,6 @@ class ContactManifold { // TODO : For each of the attributes, check if we need to keep it or not - /// Reference to the memory allocator - MemoryAllocator& mMemoryAllocator; - /// Index of the first contact point of the manifold in the list of contact points uint mContactPointsIndex; @@ -121,15 +80,6 @@ class ContactManifold { /// Entity of the second proxy-shape in contact Entity proxyShapeEntity2; - /// Pointer to the first proxy shape of the contact - ProxyShape* mShape1; - - /// Pointer to the second proxy shape of the contact - ProxyShape* mShape2; - - /// Contact points in the manifold - ContactPoint* mContactPoints; - /// Number of contacts in the cache int8 mNbContactPoints; @@ -154,41 +104,11 @@ class ContactManifold { /// True if the contact manifold has already been added into an island bool mIsAlreadyInIsland; - /// Pointer to the next contact manifold in the linked-list - ContactManifold* mNext; - - /// Pointer to the previous contact manifold in linked-list - ContactManifold* mPrevious; - - /// True if the contact manifold is obsolete - bool mIsObsolete; - - /// World settings - const WorldSettings& mWorldSettings; - // -------------------- Methods -------------------- // /// Return true if the contact manifold has already been added into an island bool isAlreadyInIsland() const; - /// Set the pointer to the next element in the linked-list - void setNext(ContactManifold* nextManifold); - - /// Return true if the manifold is obsolete - bool getIsObsolete() const; - - /// Set to true to make the manifold obsolete - void setIsObsolete(bool isObselete, bool setContactPoints); - - /// Clear the obsolete contact points - void clearObsoleteContactPoints(); - - /// Return the contact normal direction Id of the manifold - short getContactNormalId() const; - - /// Return the largest depth of all the contact points - decimal getLargestContactDepth() const; - /// set the first friction vector at the center of the contact manifold void setFrictionVector1(const Vector3& mFrictionVector1); @@ -201,24 +121,12 @@ class ContactManifold { /// Set the second friction accumulated impulse void setFrictionImpulse2(decimal frictionImpulse2); - /// Add a contact point - void addContactPoint(const ContactPointInfo* contactPointInfo); - - /// Reduce the number of contact points of the currently computed manifold - void reduce(const Transform& shape1ToWorldTransform); - - /// Remove a contact point - void removeContactPoint(ContactPoint* contactPoint); - /// Set the friction twist accumulated impulse void setFrictionTwistImpulse(decimal frictionTwistImpulse); /// Set the accumulated rolling resistance impulse void setRollingResistanceImpulse(const Vector3& rollingResistanceImpulse); - /// Set the pointer to the previous element in the linked-list - void setPrevious(ContactManifold* previousManifold); - /// Return the first friction vector at the center of the contact manifold const Vector3& getFrictionVector1() const; @@ -238,14 +146,9 @@ class ContactManifold { // -------------------- Methods -------------------- // - /// Constructor - ContactManifold(ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& memoryAllocator, - const WorldSettings& worldSettings); - /// Constructor ContactManifold(Entity bodyEntity1, Entity bodyEntity2, Entity proxyShapeEntity1, Entity proxyShapeEntity2, - uint contactPointsIndex, int8 nbContactPoints, - MemoryAllocator& allocator, const WorldSettings& worldSettings); + uint contactPointsIndex, int8 nbContactPoints); /// Destructor ~ContactManifold(); @@ -256,32 +159,12 @@ class ContactManifold { /// Assignment operator ContactManifold& operator=(const ContactManifold& contactManifold) = default; - /* - /// Return a pointer to the first proxy shape of the contact - ProxyShape* getShape1() const; - - /// Return a pointer to the second proxy shape of the contact - ProxyShape* getShape2() const; - - /// Return a pointer to the first body of the contact manifold - CollisionBody* getBody1() const; - - /// Return a pointer to the second body of the contact manifold - CollisionBody* getBody2() const; - */ - /// Return the number of contact points in the manifold int8 getNbContactPoints() const; /// Return a pointer to the first contact point of the manifold ContactPoint* getContactPoints() const; - /// Return a pointer to the previous element in the linked-list - ContactManifold* getPrevious() const; - - /// Return a pointer to the next element in the linked-list - ContactManifold* getNext() const; - // -------------------- Friendship -------------------- // friend class DynamicsWorld; @@ -292,28 +175,6 @@ class ContactManifold { friend class CollisionDetection; }; -/* -// Return a pointer to the first proxy shape of the contact -inline ProxyShape* ContactManifold::getShape1() const { - return mShape1; -} - -// Return a pointer to the second proxy shape of the contact -inline ProxyShape* ContactManifold::getShape2() const { - return mShape2; -} - -// Return a pointer to the first body of the contact manifold -inline CollisionBody* ContactManifold::getBody1() const { - return mShape1->getBody(); -} - -// Return a pointer to the second body of the contact manifold -inline CollisionBody* ContactManifold::getBody2() const { - return mShape2->getBody(); -} -*/ - // Return the number of contact points in the manifold inline int8 ContactManifold::getNbContactPoints() const { return mNbContactPoints; @@ -374,41 +235,11 @@ inline void ContactManifold::setRollingResistanceImpulse(const Vector3& rollingR mRollingResistanceImpulse = rollingResistanceImpulse; } -// Return a pointer to the first contact point of the manifold -inline ContactPoint* ContactManifold::getContactPoints() const { - return mContactPoints; -} - // Return true if the contact manifold has already been added into an island inline bool ContactManifold::isAlreadyInIsland() const { return mIsAlreadyInIsland; } -// Return a pointer to the previous element in the linked-list -inline ContactManifold* ContactManifold::getPrevious() const { - return mPrevious; -} - -// Set the pointer to the previous element in the linked-list -inline void ContactManifold::setPrevious(ContactManifold* previousManifold) { - mPrevious = previousManifold; -} - -// Return a pointer to the next element in the linked-list -inline ContactManifold* ContactManifold::getNext() const { - return mNext; -} - -// Set the pointer to the next element in the linked-list -inline void ContactManifold::setNext(ContactManifold* nextManifold) { - mNext = nextManifold; -} - -// Return true if the manifold is obsolete -inline bool ContactManifold::getIsObsolete() const { - return mIsObsolete; -} - } #endif diff --git a/src/collision/ContactManifoldSet.cpp b/src/collision/ContactManifoldSet.cpp deleted file mode 100644 index b9b21cbb..00000000 --- a/src/collision/ContactManifoldSet.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2018 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -// Libraries -#include "ContactManifoldSet.h" -#include "narrowphase/NarrowPhaseInfoBatch.h" -#include "constraint/ContactPoint.h" -#include "ProxyShape.h" -#include "collision/ContactManifold.h" - -using namespace reactphysics3d; - -// Constructor -ContactManifoldSet::ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2, - MemoryAllocator& memoryAllocator, const WorldSettings& worldSettings) - : mNbManifolds(0), mShape1(shape1), - mShape2(shape2), mMemoryAllocator(memoryAllocator), mManifolds(nullptr), mWorldSettings(worldSettings) { - - // Compute the maximum number of manifolds allowed between the two shapes - mNbMaxManifolds = computeNbMaxContactManifolds(shape1->getCollisionShape(), shape2->getCollisionShape()); -} - -// Destructor -ContactManifoldSet::~ContactManifoldSet() { - - // Clear all the contact manifolds - clear(); -} - -void ContactManifoldSet::addContactPoints(const NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex) { - - assert(narrowPhaseInfoBatch.contactPoints[batchIndex].size() > 0); - - // For each potential contact point to add - for (uint i=0; i < narrowPhaseInfoBatch.contactPoints[batchIndex].size(); i++) { - - ContactPointInfo* contactPoint = narrowPhaseInfoBatch.contactPoints[batchIndex][i]; - - // Look if the contact point correspond to an existing potential manifold - // (if the contact point normal is similar to the normal of an existing manifold) - ContactManifold* manifold = mManifolds; - bool similarManifoldFound = false; - while(manifold != nullptr) { - - // Get the first contact point - const ContactPoint* point = manifold->getContactPoints(); - assert(point != nullptr); - - // If we have found a corresponding manifold for the new contact point - // (a manifold with a similar contact normal direction) - if (point->getNormal().dot(contactPoint->normal) >= mWorldSettings.cosAngleSimilarContactManifold) { - - // Add the contact point to the manifold - manifold->addContactPoint(contactPoint); - - similarManifoldFound = true; - - break; - } - - manifold = manifold->getNext(); - } - - // If we have not found an existing manifold with a similar contact normal - if (!similarManifoldFound) { - - // Create a new contact manifold - ContactManifold* manifold = createManifold(); - - // Add the contact point to the manifold - manifold->addContactPoint(contactPoint); - } - } -} - -// Return the total number of contact points in the set of manifolds -int ContactManifoldSet::getTotalNbContactPoints() const { - int nbPoints = 0; - - ContactManifold* manifold = mManifolds; - while (manifold != nullptr) { - nbPoints += manifold->getNbContactPoints(); - - manifold = manifold->getNext(); - } - - return nbPoints; -} - -// Return the maximum number of contact manifolds allowed between to collision shapes -// TODO : Remove this method -int ContactManifoldSet::computeNbMaxContactManifolds(const CollisionShape* shape1, const CollisionShape* shape2) { - - return mWorldSettings.nbMaxContactManifolds; - - /* - // If both shapes are convex - if (shape1->isConvex() && shape2->isConvex()) { - return mWorldSettings.nbMaxContactManifoldsConvexShape; - - } // If there is at least one concave shape - else { - return mWorldSettings.nbMaxContactManifoldsConcaveShape; - } - */ -} - -// Remove a contact manifold that is the least optimal (smaller penetration depth) -void ContactManifoldSet::removeNonOptimalManifold() { - - assert(mNbManifolds > mNbMaxManifolds); - assert(mManifolds != nullptr); - - // Look for a manifold that is not new and with the smallest contact penetration depth. - // At the same time, we also look for a new manifold with the smallest contact penetration depth - // in case no old manifold exists. - ContactManifold* minDepthManifold = nullptr; - decimal minDepth = DECIMAL_LARGEST; - ContactManifold* manifold = mManifolds; - while (manifold != nullptr) { - - // Get the largest contact point penetration depth of the manifold - const decimal depth = manifold->getLargestContactDepth(); - - if (depth < minDepth) { - minDepth = depth; - minDepthManifold = manifold; - } - - manifold = manifold->getNext(); - } - - // Remove the non optimal manifold - assert(minDepthManifold != nullptr); - removeManifold(minDepthManifold); -} - -// Create a new contact manifold and add it to the set -ContactManifold* ContactManifoldSet::createManifold() { - - ContactManifold* manifold = new (mMemoryAllocator.allocate(sizeof(ContactManifold))) - ContactManifold(mShape1, mShape2, mMemoryAllocator, mWorldSettings); - manifold->setPrevious(nullptr); - manifold->setNext(mManifolds); - if (mManifolds != nullptr) { - mManifolds->setPrevious(manifold); - } - mManifolds = manifold; - - mNbManifolds++; - - return manifold; -} - -// Return the contact manifold with a similar contact normal. -// If no manifold has close enough contact normal, it returns nullptr -ContactManifold* ContactManifoldSet::selectManifoldWithSimilarNormal(const Vector3& contactNormal) const { - - ContactManifold* manifold = mManifolds; - - // Return the Id of the manifold with the same normal direction id (if exists) - while (manifold != nullptr) { - - // Get the first contact point of the current manifold - const ContactPoint* point = manifold->getContactPoints(); - assert(point != nullptr); - - // If the contact normal of the two manifolds are close enough - if (contactNormal.dot(point->getNormal()) >= mWorldSettings.cosAngleSimilarContactManifold) { - return manifold; - } - - manifold = manifold->getNext(); - } - - return nullptr; -} - -// Clear the contact manifold set -void ContactManifoldSet::clear() { - - ContactManifold* manifold = mManifolds; - while(manifold != nullptr) { - - ContactManifold* nextManifold = manifold->getNext(); - - // Delete the contact manifold - manifold->~ContactManifold(); - mMemoryAllocator.release(manifold, sizeof(ContactManifold)); - - manifold = nextManifold; - - mNbManifolds--; - } - - mManifolds = nullptr; - - assert(mNbManifolds == 0); -} - -// Remove a contact manifold from the set -void ContactManifoldSet::removeManifold(ContactManifold* manifold) { - - assert(mNbManifolds > 0); - assert(manifold != nullptr); - - ContactManifold* previous = manifold->getPrevious(); - ContactManifold* next = manifold->getNext(); - - if (previous != nullptr) { - previous->setNext(next); - } - else { - mManifolds = next; - } - - if (next != nullptr) { - next->setPrevious(previous); - } - - // Delete the contact manifold - manifold->~ContactManifold(); - mMemoryAllocator.release(manifold, sizeof(ContactManifold)); - mNbManifolds--; -} - -// Make all the contact manifolds and contact points obsolete -void ContactManifoldSet::makeContactsObsolete() { - - ContactManifold* manifold = mManifolds; - while (manifold != nullptr) { - - manifold->setIsObsolete(true, true); - - manifold = manifold->getNext(); - } -} - -// Clear the obsolete contact manifolds and contact points -void ContactManifoldSet::clearObsoleteManifoldsAndContactPoints() { - - ContactManifold* manifold = mManifolds; - while (manifold != nullptr) { - - // Get the next manifold in the linked-list - ContactManifold* nextManifold = manifold->getNext(); - - // If the manifold is obsolete - if (manifold->getIsObsolete()) { - - // Delete the contact manifold - removeManifold(manifold); - } - else { - - // Clear the obsolete contact points of the manifold - manifold->clearObsoleteContactPoints(); - } - - manifold = nextManifold; - } -} - -// Remove some contact manifolds and contact points if there are too many of them -void ContactManifoldSet::reduce() { - - // Remove non optimal contact manifold while there are too many manifolds in the set - while (mNbManifolds > mNbMaxManifolds) { - removeNonOptimalManifold(); - } - - // Reduce all the contact manifolds in case they have too many contact points - ContactManifold* manifold = mManifolds; - while (manifold != nullptr) { - manifold->reduce(mShape1->getLocalToWorldTransform()); - manifold = manifold->getNext(); - } -} diff --git a/src/collision/ContactManifoldSet.h b/src/collision/ContactManifoldSet.h deleted file mode 100644 index e34473b2..00000000 --- a/src/collision/ContactManifoldSet.h +++ /dev/null @@ -1,165 +0,0 @@ -/******************************************************************************** -* ReactPhysics3D physics library, http://www.reactphysics3d.com * -* Copyright (c) 2010-2018 Daniel Chappuis * -********************************************************************************* -* * -* This software is provided 'as-is', without any express or implied warranty. * -* In no event will the authors be held liable for any damages arising from the * -* use of this software. * -* * -* Permission is granted to anyone to use this software for any purpose, * -* including commercial applications, and to alter it and redistribute it * -* freely, subject to the following restrictions: * -* * -* 1. The origin of this software must not be misrepresented; you must not claim * -* that you wrote the original software. If you use this software in a * -* product, an acknowledgment in the product documentation would be * -* appreciated but is not required. * -* * -* 2. Altered source versions must be plainly marked as such, and must not be * -* misrepresented as being the original software. * -* * -* 3. This notice may not be removed or altered from any source distribution. * -* * -********************************************************************************/ - -#ifndef REACTPHYSICS3D_CONTACT_MANIFOLD_SET_H -#define REACTPHYSICS3D_CONTACT_MANIFOLD_SET_H - -// Libraries -#include "configuration.h" - -namespace reactphysics3d { - -// Declarations -class ContactManifold; -class ProxyShape; -class MemoryAllocator; -struct WorldSettings; -struct NarrowPhaseInfoBatch; -struct Vector3; -class CollisionShape; -class Transform; - - -// Constants -const int MAX_MANIFOLDS_IN_CONTACT_MANIFOLD_SET = 3; // Maximum number of contact manifolds in the set -const int CONTACT_CUBEMAP_FACE_NB_SUBDIVISIONS = 3; // N Number for the N x N subdivisions of the cubemap - -// Class ContactManifoldSet -/** - * This class represents a set of one or several contact manifolds. Typically a - * convex/convex collision will have a set with a single manifold and a convex-concave - * collision can have more than one manifolds. Note that a contact manifold can - * contains several contact points. - */ -class ContactManifoldSet { - - private: - - // -------------------- Attributes -------------------- // - - /// Maximum number of contact manifolds in the set - int mNbMaxManifolds; - - /// Current number of contact manifolds in the set - int mNbManifolds; - - /// Pointer to the first proxy shape of the contact - ProxyShape* mShape1; - - /// Pointer to the second proxy shape of the contact - ProxyShape* mShape2; - - /// Reference to the memory allocator for the contact manifolds - MemoryAllocator& mMemoryAllocator; - - /// Contact manifolds of the set - ContactManifold* mManifolds; - - /// World settings - const WorldSettings& mWorldSettings; - - // -------------------- Methods -------------------- // - - /// Create a new contact manifold and add it to the set - ContactManifold* createManifold(); - - // Return the contact manifold with a similar contact normal. - ContactManifold* selectManifoldWithSimilarNormal(const Vector3& contactNormal) const; - - /// Remove a contact manifold that is the least optimal (smaller penetration depth) - void removeNonOptimalManifold(); - - /// Return the maximum number of contact manifolds allowed between to collision shapes - int computeNbMaxContactManifolds(const CollisionShape* shape1, const CollisionShape* shape2); - - /// Clear the contact manifold set - void clear(); - - /// Delete a contact manifold - void removeManifold(ContactManifold* manifold); - - public: - - // -------------------- Methods -------------------- // - - /// Constructor - ContactManifoldSet(ProxyShape* shape1, ProxyShape* shape2, - MemoryAllocator& memoryAllocator, const WorldSettings& worldSettings); - - /// Destructor - ~ContactManifoldSet(); - - /// Add the contact points from the narrow phase - void addContactPoints(const NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex); - - /// Return the first proxy shape - ProxyShape* getShape1() const; - - /// Return the second proxy shape - ProxyShape* getShape2() const; - - /// Return the number of manifolds in the set - int getNbContactManifolds() const; - - /// Return a pointer to the first element of the linked-list of contact manifolds - ContactManifold* getContactManifolds() const; - - /// Make all the contact manifolds and contact points obsolete - void makeContactsObsolete(); - - /// Return the total number of contact points in the set of manifolds - int getTotalNbContactPoints() const; - - /// Clear the obsolete contact manifolds and contact points - void clearObsoleteManifoldsAndContactPoints(); - - // Remove some contact manifolds and contact points if there are too many of them - void reduce(); -}; - -// Return the first proxy shape -inline ProxyShape* ContactManifoldSet::getShape1() const { - return mShape1; -} - -// Return the second proxy shape -inline ProxyShape* ContactManifoldSet::getShape2() const { - return mShape2; -} - -// Return the number of manifolds in the set -inline int ContactManifoldSet::getNbContactManifolds() const { - return mNbManifolds; -} - -// Return a pointer to the first element of the linked-list of contact manifolds -inline ContactManifold* ContactManifoldSet::getContactManifolds() const { - return mManifolds; -} - -} - -#endif - diff --git a/src/engine/CollisionWorld.cpp b/src/engine/CollisionWorld.cpp index 09809a17..55ee9861 100644 --- a/src/engine/CollisionWorld.cpp +++ b/src/engine/CollisionWorld.cpp @@ -202,9 +202,6 @@ void CollisionWorld::destroyCollisionBody(CollisionBody* collisionBody) { // Add the body ID to the list of free IDs mFreeBodiesIds.add(collisionBody->getId()); - // Reset the contact manifold list of the body - collisionBody->resetContactManifoldsList(); - mBodyComponents.removeComponent(collisionBody->getEntity()); mTransformComponents.removeComponent(collisionBody->getEntity()); mEntityManager.destroyEntity(collisionBody->getEntity()); @@ -236,17 +233,6 @@ bodyindex CollisionWorld::computeNextAvailableBodyId() { return bodyID; } -// Reset all the contact manifolds linked list of each body -void CollisionWorld::resetContactManifoldListsOfBodies() { - - // For each rigid body of the world - for (List::Iterator it = mBodies.begin(); it != mBodies.end(); ++it) { - - // Reset the contact manifold list of the body - (*it)->resetContactManifoldsList(); - } -} - // Notify the world if a body is disabled (sleeping or inactive) or not void CollisionWorld::notifyBodyDisabled(Entity bodyEntity, bool isDisabled) { diff --git a/src/engine/CollisionWorld.h b/src/engine/CollisionWorld.h index 857bd092..ac407bff 100644 --- a/src/engine/CollisionWorld.h +++ b/src/engine/CollisionWorld.h @@ -130,9 +130,6 @@ class CollisionWorld { /// Return the next available body id bodyindex computeNextAvailableBodyId(); - /// Reset all the contact manifolds linked list of each body - void resetContactManifoldListsOfBodies(); - /// Notify the world if a body is disabled (slepping or inactive) or not void notifyBodyDisabled(Entity entity, bool isDisabled); diff --git a/src/engine/DynamicsWorld.cpp b/src/engine/DynamicsWorld.cpp index 2dcfc881..68e64dc6 100644 --- a/src/engine/DynamicsWorld.cpp +++ b/src/engine/DynamicsWorld.cpp @@ -122,9 +122,6 @@ void DynamicsWorld::update(decimal timeStep) { // Notify the event listener about the beginning of an internal tick if (mEventListener != nullptr) mEventListener->beginInternalTick(); - // Reset all the contact manifolds lists of each body - resetContactManifoldListsOfBodies(); - // Compute the collision detection mCollisionDetection.computeCollisionDetection(); @@ -504,9 +501,6 @@ void DynamicsWorld::destroyRigidBody(RigidBody* rigidBody) { destroyJoint(element->joint); } - // Reset the contact manifold list of the body - rigidBody->resetContactManifoldsList(); - // Destroy the corresponding entity and its components mBodyComponents.removeComponent(rigidBody->getEntity()); mTransformComponents.removeComponent(rigidBody->getEntity()); @@ -963,6 +957,8 @@ List DynamicsWorld::getContactsList() { List contactManifolds(mMemoryManager.getPoolAllocator()); + // TODO : Rework how to report contacts + /* // For each currently overlapping pair of bodies for (auto it = mCollisionDetection.mOverlappingPairs.begin(); it != mCollisionDetection.mOverlappingPairs.end(); ++it) { @@ -980,6 +976,7 @@ List DynamicsWorld::getContactsList() { manifold = manifold->getNext(); } } + */ // Return all the contact manifold return contactManifolds; diff --git a/src/engine/OverlappingPair.cpp b/src/engine/OverlappingPair.cpp index 67d0bb18..6dacb6dd 100644 --- a/src/engine/OverlappingPair.cpp +++ b/src/engine/OverlappingPair.cpp @@ -35,7 +35,7 @@ using namespace reactphysics3d; OverlappingPair::OverlappingPair(ProxyShape* shape1, ProxyShape* shape2, MemoryAllocator& persistentMemoryAllocator, MemoryAllocator& temporaryMemoryAllocator, const WorldSettings& worldSettings) - : mPairID(computeID(shape1->getBroadPhaseId(), shape2->getBroadPhaseId())), mContactManifoldSet(shape1, shape2, persistentMemoryAllocator, worldSettings), + : mPairID(computeID(shape1->getBroadPhaseId(), shape2->getBroadPhaseId())), mProxyShape1(shape1), mProxyShape2(shape2), mPersistentAllocator(persistentMemoryAllocator), mTempMemoryAllocator(temporaryMemoryAllocator), mLastFrameCollisionInfos(mPersistentAllocator), mWorldSettings(worldSettings) { diff --git a/src/engine/OverlappingPair.h b/src/engine/OverlappingPair.h index 98766bf3..2062a499 100644 --- a/src/engine/OverlappingPair.h +++ b/src/engine/OverlappingPair.h @@ -27,7 +27,6 @@ #define REACTPHYSICS3D_OVERLAPPING_PAIR_H // Libraries -#include "collision/ContactManifoldSet.h" #include "collision/ProxyShape.h" #include "containers/Map.h" #include "containers/Pair.h" @@ -110,8 +109,9 @@ class OverlappingPair { /// Pair ID OverlappingPairId mPairID; - /// Set of persistent contact manifolds - ContactManifoldSet mContactManifoldSet; + // TODO : Replace this by entities + ProxyShape* mProxyShape1; + ProxyShape* mProxyShape2; /// Persistent memory allocator MemoryAllocator& mPersistentAllocator; @@ -158,30 +158,12 @@ class OverlappingPair { /// Return the last frame collision info LastFrameCollisionInfo* getLastFrameCollisionInfo(ShapeIdPair& shapeIds); - /// Return the a reference to the contact manifold set - const ContactManifoldSet& getContactManifoldSet(); - - /// Add potential contact-points from narrow-phase into potential contact manifolds - void addPotentialContactPoints(const NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex); - /// Return a reference to the temporary memory allocator MemoryAllocator& getTemporaryAllocator(); /// Return true if one of the shapes of the pair is a concave shape bool hasConcaveShape() const; - /// Return true if the overlapping pair has contact manifolds with contacts - bool hasContacts() const; - - /// Make the contact manifolds and contact points obsolete - void makeContactsObsolete(); - - /// Clear the obsolete contact manifold and contact points - void clearObsoleteManifoldsAndContactPoints(); - - /// Reduce the contact manifolds that have too many contact points - void reduceContactManifolds(); - /// Add a new last frame collision info if it does not exist for the given shapes already LastFrameCollisionInfo* addLastFrameInfoIfNecessary(uint shapeId1, uint shapeId2); @@ -212,12 +194,12 @@ inline OverlappingPair::OverlappingPairId OverlappingPair::getId() const { // Return the pointer to first body inline ProxyShape* OverlappingPair::getShape1() const { - return mContactManifoldSet.getShape1(); -} + return mProxyShape1; +} // Return the pointer to second body inline ProxyShape* OverlappingPair::getShape2() const { - return mContactManifoldSet.getShape2(); + return mProxyShape2; } // Return the last frame collision info for a given shape id or nullptr if none is found @@ -230,17 +212,6 @@ inline LastFrameCollisionInfo* OverlappingPair::getLastFrameCollisionInfo(ShapeI return nullptr; } -// Return the contact manifold -inline const ContactManifoldSet& OverlappingPair::getContactManifoldSet() { - return mContactManifoldSet; -} - -// Make the contact manifolds and contact points obsolete -inline void OverlappingPair::makeContactsObsolete() { - - mContactManifoldSet.makeContactsObsolete(); -} - // Return the pair of bodies index inline OverlappingPair::OverlappingPairId OverlappingPair::computeID(int shape1BroadPhaseId, int shape2BroadPhaseId) { assert(shape1BroadPhaseId >= 0 && shape2BroadPhaseId >= 0); @@ -276,31 +247,11 @@ inline bool OverlappingPair::hasConcaveShape() const { !getShape2()->getCollisionShape()->isConvex(); } -// Return true if the overlapping pair has contact manifolds with contacts -inline bool OverlappingPair::hasContacts() const { - return mContactManifoldSet.getContactManifolds() != nullptr; -} - -// Clear the obsolete contact manifold and contact points -inline void OverlappingPair::clearObsoleteManifoldsAndContactPoints() { - mContactManifoldSet.clearObsoleteManifoldsAndContactPoints(); -} - -// Reduce the contact manifolds that have too many contact points -inline void OverlappingPair::reduceContactManifolds() { - mContactManifoldSet.reduce(); -} - // Return the last frame collision info for a given pair of shape ids inline LastFrameCollisionInfo* OverlappingPair::getLastFrameCollisionInfo(uint shapeId1, uint shapeId2) const { return mLastFrameCollisionInfos[ShapeIdPair(shapeId1, shapeId2)]; } -// Create a new potential contact manifold using contact-points from narrow-phase -inline void OverlappingPair::addPotentialContactPoints(const NarrowPhaseInfoBatch& narrowPhaseInfoBatch, uint batchIndex) { - mContactManifoldSet.addContactPoints(narrowPhaseInfoBatch, batchIndex); -} - } #endif diff --git a/test/tests/collision/TestCollisionWorld.h b/test/tests/collision/TestCollisionWorld.h index affb678e..63ea12f1 100644 --- a/test/tests/collision/TestCollisionWorld.h +++ b/test/tests/collision/TestCollisionWorld.h @@ -189,7 +189,9 @@ class WorldCollisionCallback : public CollisionCallback collisionData.bodies = std::make_pair(collisionCallbackInfo.body1, collisionCallbackInfo.body2); collisionData.proxyShapes = std::make_pair(collisionCallbackInfo.proxyShape1, collisionCallbackInfo.proxyShape2); - ContactManifoldListElement* element = collisionCallbackInfo.contactManifoldElements; + // TODO : Rework how to report contacts + /* + ContactManifoldListElement* element = collisionCallbackInfo.contactManifoldElements; while (element != nullptr) { ContactManifold* contactManifold = element->getContactManifold(); @@ -210,6 +212,7 @@ class WorldCollisionCallback : public CollisionCallback element = element->getNext(); } + */ } }; @@ -508,51 +511,84 @@ class TestCollisionWorld : public Test { mCollisionCallback.reset(); mWorld->testCollision(&mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ // ---------- Single body test ---------- // mCollisionCallback.reset(); mWorld->testCollision(mBoxBody1, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mBoxBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mSphereBody1, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mSphereBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ // Two bodies test mCollisionCallback.reset(); mWorld->testCollision(mBoxBody1, mBoxBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mSphereBody1, mSphereBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mBoxBody1, mSphereBody1, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mBoxBody1, mSphereBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mBoxBody2, mSphereBody1, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ mCollisionCallback.reset(); mWorld->testCollision(mBoxBody2, mSphereBody2, &mCollisionCallback); + // TODO : Rework how to report contacts + /* rp3d_test(!mCollisionCallback.hasContacts()); + */ } void testNoOverlap() { diff --git a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp index ea57959c..03284bfa 100755 --- a/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp +++ b/testbed/scenes/collisiondetection/CollisionDetectionScene.cpp @@ -316,6 +316,8 @@ bool CollisionDetectionScene::keyboardEvent(int key, int scancode, int action, i // This method will be called for each reported contact point void ContactManager::notifyContact(const CollisionCallbackInfo& collisionCallbackInfo) { + // TODO : Rework how to report contacts + /* // For each contact manifold rp3d::ContactManifoldListElement* manifoldElement = collisionCallbackInfo.contactManifoldElements; while (manifoldElement != nullptr) { @@ -347,4 +349,5 @@ void ContactManager::notifyContact(const CollisionCallbackInfo& collisionCallbac manifoldElement = manifoldElement->getNext(); } + */ } diff --git a/testbed/src/SceneDemo.cpp b/testbed/src/SceneDemo.cpp index 3ecaee92..c2d37455 100644 --- a/testbed/src/SceneDemo.cpp +++ b/testbed/src/SceneDemo.cpp @@ -415,6 +415,8 @@ std::vector SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW // Get the list of contact manifolds from the world rp3d::List manifolds = world->getContactsList(); + // TODO : Uncomment and fix this + /* // For each contact manifold rp3d::List::Iterator it; for (it = manifolds.begin(); it != manifolds.end(); ++it) { @@ -433,8 +435,8 @@ std::vector SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW contactPoint = contactPoint->getNext(); } - } + */ return contactPoints; }