added some brute-force way to shrink convex polyhedra (to compensate collision margin)

made Extra/EPA compile again, updated Pierre's testbed to compile out-of-the-box
This commit is contained in:
ejcoumans
2006-11-11 03:22:15 +00:00
parent 438230b95b
commit 8cbd721a1f
11 changed files with 143 additions and 145 deletions

View File

@@ -16,6 +16,7 @@ subject to the following restrictions:
#include "BspConverter.h"
#include "BspLoader.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btGeometryUtil.h"
void BspConverter::convertBsp(BspLoader& bspLoader,float scaling)
{
@@ -83,9 +84,7 @@ void BspConverter::convertBsp(BspLoader& bspLoader,float scaling)
{
std::vector<btVector3> vertices;
getVerticesFromPlaneEquations(planeEquations,vertices);
printf("getVerticesFromPlaneEquations returned %i\n",(int)vertices.size());
btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices);
bool isEntity = false;
btVector3 entityTarget(0.f,0.f,0.f);
@@ -160,7 +159,7 @@ void BspConverter::convertBsp(BspLoader& bspLoader,float scaling)
{
std::vector<btVector3> vertices;
getVerticesFromPlaneEquations(planeEquations,vertices);
btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices);
bool isEntity=true;
addConvexVerticesCollider(vertices,isEntity,targetLocation);
@@ -196,78 +195,3 @@ void BspConverter::convertBsp(BspLoader& bspLoader,float scaling)
void BspConverter::getVerticesFromPlaneEquations(const std::vector<btVector3>& planeEquations , std::vector<btVector3>& verticesOut )
{
const int numbrushes = planeEquations.size();
// brute force:
for (int i=0;i<numbrushes;i++)
{
const btVector3& N1 = planeEquations[i];
for (int j=i+1;j<numbrushes;j++)
{
const btVector3& N2 = planeEquations[j];
for (int k=j+1;k<numbrushes;k++)
{
const btVector3& N3 = planeEquations[k];
btVector3 n2n3; n2n3 = N2.cross(N3);
btVector3 n3n1; n3n1 = N3.cross(N1);
btVector3 n1n2; n1n2 = N1.cross(N2);
if ( ( n2n3.length2() > 0.0001f ) &&
( n3n1.length2() > 0.0001f ) &&
( n1n2.length2() > 0.0001f ) )
{
//point P out of 3 plane equations:
// d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
//P = -------------------------------------------------------------------------
// N1 . ( N2 * N3 )
float quotient = (N1.dot(n2n3));
if (btFabs(quotient) > 0.000001f)
{
quotient = -1.f / quotient;
n2n3 *= N1[3];
n3n1 *= N2[3];
n1n2 *= N3[3];
btVector3 potentialVertex = n2n3;
potentialVertex += n3n1;
potentialVertex += n1n2;
potentialVertex *= quotient;
//check if inside, and replace supportingVertexOut if needed
if (isInside(planeEquations,potentialVertex,0.1f))
{
verticesOut.push_back(potentialVertex);
}
}
}
}
}
}
}
bool BspConverter::isInside(const std::vector<btVector3>& planeEquations, const btVector3& point, float margin)
{
int numbrushes = planeEquations.size();
for (int i=0;i<numbrushes;i++)
{
const btVector3& N1 = planeEquations[i];
float dist = float(N1.dot(point))+float(N1[3])-margin;
if (dist>0.f)
{
return false;
}
}
return true;
}

View File

@@ -29,10 +29,6 @@ class BspConverter
virtual ~BspConverter()
{
}
///Utility function to create vertices from a Quake Brush. Brute force but it works.
///Bit overkill to use QHull package
void getVerticesFromPlaneEquations(const std::vector<btVector3>& planeEquations , std::vector<btVector3>& verticesOut );
bool isInside(const std::vector<btVector3>& planeEquations, const btVector3& point, float margin);
///this callback is called for each brush that succesfully converted into vertices
virtual void addConvexVerticesCollider(std::vector<btVector3>& vertices, bool isEntity, const btVector3& entityTargetLocation) = 0;

View File

@@ -57,6 +57,7 @@ bool createConstraint = true;//false;
bool useCompound = false;//true;//false;
#ifdef _DEBUG
const int gNumObjects = 120;
#else

View File

@@ -20,10 +20,13 @@ subject to the following restrictions:
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btGeometryUtil.h"
#include "GLDebugDrawer.h"
#include "BMF_Api.h"
#include <stdio.h> //printf debugging
#include <vector>
float deltaTime = 1.f/60.f;
@@ -89,7 +92,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(0,-4,0));
startTransform.setOrigin(btVector3(0,-4.5,0));
localCreateRigidBody(0.f,startTransform,new btBoxShape(btVector3(30,2,30)));
@@ -132,28 +135,34 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
//calc centroid, to shift vertices around center of mass
centroid.setValue(0,0,0);
std::vector<btVector3> vertices;
if ( 1 )
{
const unsigned int *src = result.mHullIndices;
for (unsigned int i=0; i<result.mHullTcount; i++)
for (unsigned int i=0; i<result.mHullVcount; i++)
{
unsigned int index0 = *src++;
unsigned int index1 = *src++;
unsigned int index2 = *src++;
btVector3 vertex0(result.mHullVertices[index0*3], result.mHullVertices[index0*3+1],result.mHullVertices[index0*3+2]);
btVector3 vertex1(result.mHullVertices[index1*3], result.mHullVertices[index1*3+1],result.mHullVertices[index1*3+2]);
btVector3 vertex2(result.mHullVertices[index2*3], result.mHullVertices[index2*3+1],result.mHullVertices[index2*3+2]);
vertex0 *= localScaling;
vertex1 *= localScaling;
vertex2 *= localScaling;
centroid += vertex0;
centroid += vertex1;
centroid += vertex2;
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
vertex *= localScaling;
centroid += vertex;
}
}
centroid *= 1.f/(float(result.mHullTcount) * 3);
centroid *= 1.f/(float(result.mHullVcount) );
if ( 1 )
{
const unsigned int *src = result.mHullIndices;
for (unsigned int i=0; i<result.mHullVcount; i++)
{
btVector3 vertex(result.mHullVertices[i*3],result.mHullVertices[i*3+1],result.mHullVertices[i*3+2]);
vertex *= localScaling;
vertex -= centroid ;
vertices.push_back(vertex);
}
}
if ( 1 )
{
@@ -176,6 +185,7 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
vertex1 -= centroid;
vertex2 -= centroid;
trimesh->addTriangle(vertex0,vertex1,vertex2);
index0+=mBaseCount;
@@ -187,7 +197,38 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
}
float mass = 1.f;
float collisionMargin = 0.01f;
//this is a tools issue: due to collision margin, convex objects overlap, compensate for it here:
//#define SHRINK_OBJECT_INWARDS 1
#ifdef SHRINK_OBJECT_INWARDS
std::vector<btVector3> planeEquations;
btGeometryUtil::getPlaneEquationsFromVertices(vertices,planeEquations);
std::vector<btVector3> shiftedPlaneEquations;
for (int p=0;p<planeEquations.size();p++)
{
btVector3 plane = planeEquations[p];
plane[3] += 5*collisionMargin;
shiftedPlaneEquations.push_back(plane);
}
std::vector<btVector3> shiftedVertices;
btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);
btCollisionShape* convexShape = new btConvexHullShape(&(shiftedVertices[0].getX()),shiftedVertices.size());
#else //SHRINK_OBJECT_INWARDS
//btCollisionShape* convexShape = new btConvexHullShape(&(vertices[0].getX()),vertices.size());
btCollisionShape* convexShape = new btConvexTriangleMeshShape(trimesh);
#endif
convexShape->setMargin(0.01);
btTransform trans;
trans.setIdentity();
trans.setOrigin(centroid);
@@ -251,11 +292,11 @@ void ConvexDecompositionDemo::initPhysics(const char* filename)
strcat(outputFileName,"_convex.obj");
FILE* outputFile = fopen(outputFileName,"wb");
unsigned int depth = 7;
unsigned int depth = 5;
float cpercent = 5;
float ppercent = 15;
unsigned int maxv = 16;
float skinWidth = 0.01;
float skinWidth = 0.0;
printf("WavefrontObj num triangles read %i",tcount);
ConvexDecomposition::DecompDesc desc;

