Replies: 4 comments
-
...bullet api does not contains this function, what is that? btCollisionAlgorithm::processCollision() needs manifold result.. I don't really understand what about is that issue. |
Beta Was this translation helpful? Give feedback.
-
Oh, this is an improve suggestion. Processing manifold result is too heavy weight for some kind collision object just like sensor object who just want to know the overlapping objects. So I wonder if we could separate the manifold result processing from collision processing. |
Beta Was this translation helpful? Give feedback.
-
I'll consider it for a release after Bullet 2.83, so let's keep this issue open. THanks for the request! |
Beta Was this translation helpful? Give feedback.
-
In my modified version, I add an array in .../CollisionDispatch/btManifoldResult.cpp | 168 +++++++++++----------
.../CollisionDispatch/btManifoldResult.h | 82 +++++++---
2 files changed, 145 insertions(+), 105 deletions(-)
diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
index 4b2986a..1b2339c 100644
--- a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
+++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
@@ -59,96 +59,98 @@ btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject*
}
-
-btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
- :m_manifoldPtr(0),
- m_body0Wrap(body0Wrap),
- m_body1Wrap(body1Wrap)
-#ifdef DEBUG_PART_INDEX
- ,m_partId0(-1),
- m_partId1(-1),
- m_index0(-1),
- m_index1(-1)
-#endif //DEBUG_PART_INDEX
-{
-}
-
-
-void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+void btManifoldResult::processContactPoints(btPersistentManifold* manifoldPtr)
{
- btAssert(m_manifoldPtr);
+ btAssert(manifoldPtr);
//order in manifold needs to match
- if (depth > m_manifoldPtr->getContactBreakingThreshold())
-// if (depth > m_manifoldPtr->getContactProcessingThreshold())
- return;
-
- bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
-
- btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
-
- btVector3 localA;
- btVector3 localB;
-
- if (isSwapped)
+ int i;
+ for (i = 0; i < m_numContactPoints; ++i)
{
- localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
- localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
- } else
- {
- localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
- localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
+ const btContactPoint& contactPoint = m_contactPointArray[i];
+ const btVector3& normalOnBInWorld = contactPoint.m_normalOnBInWorld;
+ const btVector3& pointInWorld = contactPoint.m_pointInWorld;
+ const btScalar depth = contactPoint.m_depth;
+
+ // if (depth > m_manifoldPtr->getContactProcessingThreshold())
+ if (depth > manifoldPtr->getContactBreakingThreshold())
+ continue;
+
+ bool isSwapped = manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
+
+ btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
+
+ btVector3 localA;
+ btVector3 localB;
+
+ if (isSwapped)
+ {
+ localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
+ localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
+ }
+ else
+ {
+ localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA);
+ localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
+ }
+
+ btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth);
+ newPt.m_positionWorldOnA = pointA;
+ newPt.m_positionWorldOnB = pointInWorld;
+
+ int insertIndex = manifoldPtr->getCacheEntry(newPt);
+
+ newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject());
+ newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject());
+ newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject());
+ btPlaneSpace1(newPt.m_normalWorldOnB, newPt.m_lateralFrictionDir1, newPt.m_lateralFrictionDir2);
+
+
+
+ //BP mod, store contact triangles.
+ if (isSwapped)
+ {
+ newPt.m_partId0 = m_partId1;
+ newPt.m_partId1 = m_partId0;
+ newPt.m_index0 = m_index1;
+ newPt.m_index1 = m_index0;
+ }
+ else
+ {
+ newPt.m_partId0 = m_partId0;
+ newPt.m_partId1 = m_partId1;
+ newPt.m_index0 = m_index0;
+ newPt.m_index1 = m_index1;
+ }
+ //printf("depth=%f\n",depth);
+ ///@todo, check this for any side effects
+ if (insertIndex >= 0)
+ {
+ //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
+ manifoldPtr->replaceContactPoint(newPt, insertIndex);
+ }
+ else
+ {
+ insertIndex = manifoldPtr->addManifoldPoint(newPt);
+ }
+
+ //User can override friction and/or restitution
+ if (gContactAddedCallback &&
+ //and if either of the two bodies requires custom material
+ ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
+ (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
+ {
+ //experimental feature info, for per-triangle material etc.
+ const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap;
+ const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap;
+ (*gContactAddedCallback)(manifoldPtr->getContactPoint(insertIndex), obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1);
+ }
}
- btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
- newPt.m_positionWorldOnA = pointA;
- newPt.m_positionWorldOnB = pointInWorld;
-
- int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
-
- newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
- newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
- newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
- btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2);
-
-
-
- //BP mod, store contact triangles.
- if (isSwapped)
- {
- newPt.m_partId0 = m_partId1;
- newPt.m_partId1 = m_partId0;
- newPt.m_index0 = m_index1;
- newPt.m_index1 = m_index0;
- } else
- {
- newPt.m_partId0 = m_partId0;
- newPt.m_partId1 = m_partId1;
- newPt.m_index0 = m_index0;
- newPt.m_index1 = m_index1;
- }
- //printf("depth=%f\n",depth);
- ///@todo, check this for any side effects
- if (insertIndex >= 0)
+ if (m_numContactPoints > 0)
{
- //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
- m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
- } else
- {
- insertIndex = m_manifoldPtr->addManifoldPoint(newPt);
- }
-
- //User can override friction and/or restitution
- if (gContactAddedCallback &&
- //and if either of the two bodies requires custom material
- ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
- (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
- {
- //experimental feature info, for per-triangle material etc.
- const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
- const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
- (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
+ ++m_numActiveManifolds;
+ m_numContactPoints = 0;
}
-
}
diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/src/BulletCollision/CollisionDispatch/btManifoldResult.h
index 977b9a0..4b2d78d 100644
--- a/src/BulletCollision/CollisionDispatch/btManifoldResult.h
+++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.h
@@ -40,7 +40,22 @@ class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
{
protected:
- btPersistentManifold* m_manifoldPtr;
+ struct btContactPoint
+ {
+ btVector3 m_normalOnBInWorld;
+ btVector3 m_pointInWorld;
+ btScalar m_depth;
+
+ /**@brief No initialization constructor */
+ SIMD_FORCE_INLINE btContactPoint()
+ {
+ }
+ };
+
+ int m_numContactPoints;
+ btAlignedObjectArray<btContactPoint> m_contactPointArray;
+
+ int m_numActiveManifolds;
const btCollisionObjectWrapper* m_body0Wrap;
const btCollisionObjectWrapper* m_body1Wrap;
@@ -53,32 +68,43 @@ protected:
public:
btManifoldResult()
+ : m_numContactPoints(0)
+ , m_contactPointArray()
+ , m_numActiveManifolds(0)
#ifdef DEBUG_PART_INDEX
- :
- m_partId0(-1),
- m_partId1(-1),
- m_index0(-1),
- m_index1(-1)
+ , m_partId0(-1)
+ , m_partId1(-1)
+ , m_index0(-1)
+ , m_index1(-1)
#endif //DEBUG_PART_INDEX
{
}
- btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
+ btManifoldResult(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap)
+ : m_numContactPoints(0)
+ , m_contactPointArray()
+ , m_numActiveManifolds(0)
+ , m_body0Wrap(body0Wrap)
+ , m_body1Wrap(body1Wrap)
+#ifdef DEBUG_PART_INDEX
+ , m_partId0(-1)
+ , m_partId1(-1)
+ , m_index0(-1)
+ , m_index1(-1)
+#endif //DEBUG_PART_INDEX
+ {
+ }
virtual ~btManifoldResult() {};
- void setPersistentManifold(btPersistentManifold* manifoldPtr)
+ int getNumContactPoints()
{
- m_manifoldPtr = manifoldPtr;
+ return m_numContactPoints;
}
- const btPersistentManifold* getPersistentManifold() const
- {
- return m_manifoldPtr;
- }
- btPersistentManifold* getPersistentManifold()
+ int getNumActiveManifolds()
{
- return m_manifoldPtr;
+ return m_numActiveManifolds;
}
virtual void setShapeIdentifiersA(int partId0,int index0)
@@ -93,23 +119,35 @@ public:
m_index1=index1;
}
+ virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth)
+ {
+ if (m_numContactPoints >= m_contactPointArray.size())
+ {
+ m_contactPointArray.resizeNoInitialize(m_numContactPoints + 8);
+ }
+ btContactPoint& contactPoint = m_contactPointArray[m_numContactPoints];
+ contactPoint.m_normalOnBInWorld = normalOnBInWorld;
+ contactPoint.m_pointInWorld = pointInWorld;
+ contactPoint.m_depth = depth;
+ ++m_numContactPoints;
+ }
- virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
+ virtual void processContactPoints(btPersistentManifold* manifoldPtr);
- SIMD_FORCE_INLINE void refreshContactPoints()
+ SIMD_FORCE_INLINE void refreshContactPoints(btPersistentManifold* manifoldPtr)
{
- btAssert(m_manifoldPtr);
- if (!m_manifoldPtr->getNumContacts())
+ btAssert(manifoldPtr);
+ if (!manifoldPtr->getNumContacts())
return;
- bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
+ bool isSwapped = manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
if (isSwapped)
{
- m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(),m_body0Wrap->getCollisionObject()->getWorldTransform());
+ manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(), m_body0Wrap->getCollisionObject()->getWorldTransform());
} else
{
- m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(),m_body1Wrap->getCollisionObject()->getWorldTransform());
+ manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(), m_body1Wrap->getCollisionObject()->getWorldTransform());
}
}
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
In some usage scenario, user doesn't need to know the exact contact point of the collision. Thus, it's happy if the user could got 50% performance improved through just rewrite the default near callback.
A benchmark profile of bullet2:

Beta Was this translation helpful? Give feedback.
All reactions