fixed btSoftBodyConcaveCollisionAlgorithm, wrong bounding box transformation
added vertex welding option for btTriangleMesh (brute-force slow) reject appendFace for some degenerate triangles (all 3 vertices/nodes need to be different) add setVelocity method for btSoftBody
This commit is contained in:
@@ -19,7 +19,8 @@ subject to the following restrictions:
|
|||||||
|
|
||||||
btTriangleMesh::btTriangleMesh (bool use32bitIndices,bool use4componentVertices)
|
btTriangleMesh::btTriangleMesh (bool use32bitIndices,bool use4componentVertices)
|
||||||
:m_use32bitIndices(use32bitIndices),
|
:m_use32bitIndices(use32bitIndices),
|
||||||
m_use4componentVertices(use4componentVertices)
|
m_use4componentVertices(use4componentVertices),
|
||||||
|
m_weldingThreshold(0.0)
|
||||||
{
|
{
|
||||||
btIndexedMesh meshIndex;
|
btIndexedMesh meshIndex;
|
||||||
meshIndex.m_numTriangles = 0;
|
meshIndex.m_numTriangles = 0;
|
||||||
@@ -60,49 +61,66 @@ m_use4componentVertices(use4componentVertices)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void btTriangleMesh::addIndex(int index)
|
||||||
|
{
|
||||||
|
if (m_use32bitIndices)
|
||||||
|
{
|
||||||
|
m_32bitIndices.push_back(index);
|
||||||
|
m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_32bitIndices[0];
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
m_16bitIndices.push_back(index);
|
||||||
|
m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_16bitIndices[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int btTriangleMesh::findOrAddVertex(const btVector3& vertex)
|
||||||
|
{
|
||||||
|
//return index of new/existing vertex
|
||||||
|
//todo: could use acceleration structure for this
|
||||||
|
if (m_use4componentVertices)
|
||||||
|
{
|
||||||
|
for (int i=0;i< m_4componentVertices.size();i++)
|
||||||
|
{
|
||||||
|
if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_indexedMeshes[0].m_numVertices++;
|
||||||
|
m_4componentVertices.push_back(vertex);
|
||||||
|
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_4componentVertices[0];
|
||||||
|
|
||||||
|
return m_4componentVertices.size()-1;
|
||||||
|
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i=0;i< m_3componentVertices.size();i+=3)
|
||||||
|
{
|
||||||
|
btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
|
||||||
|
if ((vtx-vertex).length2() <= m_weldingThreshold)
|
||||||
|
{
|
||||||
|
return i/3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_3componentVertices.push_back(vertex.getX());
|
||||||
|
m_3componentVertices.push_back(vertex.getY());
|
||||||
|
m_3componentVertices.push_back(vertex.getZ());
|
||||||
|
m_indexedMeshes[0].m_numVertices++;
|
||||||
|
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
|
||||||
|
return (m_3componentVertices.size()/3)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2)
|
void btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2)
|
||||||
{
|
{
|
||||||
m_indexedMeshes[0].m_numTriangles++;
|
m_indexedMeshes[0].m_numTriangles++;
|
||||||
m_indexedMeshes[0].m_numVertices+=3;
|
|
||||||
|
addIndex(findOrAddVertex(vertex0));
|
||||||
if (m_use4componentVertices)
|
addIndex(findOrAddVertex(vertex1));
|
||||||
{
|
addIndex(findOrAddVertex(vertex2));
|
||||||
m_4componentVertices.push_back(vertex0);
|
|
||||||
m_4componentVertices.push_back(vertex1);
|
|
||||||
m_4componentVertices.push_back(vertex2);
|
|
||||||
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_4componentVertices[0];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
m_3componentVertices.push_back(vertex0.getX());
|
|
||||||
m_3componentVertices.push_back(vertex0.getY());
|
|
||||||
m_3componentVertices.push_back(vertex0.getZ());
|
|
||||||
|
|
||||||
m_3componentVertices.push_back(vertex1.getX());
|
|
||||||
m_3componentVertices.push_back(vertex1.getY());
|
|
||||||
m_3componentVertices.push_back(vertex1.getZ());
|
|
||||||
|
|
||||||
m_3componentVertices.push_back(vertex2.getX());
|
|
||||||
m_3componentVertices.push_back(vertex2.getY());
|
|
||||||
m_3componentVertices.push_back(vertex2.getZ());
|
|
||||||
m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_use32bitIndices)
|
|
||||||
{
|
|
||||||
int curIndex = m_32bitIndices.size();
|
|
||||||
m_32bitIndices.push_back(curIndex++);
|
|
||||||
m_32bitIndices.push_back(curIndex++);
|
|
||||||
m_32bitIndices.push_back(curIndex++);
|
|
||||||
m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_32bitIndices[0];
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
short curIndex = static_cast<short>(m_16bitIndices.size());
|
|
||||||
m_16bitIndices.push_back(curIndex++);
|
|
||||||
m_16bitIndices.push_back(curIndex++);
|
|
||||||
m_16bitIndices.push_back(curIndex++);
|
|
||||||
m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_16bitIndices[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int btTriangleMesh::getNumTriangles() const
|
int btTriangleMesh::getNumTriangles() const
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ subject to the following restrictions:
|
|||||||
///It allows either 32bit or 16bit indices, and 4 (x-y-z-w) or 3 (x-y-z) component vertices.
|
///It allows either 32bit or 16bit indices, and 4 (x-y-z-w) or 3 (x-y-z) component vertices.
|
||||||
///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface.
|
///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface.
|
||||||
///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same.
|
///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same.
|
||||||
|
///It has a brute-force option to weld together closeby vertices.
|
||||||
class btTriangleMesh : public btTriangleIndexVertexArray
|
class btTriangleMesh : public btTriangleIndexVertexArray
|
||||||
{
|
{
|
||||||
btAlignedObjectArray<btVector3> m_4componentVertices;
|
btAlignedObjectArray<btVector3> m_4componentVertices;
|
||||||
@@ -34,11 +35,16 @@ class btTriangleMesh : public btTriangleIndexVertexArray
|
|||||||
btAlignedObjectArray<unsigned short int> m_16bitIndices;
|
btAlignedObjectArray<unsigned short int> m_16bitIndices;
|
||||||
bool m_use32bitIndices;
|
bool m_use32bitIndices;
|
||||||
bool m_use4componentVertices;
|
bool m_use4componentVertices;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
btScalar m_weldingThreshold;
|
||||||
|
|
||||||
btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
|
btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
|
||||||
|
|
||||||
|
int findOrAddVertex(const btVector3& vertex);
|
||||||
|
void addIndex(int index);
|
||||||
|
|
||||||
bool getUse32bitIndices() const
|
bool getUse32bitIndices() const
|
||||||
{
|
{
|
||||||
return m_use32bitIndices;
|
return m_use32bitIndices;
|
||||||
|
|||||||
@@ -284,6 +284,13 @@ m_faces.push_back(f);
|
|||||||
//
|
//
|
||||||
void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
|
void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat)
|
||||||
{
|
{
|
||||||
|
if (node0==node1)
|
||||||
|
return;
|
||||||
|
if (node1==node2)
|
||||||
|
return;
|
||||||
|
if (node2==node0)
|
||||||
|
return;
|
||||||
|
|
||||||
appendFace(-1,mat);
|
appendFace(-1,mat);
|
||||||
Face& f=m_faces[m_faces.size()-1];
|
Face& f=m_faces[m_faces.size()-1];
|
||||||
btAssert(node0!=node1);
|
btAssert(node0!=node1);
|
||||||
@@ -384,6 +391,20 @@ void btSoftBody::addVelocity(const btVector3& velocity)
|
|||||||
for(int i=0,ni=m_nodes.size();i<ni;++i) addVelocity(velocity,i);
|
for(int i=0,ni=m_nodes.size();i<ni;++i) addVelocity(velocity,i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set velocity for the entire body */
|
||||||
|
void btSoftBody::setVelocity( const btVector3& velocity)
|
||||||
|
{
|
||||||
|
for(int i=0,ni=m_nodes.size();i<ni;++i)
|
||||||
|
{
|
||||||
|
Node& n=m_nodes[i];
|
||||||
|
if(n.m_im>0)
|
||||||
|
{
|
||||||
|
n.m_v = velocity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
void btSoftBody::addVelocity(const btVector3& velocity,int node)
|
void btSoftBody::addVelocity(const btVector3& velocity,int node)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -677,6 +677,10 @@ public:
|
|||||||
int node);
|
int node);
|
||||||
/* Add velocity to the entire body */
|
/* Add velocity to the entire body */
|
||||||
void addVelocity( const btVector3& velocity);
|
void addVelocity( const btVector3& velocity);
|
||||||
|
|
||||||
|
/* Set velocity for the entire body */
|
||||||
|
void setVelocity( const btVector3& velocity);
|
||||||
|
|
||||||
/* Add velocity to a node of the body */
|
/* Add velocity to a node of the body */
|
||||||
void addVelocity( const btVector3& velocity,
|
void addVelocity( const btVector3& velocity,
|
||||||
int node);
|
int node);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ subject to the following restrictions:
|
|||||||
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
|
||||||
#include "BulletSoftBody/btSoftBody.h"
|
#include "BulletSoftBody/btSoftBody.h"
|
||||||
|
|
||||||
#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.3)
|
#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable
|
||||||
|
|
||||||
btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
|
btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
|
||||||
: btCollisionAlgorithm(ci),
|
: btCollisionAlgorithm(ci),
|
||||||
@@ -210,44 +210,22 @@ btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
|||||||
void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
|
||||||
{
|
{
|
||||||
m_dispatchInfoPtr = &dispatchInfo;
|
m_dispatchInfoPtr = &dispatchInfo;
|
||||||
m_collisionMarginTriangle = collisionMarginTriangle;
|
m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
|
||||||
m_resultOut = resultOut;
|
m_resultOut = resultOut;
|
||||||
|
|
||||||
//recalc aabbs
|
|
||||||
// btTransform softbodyInTriangleSpace;
|
|
||||||
// softbodyInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_softBody->getWorldTransform();
|
|
||||||
// btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
|
|
||||||
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
|
|
||||||
btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax;
|
btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax;
|
||||||
m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax);
|
m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax);
|
||||||
|
|
||||||
btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5);
|
btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5);
|
||||||
btVector3 softBodyCenter = (aabbWorldSpaceMax+aabbWorldSpaceMin)*btScalar(0.5);
|
btVector3 softBodyCenter = (aabbWorldSpaceMax+aabbWorldSpaceMin)*btScalar(0.5);
|
||||||
|
|
||||||
btTransform triInverse = m_triBody->getWorldTransform().inverse();
|
btTransform softTransform;
|
||||||
|
softTransform.setIdentity();
|
||||||
btMatrix3x3 abs_b = triInverse.getBasis().absolute();
|
softTransform.setOrigin(softBodyCenter);
|
||||||
btPoint3 center = softBodyCenter + triInverse.getOrigin();
|
|
||||||
|
|
||||||
btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
|
|
||||||
abs_b[1].dot(halfExtents),
|
|
||||||
abs_b[2].dot(halfExtents));
|
|
||||||
// extent += btVector3(getMargin(),getMargin(),getMargin());
|
|
||||||
|
|
||||||
m_aabbMin = center - extent;
|
|
||||||
m_aabbMax = center + extent;
|
|
||||||
|
|
||||||
btScalar extraMargin = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
|
|
||||||
btVector3 extra(extraMargin,extraMargin,extraMargin);
|
|
||||||
|
|
||||||
m_aabbMax += extra;
|
|
||||||
m_aabbMin -= extra;
|
|
||||||
|
|
||||||
/* btVector3 extra(2,2,2);
|
|
||||||
m_aabbMin = aabbWorldSpaceMin-extra;
|
|
||||||
m_aabbMax = aabbWorldSpaceMax+extra;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
btTransform convexInTriangleSpace;
|
||||||
|
convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * softTransform;
|
||||||
|
btTransformAabb(halfExtents,m_collisionMarginTriangle,convexInTriangleSpace,m_aabbMin,m_aabbMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
void btSoftBodyConcaveCollisionAlgorithm::clearCache()
|
void btSoftBodyConcaveCollisionAlgorithm::clearCache()
|
||||||
|
|||||||
Reference in New Issue
Block a user