add support for clipFaceAgainstHull, so we can clip convex polyhedra against triangles (without connectivity information)

in addition to the existing clipHullAgainstHull
Fix for debug drawing of contact points
comment-out some debug drawing code for triangle meshes
This commit is contained in:
erwin.coumans
2011-03-29 21:58:15 +00:00
parent 8847b21eb7
commit 2a856f8c32
5 changed files with 104 additions and 76 deletions

View File

@@ -114,20 +114,19 @@ void GLDebugDrawer::drawContactPoint(const btVector3& pointOnB,const btVector3&
{
{
btVector3 to=pointOnB+normalOnB*distance;
btVector3 to=pointOnB+normalOnB*1;//distance;
const btVector3&from = pointOnB;
glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
//glColor4f(0,0,0,1.f);
glBegin(GL_LINES);
glVertex3d(from.getX(), from.getY(), from.getZ());
glVertex3d(to.getX(), to.getY(), to.getZ());
glEnd();
glRasterPos3f(from.x(), from.y(), from.z());
char buf[12];
sprintf(buf," %d",lifeTime);
// glRasterPos3f(from.x(), from.y(), from.z());
// char buf[12];
// sprintf(buf," %d",lifeTime);
//BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);

View File

@@ -91,7 +91,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
#if 0
///debug drawing of the overlapping triangles
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
{
@@ -100,17 +100,8 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
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[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);
}
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
#endif
if (m_convexBody->getCollisionShape()->isConvex())
{

View File

@@ -26,6 +26,8 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
@@ -395,18 +397,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
{
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar maxDist = 0.f;
if (dispatchInfo.m_convexMaxDistanceUseCPT)
{
maxDist = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold();
} else
{
maxDist = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
}
maxDist =0.f;
btVector3 sepNormalWorldSpace;
//#define USE_SAT_TEST
#ifdef USE_SAT_TEST
@@ -421,9 +413,11 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
#endif //USE_SAT_TEST
if (foundSepAxis)
{
btPolyhedralContactClipping::clipFaceContacts(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
btScalar minDist = gjkPairDetector.getCachedSeparatingDistance();
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
body0->getWorldTransform(),
body1->getWorldTransform(), maxDist, *resultOut);
body1->getWorldTransform(), minDist-threshold, threshold, *resultOut);
if (m_ownManifold)
{
@@ -433,6 +427,31 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
} else
{
//we can also deal with convex versus triangle (without connectivity data)
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE)
{
btVector3 sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
btVertexArray vertices;
btTriangleShape* tri = (btTriangleShape*)polyhedronB;
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[0]);
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[1]);
vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[2]);
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar minDist = gjkPairDetector.getCachedSeparatingDistance();
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
body0->getWorldTransform(), vertices, minDist-threshold, threshold, *resultOut);
if (m_ownManifold)
{
resultOut->refreshContactPoints();
}
return;
}
}
}

View File

@@ -208,29 +208,17 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
}
}
}
void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btScalar curMaxDist=maxDist;
int closestFaceA=-1, closestFaceB=-1;
{
btScalar dmax = -FLT_MAX;
for(int face=0;face<hullB.m_faces.size();face++)
{
const btVector3 Normal(hullB.m_faces[face].m_plane[0], hullB.m_faces[face].m_plane[1], hullB.m_faces[face].m_plane[2]);
const btVector3 WorldNormal = transB.getBasis() * Normal;
btScalar d = WorldNormal.dot(separatingNormal);
if (d > dmax)
{
dmax = d;
closestFaceB = face;
}
}
return true;
}
void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btVertexArray worldVertsB2;
btVertexArray* pVtxIn = &worldVertsB1;
btVertexArray* pVtxOut = &worldVertsB2;
pVtxOut->reserve(pVtxIn->size());
int closestFaceA=-1;
{
btScalar dmin = FLT_MAX;
for(int face=0;face<hullA.m_faces.size();face++)
@@ -246,29 +234,10 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
}
}
}
if (closestFaceA<0 || closestFaceB<0)
{
if (closestFaceA<0)
return;
}
// setup initial clip face (minimizing face from hull B)
btVertexArray worldVertsB1;
btVertexArray worldVertsB2;
btVertexArray* pVtxIn = &worldVertsB1;
btVertexArray* pVtxOut = &worldVertsB2;
const btFace& polyA = hullA.m_faces[closestFaceA];
{
const btFace& polyB = hullB.m_faces[closestFaceB];
const int numVertices = polyB.m_indices.size();
for(int e0=0;e0<numVertices;e0++)
{
const btVector3& b = hullB.m_vertices[polyB.m_indices[e0]];
pVtxIn->push_back(transB*b);
}
}
pVtxOut->reserve(pVtxIn->size());
// clip polygon to back of planes of all faces of hull A that are adjacent to witness face
int numContacts = pVtxIn->size();
@@ -309,7 +278,7 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
{
btScalar depth = planeNormalWS.dot(pVtxIn->at(i))+planeEqWS;
if (depth <=0)
if (depth <=maxDist && depth >=minDist)
{
btVector3 point = pVtxIn->at(i);
#ifdef ONLY_REPORT_DEEPEST_POINT
@@ -335,3 +304,50 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
#endif //ONLY_REPORT_DEEPEST_POINT
}
void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btScalar curMaxDist=maxDist;
int closestFaceB=-1;
{
btScalar dmax = -FLT_MAX;
for(int face=0;face<hullB.m_faces.size();face++)
{
const btVector3 Normal(hullB.m_faces[face].m_plane[0], hullB.m_faces[face].m_plane[1], hullB.m_faces[face].m_plane[2]);
const btVector3 WorldNormal = transB.getBasis() * Normal;
btScalar d = WorldNormal.dot(separatingNormal);
if (d > dmax)
{
dmax = d;
closestFaceB = face;
}
}
}
if (closestFaceB<0)
{
return;
}
// setup initial clip face (minimizing face from hull B)
btVertexArray worldVertsB1;
{
const btFace& polyB = hullB.m_faces[closestFaceB];
const int numVertices = polyB.m_indices.size();
for(int e0=0;e0<numVertices;e0++)
{
const btVector3& b = hullB.m_vertices[polyB.m_indices[e0]];
worldVertsB1.push_back(transB*b);
}
}
clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, minDist, maxDist,resultOut);
}

View File

@@ -32,11 +32,14 @@ typedef btAlignedObjectArray<btVector3> btVertexArray;
// Clips a face to the back of a plane
struct btPolyhedralContactClipping
{
static void clipFaceContacts(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS);
static void clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut);
static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep);
///the clipFace method is used internally
static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS);
};
#endif // __POLYHEDRAL_CONTACT_CLIPPING_H