Modify the policy to drop contact manifolds. First drop the old ones before the new ones
This commit is contained in:
parent
17d1ee3681
commit
d5617526ff
|
@ -71,7 +71,7 @@ void CollisionDetection::computeCollisionDetection() {
|
||||||
computeMiddlePhase();
|
computeMiddlePhase();
|
||||||
|
|
||||||
// Compute the narrow-phase collision detection
|
// Compute the narrow-phase collision detection
|
||||||
computeNarrowPhase();
|
computeNarrowPhase();
|
||||||
|
|
||||||
// Reset the linked list of narrow-phase info
|
// Reset the linked list of narrow-phase info
|
||||||
mNarrowPhaseInfoList = nullptr;
|
mNarrowPhaseInfoList = nullptr;
|
||||||
|
@ -410,6 +410,9 @@ void CollisionDetection::processPotentialContacts(OverlappingPair* pair) {
|
||||||
potentialManifold = potentialManifold->mNext;
|
potentialManifold = potentialManifold->mNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset the isNew status of the manifolds
|
||||||
|
pair->resetIsNewManifoldStatus();
|
||||||
|
|
||||||
// Clear the obsolete contact manifolds and contact points
|
// Clear the obsolete contact manifolds and contact points
|
||||||
pair->clearObsoleteManifoldsAndContactPoints();
|
pair->clearObsoleteManifoldsAndContactPoints();
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ ContactManifold::ContactManifold(const ContactManifoldInfo* manifoldInfo, ProxyS
|
||||||
: mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), mContactNormalId(manifoldInfo->getContactNormalId()),
|
: mShape1(shape1), mShape2(shape2), mContactPoints(nullptr), mContactNormalId(manifoldInfo->getContactNormalId()),
|
||||||
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
|
mNbContactPoints(0), mFrictionImpulse1(0.0), mFrictionImpulse2(0.0),
|
||||||
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
|
mFrictionTwistImpulse(0.0), mIsAlreadyInIsland(false),
|
||||||
mMemoryAllocator(memoryAllocator), mNext(nullptr), mPrevious(nullptr), mIsObsolete(false) {
|
mMemoryAllocator(memoryAllocator), mNext(nullptr), mPrevious(nullptr), mIsObsolete(false), mIsNew(true) {
|
||||||
|
|
||||||
// For each contact point info in the manifold
|
// For each contact point info in the manifold
|
||||||
const ContactPointInfo* pointInfo = manifoldInfo->getFirstContactPointInfo();
|
const ContactPointInfo* pointInfo = manifoldInfo->getFirstContactPointInfo();
|
||||||
|
@ -85,6 +85,7 @@ void ContactManifold::addContactPoint(const ContactPointInfo* contactPointInfo)
|
||||||
mContactPoints = contactPoint;
|
mContactPoints = contactPoint;
|
||||||
|
|
||||||
mNbContactPoints++;
|
mNbContactPoints++;
|
||||||
|
assert(mNbContactPoints <= MAX_CONTACT_POINTS_IN_MANIFOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the obsolete contact points
|
// Clear the obsolete contact points
|
||||||
|
|
|
@ -143,6 +143,9 @@ class ContactManifold {
|
||||||
/// True if the contact manifold is obsolete
|
/// True if the contact manifold is obsolete
|
||||||
bool mIsObsolete;
|
bool mIsObsolete;
|
||||||
|
|
||||||
|
/// True if the contact manifold is new (has just been added from potential contacts)
|
||||||
|
bool mIsNew;
|
||||||
|
|
||||||
// -------------------- Methods -------------------- //
|
// -------------------- Methods -------------------- //
|
||||||
|
|
||||||
/// Return true if the contact manifold has already been added into an island
|
/// Return true if the contact manifold has already been added into an island
|
||||||
|
@ -204,6 +207,12 @@ class ContactManifold {
|
||||||
|
|
||||||
/// Return the friction twist accumulated impulse
|
/// Return the friction twist accumulated impulse
|
||||||
decimal getFrictionTwistImpulse() const;
|
decimal getFrictionTwistImpulse() const;
|
||||||
|
|
||||||
|
/// Return true if the manifold has just been created
|
||||||
|
bool getIsNew() const;
|
||||||
|
|
||||||
|
/// Set the isNew attribute
|
||||||
|
void setIsNew(bool isNew);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -408,6 +417,18 @@ inline short ContactManifold::getContactNormalId() const {
|
||||||
return mContactNormalId;
|
return mContactNormalId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return true if the manifold has just been created
|
||||||
|
inline bool ContactManifold::getIsNew() const {
|
||||||
|
return mIsNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the isNew attribute
|
||||||
|
inline void ContactManifold::setIsNew(bool isNew) {
|
||||||
|
mIsNew = isNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -66,8 +66,9 @@ void ContactManifoldSet::addContactManifold(const ContactManifoldInfo* contactMa
|
||||||
if (mNbManifolds >= mNbMaxManifolds) {
|
if (mNbManifolds >= mNbMaxManifolds) {
|
||||||
|
|
||||||
// We need to remove a manifold from the set.
|
// We need to remove a manifold from the set.
|
||||||
// We seach for the one with the smallest maximum penetration depth among its contact points
|
// We search for an old manifold with the smallest maximum penetration depth among its contact points.
|
||||||
ContactManifold* minDepthManifold = getManifoldWithSmallestContactPenetrationDepth(contactManifoldInfo->getLargestPenetrationDepth());
|
// If we do not find an old manifold, we select a new one that has the smallest contact penetration depth.
|
||||||
|
ContactManifold* minDepthManifold = selectManifoldToRemove(contactManifoldInfo->getLargestPenetrationDepth());
|
||||||
|
|
||||||
// If the manifold with the minimum penetration depth is an existing one
|
// If the manifold with the minimum penetration depth is an existing one
|
||||||
if (minDepthManifold != nullptr) {
|
if (minDepthManifold != nullptr) {
|
||||||
|
@ -135,25 +136,53 @@ void ContactManifoldSet::updateManifoldWithNewOne(ContactManifold* oldManifold,
|
||||||
oldManifold->setIsObsolete(false, false);
|
oldManifold->setIsObsolete(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the manifold with the smallest contact penetration depth among its points
|
// Return the manifold to remove (because it is too old or has not the largest penetration depth)
|
||||||
ContactManifold* ContactManifoldSet::getManifoldWithSmallestContactPenetrationDepth(decimal initDepth) const {
|
ContactManifold* ContactManifoldSet::selectManifoldToRemove(decimal penDepthNewManifold) const {
|
||||||
|
|
||||||
assert(mNbManifolds == mNbMaxManifolds);
|
assert(mNbManifolds == mNbMaxManifolds);
|
||||||
|
assert(mManifolds != nullptr);
|
||||||
|
|
||||||
ContactManifold* minDepthManifold = nullptr;
|
// Look for a manifold that is not new and with the smallest contact penetration depth.
|
||||||
decimal minDepth = initDepth;
|
// At the same time, we also look for a new manifold with the smallest contact penetration depth
|
||||||
|
// in case no old manifold exists.
|
||||||
|
ContactManifold* minDepthOldManifold = nullptr;
|
||||||
|
ContactManifold* minDepthNewManifold = nullptr;
|
||||||
|
decimal minDepthOld = DECIMAL_LARGEST;
|
||||||
|
decimal minDepthNew = penDepthNewManifold;
|
||||||
ContactManifold* manifold = mManifolds;
|
ContactManifold* manifold = mManifolds;
|
||||||
while (manifold != nullptr) {
|
while (manifold != nullptr) {
|
||||||
decimal depth = manifold->getLargestContactDepth();
|
|
||||||
if (depth < minDepth) {
|
// Get the largest contact point penetration depth of the manifold
|
||||||
minDepth = depth;
|
const decimal depth = manifold->getLargestContactDepth();
|
||||||
minDepthManifold = manifold;
|
|
||||||
|
// If it is a new manifold
|
||||||
|
if (manifold->getIsNew()) {
|
||||||
|
|
||||||
|
if (depth < minDepthNew) {
|
||||||
|
minDepthNew = depth;
|
||||||
|
minDepthNewManifold = manifold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (depth < minDepthOld) {
|
||||||
|
minDepthOld = depth;
|
||||||
|
minDepthOldManifold = manifold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manifold = manifold->getNext();
|
manifold = manifold->getNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
return minDepthManifold;
|
// If there was a contact manifold that was not new
|
||||||
|
if (minDepthOldManifold != nullptr) {
|
||||||
|
|
||||||
|
// Return the old manifold with the smallest penetration depth
|
||||||
|
return minDepthOldManifold;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we return the new manifold with the smallest penetration depth
|
||||||
|
return minDepthNewManifold;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the contact manifold with a similar average normal.
|
// Return the contact manifold with a similar average normal.
|
||||||
|
|
|
@ -74,8 +74,8 @@ class ContactManifoldSet {
|
||||||
// Return the contact manifold with a similar average normal.
|
// Return the contact manifold with a similar average normal.
|
||||||
ContactManifold* selectManifoldWithSimilarNormal(short int normalDirectionId) const;
|
ContactManifold* selectManifoldWithSimilarNormal(short int normalDirectionId) const;
|
||||||
|
|
||||||
/// Return the manifold with the smallest contact penetration depth
|
/// Return the manifold to remove (because it is too old or has not the largest penetration depth)
|
||||||
ContactManifold* getManifoldWithSmallestContactPenetrationDepth(decimal initDepth) const;
|
ContactManifold* selectManifoldToRemove(decimal penDepthNewManifold) const;
|
||||||
|
|
||||||
/// Update a previous similar manifold with a new one
|
/// Update a previous similar manifold with a new one
|
||||||
void updateManifoldWithNewOne(ContactManifold* oldManifold, const ContactManifoldInfo* newManifold);
|
void updateManifoldWithNewOne(ContactManifold* oldManifold, const ContactManifoldInfo* newManifold);
|
||||||
|
@ -124,6 +124,9 @@ class ContactManifoldSet {
|
||||||
/// Clear the obsolete contact manifolds and contact points
|
/// Clear the obsolete contact manifolds and contact points
|
||||||
void clearObsoleteManifoldsAndContactPoints();
|
void clearObsoleteManifoldsAndContactPoints();
|
||||||
|
|
||||||
|
/// Reset the isNew status of all the manifolds
|
||||||
|
void resetIsNewManifoldStatus();
|
||||||
|
|
||||||
// Map the normal vector into a cubemap face bucket (a face contains 4x4 buckets)
|
// Map the normal vector into a cubemap face bucket (a face contains 4x4 buckets)
|
||||||
// Each face of the cube is divided into 4x4 buckets. This method maps the
|
// Each face of the cube is divided into 4x4 buckets. This method maps the
|
||||||
// normal vector into of the of the bucket and returns a unique Id for the bucket
|
// normal vector into of the of the bucket and returns a unique Id for the bucket
|
||||||
|
@ -177,6 +180,17 @@ inline int ContactManifoldSet::computeNbMaxContactManifolds(const CollisionShape
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Reset the isNew status of all the manifolds
|
||||||
|
inline void ContactManifoldSet::resetIsNewManifoldStatus() {
|
||||||
|
|
||||||
|
ContactManifold* manifold = mManifolds;
|
||||||
|
while (manifold != nullptr) {
|
||||||
|
manifold->setIsNew(false);
|
||||||
|
manifold = manifold->getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,6 +172,9 @@ class OverlappingPair {
|
||||||
/// Clear the obsolete contact manifold and contact points
|
/// Clear the obsolete contact manifold and contact points
|
||||||
void clearObsoleteManifoldsAndContactPoints();
|
void clearObsoleteManifoldsAndContactPoints();
|
||||||
|
|
||||||
|
/// Reset the isNew status of all the manifolds
|
||||||
|
void resetIsNewManifoldStatus();
|
||||||
|
|
||||||
/// Return the pair of bodies index
|
/// Return the pair of bodies index
|
||||||
static overlappingpairid computeID(ProxyShape* shape1, ProxyShape* shape2);
|
static overlappingpairid computeID(ProxyShape* shape1, ProxyShape* shape2);
|
||||||
|
|
||||||
|
@ -269,6 +272,12 @@ inline void OverlappingPair::clearObsoleteManifoldsAndContactPoints() {
|
||||||
mContactManifoldSet.clearObsoleteManifoldsAndContactPoints();
|
mContactManifoldSet.clearObsoleteManifoldsAndContactPoints();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Reset the isNew status of all the manifolds
|
||||||
|
inline void OverlappingPair::resetIsNewManifoldStatus() {
|
||||||
|
mContactManifoldSet.resetIsNewManifoldStatus();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue
Block a user