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:
@@ -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;
|
const btVector3&from = pointOnB;
|
||||||
glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
|
glColor4f(color.getX(), color.getY(), color.getZ(),1.f);
|
||||||
//glColor4f(0,0,0,1.f);
|
//glColor4f(0,0,0,1.f);
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glVertex3d(from.getX(), from.getY(), from.getZ());
|
glVertex3d(from.getX(), from.getY(), from.getZ());
|
||||||
glVertex3d(to.getX(), to.getY(), to.getZ());
|
glVertex3d(to.getX(), to.getY(), to.getZ());
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
|
||||||
glRasterPos3f(from.x(), from.y(), from.z());
|
// glRasterPos3f(from.x(), from.y(), from.z());
|
||||||
char buf[12];
|
// char buf[12];
|
||||||
sprintf(buf," %d",lifeTime);
|
// sprintf(buf," %d",lifeTime);
|
||||||
//BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
//BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),buf);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
|
|||||||
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
///debug drawing of the overlapping triangles
|
///debug drawing of the overlapping triangles
|
||||||
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
|
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[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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
|
|
||||||
|
|
||||||
if (m_convexBody->getCollisionShape()->isConvex())
|
if (m_convexBody->getCollisionShape()->isConvex())
|
||||||
{
|
{
|
||||||
@@ -119,7 +110,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
|
|||||||
|
|
||||||
btCollisionShape* tmpShape = ob->getCollisionShape();
|
btCollisionShape* tmpShape = ob->getCollisionShape();
|
||||||
ob->internalSetTemporaryCollisionShape( &tm );
|
ob->internalSetTemporaryCollisionShape( &tm );
|
||||||
|
|
||||||
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
|
btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
|
||||||
|
|
||||||
if (m_resultOut->getBody0Internal() == m_triBody)
|
if (m_resultOut->getBody0Internal() == m_triBody)
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ subject to the following restrictions:
|
|||||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||||
|
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
|
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
|
||||||
@@ -395,18 +397,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
|
|||||||
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
|
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
|
||||||
if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron())
|
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;
|
btVector3 sepNormalWorldSpace;
|
||||||
//#define USE_SAT_TEST
|
//#define USE_SAT_TEST
|
||||||
#ifdef USE_SAT_TEST
|
#ifdef USE_SAT_TEST
|
||||||
@@ -421,10 +413,12 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
|
|||||||
#endif //USE_SAT_TEST
|
#endif //USE_SAT_TEST
|
||||||
if (foundSepAxis)
|
if (foundSepAxis)
|
||||||
{
|
{
|
||||||
btPolyhedralContactClipping::clipFaceContacts(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
|
btScalar minDist = gjkPairDetector.getCachedSeparatingDistance();
|
||||||
body0->getWorldTransform(),
|
|
||||||
body1->getWorldTransform(), maxDist, *resultOut);
|
|
||||||
|
|
||||||
|
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
|
||||||
|
body0->getWorldTransform(),
|
||||||
|
body1->getWorldTransform(), minDist-threshold, threshold, *resultOut);
|
||||||
|
|
||||||
if (m_ownManifold)
|
if (m_ownManifold)
|
||||||
{
|
{
|
||||||
resultOut->refreshContactPoints();
|
resultOut->refreshContactPoints();
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,29 +208,17 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut)
|
|
||||||
|
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());
|
||||||
|
|
||||||
btScalar curMaxDist=maxDist;
|
int closestFaceA=-1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
btScalar dmin = FLT_MAX;
|
btScalar dmin = FLT_MAX;
|
||||||
for(int face=0;face<hullA.m_faces.size();face++)
|
for(int face=0;face<hullA.m_faces.size();face++)
|
||||||
@@ -246,31 +234,12 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (closestFaceA<0 || closestFaceB<0)
|
if (closestFaceA<0)
|
||||||
{
|
|
||||||
return;
|
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& 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
|
// clip polygon to back of planes of all faces of hull A that are adjacent to witness face
|
||||||
int numContacts = pVtxIn->size();
|
int numContacts = pVtxIn->size();
|
||||||
int numVerticesA = polyA.m_indices.size();
|
int numVerticesA = polyA.m_indices.size();
|
||||||
for(int e0=0;e0<numVerticesA;e0++)
|
for(int e0=0;e0<numVerticesA;e0++)
|
||||||
@@ -309,7 +278,7 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
|
|||||||
{
|
{
|
||||||
|
|
||||||
btScalar depth = planeNormalWS.dot(pVtxIn->at(i))+planeEqWS;
|
btScalar depth = planeNormalWS.dot(pVtxIn->at(i))+planeEqWS;
|
||||||
if (depth <=0)
|
if (depth <=maxDist && depth >=minDist)
|
||||||
{
|
{
|
||||||
btVector3 point = pVtxIn->at(i);
|
btVector3 point = pVtxIn->at(i);
|
||||||
#ifdef ONLY_REPORT_DEEPEST_POINT
|
#ifdef ONLY_REPORT_DEEPEST_POINT
|
||||||
@@ -334,4 +303,51 @@ void btPolyhedralContactClipping::clipFaceContacts(const btVector3& separatingNo
|
|||||||
}
|
}
|
||||||
#endif //ONLY_REPORT_DEEPEST_POINT
|
#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);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -32,11 +32,14 @@ typedef btAlignedObjectArray<btVector3> btVertexArray;
|
|||||||
// Clips a face to the back of a plane
|
// Clips a face to the back of a plane
|
||||||
struct btPolyhedralContactClipping
|
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 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 void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS);
|
|
||||||
|
|
||||||
static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep);
|
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
|
#endif // __POLYHEDRAL_CONTACT_CLIPPING_H
|
||||||
|
|||||||
Reference in New Issue
Block a user