Remove old code

This commit is contained in:
Daniel Chappuis 2019-05-12 14:26:55 +02:00
parent e672c0d617
commit ac0e620f02
19 changed files with 79 additions and 1263 deletions

View File

@ -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"

View File

@ -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,

View File

@ -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

View File

@ -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();

View File

@ -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;
}
*/
}

View File

@ -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

View File

@ -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);

View File

@ -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; i<MAX_CONTACT_POINTS_IN_MANIFOLD; i++) {
pointsToKeep[i] = nullptr;
}
// Compute the initial contact point we need to keep.
// The first point we keep is always the point in a given
// constant direction (in order to always have same contact points
// between frames for better stability)
const Transform worldToShape1Transform = shape1ToWorldTransform.getInverse();
// Compute the contact normal of the manifold (we use the first contact point)
// in the local-space of the first collision shape
const Vector3 contactNormalShape1Space = worldToShape1Transform.getOrientation() * mContactPoints->getNormal();
// 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; i<nbReducedPoints; i++) {
if (element == pointsToKeep[i]) {
previousElement = element;
element = element->getNext();
deletePoint = false;
}
}
if (deletePoint) {
ContactPoint* contactPointToDelete = element;
element = element->getNext();
removeContactPoint(contactPointToDelete);
}
}
assert(nbReducedPoints > 0 && nbReducedPoints <= 4);
mNbContactPoints = nbReducedPoints;
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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

View File

@ -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<CollisionBody*>::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) {

View File

@ -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);

View File

@ -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<const ContactManifold*> DynamicsWorld::getContactsList() {
List<const ContactManifold*> 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<const ContactManifold*> DynamicsWorld::getContactsList() {
manifold = manifold->getNext();
}
}
*/
// Return all the contact manifold
return contactManifolds;

View File

@ -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) {

View File

@ -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

View File

@ -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() {

View File

@ -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();
}
*/
}

View File

@ -415,6 +415,8 @@ std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW
// Get the list of contact manifolds from the world
rp3d::List<const rp3d::ContactManifold*> manifolds = world->getContactsList();
// TODO : Uncomment and fix this
/*
// For each contact manifold
rp3d::List<const rp3d::ContactManifold*>::Iterator it;
for (it = manifolds.begin(); it != manifolds.end(); ++it) {
@ -433,8 +435,8 @@ std::vector<ContactPoint> SceneDemo::computeContactPointsOfWorld(rp3d::DynamicsW
contactPoint = contactPoint->getNext();
}
}
*/
return contactPoints;
}