View File

@@ -1,14 +1,37 @@
#include <stdio.h>
#include <GL/glut.h>
#include "btDiscreteCollisionDetectorInterface.h"
#include "btSimplexSolverInterface.h"
#include "btConvexHullShape.h"
#include "Solid3EpaPenetrationDepth.h"
#include "Solid3JohnsonSimplexSolver.h"
#include "btGjkPairDetector.h"
#include "btMinkowskiPenetrationDepthSolver.h"
#include "EpaPenetrationDepthSolver.h"
///contribution by Pierre Terdiman to check penetration depth solvers
///see http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=638
#ifdef WIN32//for glut.h
#include <windows.h>
#endif
//think different
#if defined(__APPLE__) && !defined (VMDMESA)
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "btBulletCollisionCommon.h"
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
#include "../Extras/ExtraSolid35/Solid3EpaPenetrationDepth.h"
#include "../Extras/ExtraSolid35/Solid3JohnsonSimplexSolver.h"
#include "../Extras/EPA/EpaPenetrationDepthSolver.h"
static bool gRefMode = false;
static int gMethod = 0;
@@ -211,7 +234,8 @@ static float gDepth;
static bool TestEPA(const MyConvex& hull0, const MyConvex& hull1)
{
static btSimplexSolverInterface simplexSolver;
// static Solid3JohnsonSimplexSolver simplexSolver;
//static Solid3JohnsonSimplexSolver simplexSolver;
simplexSolver.reset();
btConvexHullShape convexA((float*)hull0.mVerts, hull0.mNbVerts, sizeof(btVector3));
@@ -222,14 +246,17 @@ static bool TestEPA(const MyConvex& hull0, const MyConvex& hull1)
static btMinkowskiPenetrationDepthSolver Solver2;
btConvexPenetrationDepthSolver* Solver;
if(gMethod==0) Solver = &Solver0;
else if(gMethod==1) Solver = &Solver1;
else Solver = &Solver2;
if(gMethod==0)
Solver = &Solver0;
else if(gMethod==1)
Solver = &Solver1;
else
Solver = &Solver2;
btGjkPairDetector GJK(&convexA, &convexB, &simplexSolver, Solver);
GJK.setIgnoreMargin(true);
convexA.setMargin(0.0f);
convexB.setMargin(0.0f);
//GJK.setIgnoreMargin(true);
convexA.setMargin(0.01f);
convexB.setMargin(0.01f);
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_transformA = hull0.mTransform;
@@ -594,20 +621,20 @@ int main(int argc, char** argv)
glEnable(GL_LIGHT0);
//
bool Status = gConvex0.LoadFromFile("c:\\convex0.bin");
bool Status = gConvex0.LoadFromFile("convex0.bin");
if(!Status)
{
Status = gConvex0.LoadFromFile("convex0.bin");
Status = gConvex0.LoadFromFile("../../convex0.bin");
if(!Status)
{
printf("Failed to load object!\n");
exit(0);
}
}
Status = gConvex1.LoadFromFile("c:\\convex0.bin");
Status = gConvex1.LoadFromFile("convex0.bin");
if(!Status)
{
Status = gConvex1.LoadFromFile("convex0.bin");
Status = gConvex1.LoadFromFile("../../convex0.bin");
if(!Status)
{
printf("Failed to load object!\n");

View File

@@ -29,13 +29,13 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "NarrowPhaseCollision/EpaCommon.h"
#include "EpaCommon.h"
#include "NarrowPhaseCollision/EpaVertex.h"
#include "NarrowPhaseCollision/EpaHalfEdge.h"
#include "NarrowPhaseCollision/EpaFace.h"
#include "NarrowPhaseCollision/EpaPolyhedron.h"
#include "NarrowPhaseCollision/Epa.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#include "EpaPolyhedron.h"
#include "Epa.h"
const btScalar EPA_MAX_RELATIVE_ERROR = 1e-2f;
const btScalar EPA_MAX_RELATIVE_ERROR_SQRD = EPA_MAX_RELATIVE_ERROR * EPA_MAX_RELATIVE_ERROR;

View File

@@ -18,11 +18,11 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "NarrowPhaseCollision/EpaCommon.h"
#include "EpaCommon.h"
#include "NarrowPhaseCollision/EpaVertex.h"
#include "NarrowPhaseCollision/EpaHalfEdge.h"
#include "NarrowPhaseCollision/EpaFace.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#ifdef EPA_POLYHEDRON_USE_PLANES
btScalar PLANE_THICKNESS = 1e-5f;

View File

@@ -26,15 +26,15 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
#include "NarrowPhaseCollision/EpaCommon.h"
#include "EpaCommon.h"
#include "NarrowPhaseCollision/EpaVertex.h"
#include "NarrowPhaseCollision/EpaHalfEdge.h"
#include "NarrowPhaseCollision/EpaFace.h"
#include "NarrowPhaseCollision/EpaPolyhedron.h"
#include "NarrowPhaseCollision/Epa.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#include "EpaPolyhedron.h"
#include "Epa.h"
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
#include "NarrowPhaseCollision/EpaPenetrationDepthSolver.h"
#include "EpaPenetrationDepthSolver.h"
btScalar g_GJKMaxRelError = 1e-3f;
btScalar g_GJKMaxRelErrorSqrd = g_GJKMaxRelError * g_GJKMaxRelError;

View File

@@ -17,7 +17,7 @@ subject to the following restrictions:
#include "LinearMath/btScalar.h"
#include "LinearMath/btVector3.h"
#include "LinearMath/btPoint3.h"
#include "Memory2.h"
//#include "Memory2.h"
#include <list>
#ifdef _DEBUG
@@ -25,12 +25,12 @@ subject to the following restrictions:
#endif
#include "NarrowPhaseCollision/EpaCommon.h"
#include "EpaCommon.h"
#include "NarrowPhaseCollision/EpaVertex.h"
#include "NarrowPhaseCollision/EpaHalfEdge.h"
#include "NarrowPhaseCollision/EpaFace.h"
#include "NarrowPhaseCollision/EpaPolyhedron.h"
#include "EpaVertex.h"
#include "EpaHalfEdge.h"
#include "EpaFace.h"
#include "EpaPolyhedron.h"
EpaPolyhedron::EpaPolyhedron() : m_nbFaces( 0 )

BIN
convex0.bin Normal file

Binary file not shown.

View File

@@ -46,6 +46,15 @@ class btTriangleMesh : public btStridingMeshInterface
m_triangles.push_back(tri);
}
int getNumTriangles() const
{
return m_triangles.size();
}
const btMyTriangle& getTriangle(int index) const
{
return m_triangles[index];
}
//StridingMeshInterface interface implementation