fixed some outstanding issues with Bullet soft bodies:
1) re-allocate a pool allocator, if one of the soft body collision algorithms is larger than max pool element size 2) manage child shapes properly, and call RemoveReferences on the m_sparsesdf
This commit is contained in:
@@ -48,6 +48,8 @@ struct btDefaultCollisionConstructionInfo
|
|||||||
class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
||||||
{
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
int m_persistentManifoldPoolSize;
|
int m_persistentManifoldPoolSize;
|
||||||
|
|
||||||
btStackAlloc* m_stackAlloc;
|
btStackAlloc* m_stackAlloc;
|
||||||
@@ -56,6 +58,7 @@ class btDefaultCollisionConfiguration : public btCollisionConfiguration
|
|||||||
btPoolAllocator* m_persistentManifoldPool;
|
btPoolAllocator* m_persistentManifoldPool;
|
||||||
bool m_ownsPersistentManifoldPool;
|
bool m_ownsPersistentManifoldPool;
|
||||||
|
|
||||||
|
|
||||||
btPoolAllocator* m_collisionAlgorithmPool;
|
btPoolAllocator* m_collisionAlgorithmPool;
|
||||||
bool m_ownsCollisionAlgorithmPool;
|
bool m_ownsCollisionAlgorithmPool;
|
||||||
|
|
||||||
|
|||||||
@@ -609,6 +609,11 @@ public:
|
|||||||
|
|
||||||
btAlignedObjectArray<int> m_userIndexMapping;
|
btAlignedObjectArray<int> m_userIndexMapping;
|
||||||
|
|
||||||
|
btSoftBodyWorldInfo* getWorldInfo()
|
||||||
|
{
|
||||||
|
return m_worldInfo;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void setCollisionShape(btCollisionShape* collisionShape)
|
virtual void setCollisionShape(btCollisionShape* collisionShape)
|
||||||
{
|
{
|
||||||
//don't do anything, due to the internal shape hack: todo: fix this
|
//don't do anything, due to the internal shape hack: todo: fix this
|
||||||
|
|||||||
@@ -74,35 +74,23 @@ btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback()
|
|||||||
|
|
||||||
void btSoftBodyTriangleCallback::clearCache()
|
void btSoftBodyTriangleCallback::clearCache()
|
||||||
{
|
{
|
||||||
//m_dispatcher->clearManifold(m_manifoldPtr);
|
for (int i=0;i<m_shapeCache.size();i++)
|
||||||
|
{
|
||||||
|
btTriIndex* tmp = m_shapeCache.getAtIndex(i);
|
||||||
|
btAssert(tmp);
|
||||||
|
btAssert(tmp->m_childShape);
|
||||||
|
m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape);//necessary?
|
||||||
|
delete tmp->m_childShape;
|
||||||
|
}
|
||||||
|
m_shapeCache.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const int maxParts = 1;
|
|
||||||
static const int maxTriangleIndex = 100*100;
|
|
||||||
|
|
||||||
btCollisionShape* shapeCache[maxParts][maxTriangleIndex];
|
|
||||||
|
|
||||||
|
|
||||||
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
|
||||||
{
|
{
|
||||||
static bool hackedFirst = true;
|
//just for debugging purposes
|
||||||
if (hackedFirst)
|
|
||||||
{
|
|
||||||
hackedFirst = false;
|
|
||||||
int i,j;
|
|
||||||
for (i=0;i<maxParts;i++)
|
|
||||||
{
|
|
||||||
for (j=0;j<maxTriangleIndex;j++)
|
|
||||||
{
|
|
||||||
shapeCache[i][j]=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//just for debugging purposes
|
|
||||||
//printf("triangle %d",m_triangleCount++);
|
//printf("triangle %d",m_triangleCount++);
|
||||||
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
||||||
btCollisionAlgorithmConstructionInfo ci;
|
btCollisionAlgorithmConstructionInfo ci;
|
||||||
ci.m_dispatcher1 = m_dispatcher;
|
ci.m_dispatcher1 = m_dispatcher;
|
||||||
|
|
||||||
@@ -114,18 +102,17 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
|||||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
|
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
|
||||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
|
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
|
||||||
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
|
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
|
||||||
|
|
||||||
//btVector3 center = triangle[0] + triangle[1]+triangle[2];
|
|
||||||
//center *= btScalar(0.333333);
|
|
||||||
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
|
|
||||||
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
|
|
||||||
//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shapeCache[partId][triangleIndex])
|
btTriIndex triIndex(partId,triangleIndex,0);
|
||||||
|
btHashKey<btTriIndex> triKey(triIndex.getUid());
|
||||||
|
|
||||||
|
|
||||||
|
btTriIndex* shapeIndex = m_shapeCache[triKey];
|
||||||
|
if (shapeIndex)
|
||||||
{
|
{
|
||||||
btCollisionShape* tm = shapeCache[partId][triangleIndex];
|
btCollisionShape* tm = shapeIndex->m_childShape;
|
||||||
|
btAssert(tm);
|
||||||
|
|
||||||
//copy over user pointers to temporary shape
|
//copy over user pointers to temporary shape
|
||||||
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
|
tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
|
||||||
@@ -145,13 +132,6 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
|||||||
|
|
||||||
//aabb filter is already applied!
|
//aabb filter is already applied!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
|
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
|
||||||
|
|
||||||
// if (m_softBody->getCollisionShape()->getShapeType()==
|
// if (m_softBody->getCollisionShape()->getShapeType()==
|
||||||
@@ -194,10 +174,11 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
|||||||
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
|
||||||
colAlgo->~btCollisionAlgorithm();
|
colAlgo->~btCollisionAlgorithm();
|
||||||
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
|
||||||
ob->internalSetTemporaryCollisionShape( tmpShape );
|
|
||||||
// delete tm;
|
|
||||||
|
|
||||||
shapeCache[partId][triangleIndex] = tm;
|
|
||||||
|
ob->internalSetTemporaryCollisionShape( tmpShape );
|
||||||
|
triIndex.m_childShape = tm;
|
||||||
|
m_shapeCache.insert(triKey,triIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,39 @@ class btDispatcher;
|
|||||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||||
class btSoftBody;
|
class btSoftBody;
|
||||||
|
class btCollisionShape;
|
||||||
|
|
||||||
|
#include "LinearMath/btHashMap.h"
|
||||||
|
|
||||||
|
#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS
|
||||||
|
|
||||||
|
struct btTriIndex
|
||||||
|
{
|
||||||
|
int m_PartIdTriangleIndex;
|
||||||
|
class btCollisionShape* m_childShape;
|
||||||
|
|
||||||
|
btTriIndex(int partId,int triangleIndex,btCollisionShape* shape)
|
||||||
|
{
|
||||||
|
m_PartIdTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
|
||||||
|
m_childShape = shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getTriangleIndex() const
|
||||||
|
{
|
||||||
|
// Get only the lower bits where the triangle index is stored
|
||||||
|
return (m_PartIdTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
|
||||||
|
}
|
||||||
|
int getPartId() const
|
||||||
|
{
|
||||||
|
// Get only the highest bits where the part index is stored
|
||||||
|
return (m_PartIdTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
|
||||||
|
}
|
||||||
|
int getUid() const
|
||||||
|
{
|
||||||
|
return m_PartIdTriangleIndex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
///For each triangle in the concave mesh that overlaps with the AABB of a soft body (m_softBody), processTriangle is called.
|
///For each triangle in the concave mesh that overlaps with the AABB of a soft body (m_softBody), processTriangle is called.
|
||||||
class btSoftBodyTriangleCallback : public btTriangleCallback
|
class btSoftBodyTriangleCallback : public btTriangleCallback
|
||||||
@@ -41,6 +74,8 @@ class btSoftBodyTriangleCallback : public btTriangleCallback
|
|||||||
const btDispatcherInfo* m_dispatchInfoPtr;
|
const btDispatcherInfo* m_dispatchInfoPtr;
|
||||||
btScalar m_collisionMarginTriangle;
|
btScalar m_collisionMarginTriangle;
|
||||||
|
|
||||||
|
btHashMap<btHashKey<btTriIndex>,btTriIndex> m_shapeCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int m_triangleCount;
|
int m_triangleCount;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ subject to the following restrictions:
|
|||||||
#include "btSoftBodyConcaveCollisionAlgorithm.h"
|
#include "btSoftBodyConcaveCollisionAlgorithm.h"
|
||||||
#include "btSoftSoftCollisionAlgorithm.h"
|
#include "btSoftSoftCollisionAlgorithm.h"
|
||||||
|
|
||||||
|
#include "LinearMath/btPoolAllocator.h"
|
||||||
|
|
||||||
#define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1
|
#define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1
|
||||||
|
|
||||||
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
|
||||||
@@ -44,6 +46,31 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura
|
|||||||
m_swappedSoftRigidConcaveCreateFunc->m_swapped=true;
|
m_swappedSoftRigidConcaveCreateFunc->m_swapped=true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//replace pool by a new one, with potential larger size
|
||||||
|
|
||||||
|
if (m_ownsCollisionAlgorithmPool && m_collisionAlgorithmPool)
|
||||||
|
{
|
||||||
|
int curElemSize = m_collisionAlgorithmPool->getElementSize();
|
||||||
|
///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
|
||||||
|
|
||||||
|
|
||||||
|
int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm);
|
||||||
|
int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm);
|
||||||
|
int maxSize2 = sizeof(btSoftBodyConcaveCollisionAlgorithm);
|
||||||
|
|
||||||
|
int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1);
|
||||||
|
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
|
||||||
|
if (collisionAlgorithmMaxElementSize > curElemSize)
|
||||||
|
{
|
||||||
|
btAlignedFree(m_collisionAlgorithmPool);
|
||||||
|
void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
|
||||||
|
m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
|
btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration()
|
||||||
|
|||||||
@@ -91,6 +91,11 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getElementSize() const
|
||||||
|
{
|
||||||
|
return m_elemSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user