+ CMake build system fix under Windows: don't define _WINDOWS to allow Glut console demo to build properly
+ Allow user to enable useConvexConservativeDistanceUtil . Use dynamicsWorld->getDispatchInfo().m_useConvexConservativeDistanceUtil = true; (see Demos/Benchmarks/Benchmark4 (convex objects falling down) + Fix for plane drawing (just wire-frame) + Gimpact: use collision margin of 0.07 for demo (because BULLET_TRIANGLE_COLLISION is used) + replace dot,cross,distance,angle,triple in btVector3 by btDot, btCross,btDistance,btAngle,btDistance to avoid naming conflicts + Some fixes in GJK penetration depth normal direction (broken in a previous commit) + fix in calculateDiffAxisAngleQuaternion to make ConvexConservativeDistanceUtil work properly + allow debug drawing to debug btContinuousConvexCollision + add comment/warning that btTriangleMesh::findOrAddVertex is an internal method, users should use addTriangle instead
This commit is contained in:
@@ -238,7 +238,7 @@ static void split( const tNodeArray& leaves,
|
||||
right.resize(0);
|
||||
for(int i=0,ni=leaves.size();i<ni;++i)
|
||||
{
|
||||
if(dot(axis,leaves[i]->volume.Center()-org)<0)
|
||||
if(btDot(axis,leaves[i]->volume.Center()-org)<0)
|
||||
left.push_back(leaves[i]);
|
||||
else
|
||||
right.push_back(leaves[i]);
|
||||
@@ -319,7 +319,7 @@ static btDbvtNode* topdown(btDbvt* pdbvt,
|
||||
const btVector3 x=leaves[i]->volume.Center()-org;
|
||||
for(int j=0;j<3;++j)
|
||||
{
|
||||
++splitcount[j][dot(x,axis[j])>0?1:0];
|
||||
++splitcount[j][btDot(x,axis[j])>0?1:0];
|
||||
}
|
||||
}
|
||||
for( i=0;i<3;++i)
|
||||
|
||||
@@ -484,8 +484,8 @@ DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) con
|
||||
case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z());
|
||||
pi=btVector3(mi.x(),mi.y(),mi.z());break;
|
||||
}
|
||||
if((dot(n,px)+o)<0) return(-1);
|
||||
if((dot(n,pi)+o)>=0) return(+1);
|
||||
if((btDot(n,px)+o)<0) return(-1);
|
||||
if((btDot(n,pi)+o)>=0) return(+1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned si
|
||||
const btVector3 p( b[(signs>>0)&1]->x(),
|
||||
b[(signs>>1)&1]->y(),
|
||||
b[(signs>>2)&1]->z());
|
||||
return(dot(p,v));
|
||||
return(btDot(p,v));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -46,7 +46,7 @@ struct btDispatcherInfo
|
||||
m_enableSPU(true),
|
||||
m_useEpa(true),
|
||||
m_allowedCcdPenetration(btScalar(0.04)),
|
||||
m_useConvexConservativeDistanceUtil(true),
|
||||
m_useConvexConservativeDistanceUtil(false),
|
||||
m_convexConservativeDistanceThreshold(0.0f),
|
||||
m_stackAllocator(0)
|
||||
{
|
||||
|
||||
@@ -69,7 +69,7 @@ m_ownManifold (false),
|
||||
m_manifoldPtr(mf),
|
||||
m_lowLevelOfDetail(false),
|
||||
#ifdef USE_SEPDISTANCE_UTIL2
|
||||
,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
|
||||
m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
|
||||
(static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
|
||||
#endif
|
||||
m_numPerturbationIterations(numPerturbationIterations),
|
||||
|
||||
@@ -31,7 +31,8 @@ class btConvexPenetrationDepthSolver;
|
||||
///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
|
||||
///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
|
||||
///for certain pairs that have a small size ratio
|
||||
///#define USE_SEPDISTANCE_UTIL2 1
|
||||
|
||||
#define USE_SEPDISTANCE_UTIL2 1
|
||||
|
||||
///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
|
||||
///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
|
||||
|
||||
@@ -102,7 +102,8 @@ btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefault
|
||||
int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
|
||||
int sl = sizeof(btConvexSeparatingDistanceUtil);
|
||||
sl = sizeof(btGjkPairDetector);
|
||||
int collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
|
||||
int collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
|
||||
collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
|
||||
|
||||
if (constructionInfo.m_stackAlloc)
|
||||
|
||||
@@ -27,6 +27,7 @@ struct btDefaultCollisionConstructionInfo
|
||||
btPoolAllocator* m_collisionAlgorithmPool;
|
||||
int m_defaultMaxPersistentManifoldPoolSize;
|
||||
int m_defaultMaxCollisionAlgorithmPoolSize;
|
||||
int m_customCollisionAlgorithmMaxElementSize;
|
||||
int m_defaultStackAllocatorSize;
|
||||
int m_useEpaPenetrationAlgorithm;
|
||||
|
||||
@@ -36,6 +37,7 @@ struct btDefaultCollisionConstructionInfo
|
||||
m_collisionAlgorithmPool(0),
|
||||
m_defaultMaxPersistentManifoldPoolSize(4096),
|
||||
m_defaultMaxCollisionAlgorithmPoolSize(4096),
|
||||
m_customCollisionAlgorithmMaxElementSize(0),
|
||||
m_defaultStackAllocatorSize(0),
|
||||
m_useEpaPenetrationAlgorithm(true)
|
||||
{
|
||||
|
||||
@@ -40,9 +40,6 @@ class btTriangleMesh : public btTriangleIndexVertexArray
|
||||
|
||||
btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
|
||||
|
||||
int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
|
||||
void addIndex(int index);
|
||||
|
||||
bool getUse32bitIndices() const
|
||||
{
|
||||
return m_use32bitIndices;
|
||||
@@ -61,6 +58,10 @@ class btTriangleMesh : public btTriangleIndexVertexArray
|
||||
virtual void preallocateVertices(int numverts){(void) numverts;}
|
||||
virtual void preallocateIndices(int numindices){(void) numindices;}
|
||||
|
||||
///findOrAddVertex is an internal method, use addTriangle instead
|
||||
int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
|
||||
///addIndex is an internal method, use addTriangle instead
|
||||
void addIndex(int index);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -121,6 +121,10 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
|
||||
//not close enough
|
||||
while (dist > radius)
|
||||
{
|
||||
if (result.m_debugDrawer)
|
||||
{
|
||||
result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1));
|
||||
}
|
||||
numIter++;
|
||||
if (numIter > maxIter)
|
||||
{
|
||||
@@ -170,6 +174,11 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
|
||||
btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
|
||||
relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
|
||||
|
||||
if (result.m_debugDrawer)
|
||||
{
|
||||
result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(),0.2f,btVector3(1,0,0));
|
||||
}
|
||||
|
||||
result.DebugDraw( lambda );
|
||||
|
||||
btPointCollector pointCollector;
|
||||
@@ -197,6 +206,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
|
||||
//??
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -224,4 +234,3 @@ bool btContinuousConvexCollision::calcTimeOfImpact(
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace gjkepa2_impl
|
||||
lastw[clastw=(clastw+1)&3]=w;
|
||||
}
|
||||
/* Check for termination */
|
||||
const btScalar omega=dot(m_ray,w)/rl;
|
||||
const btScalar omega=btDot(m_ray,w)/rl;
|
||||
alpha=btMax(omega,alpha);
|
||||
if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
|
||||
{/* Return old simplex */
|
||||
@@ -288,7 +288,7 @@ namespace gjkepa2_impl
|
||||
{
|
||||
btVector3 axis=btVector3(0,0,0);
|
||||
axis[i]=1;
|
||||
const btVector3 p=cross(d,axis);
|
||||
const btVector3 p=btCross(d,axis);
|
||||
if(p.length2()>0)
|
||||
{
|
||||
appendvertice(*m_simplex, p);
|
||||
@@ -303,7 +303,7 @@ namespace gjkepa2_impl
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
const btVector3 n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
|
||||
const btVector3 n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w,
|
||||
m_simplex->c[2]->w-m_simplex->c[0]->w);
|
||||
if(n.length2()>0)
|
||||
{
|
||||
@@ -357,7 +357,7 @@ namespace gjkepa2_impl
|
||||
const btScalar l=d.length2();
|
||||
if(l>GJK_SIMPLEX2_EPS)
|
||||
{
|
||||
const btScalar t(l>0?-dot(a,d)/l:0);
|
||||
const btScalar t(l>0?-btDot(a,d)/l:0);
|
||||
if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); }
|
||||
else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); }
|
||||
else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
|
||||
@@ -372,7 +372,7 @@ namespace gjkepa2_impl
|
||||
static const U imd3[]={1,2,0};
|
||||
const btVector3* vt[]={&a,&b,&c};
|
||||
const btVector3 dl[]={a-b,b-c,c-a};
|
||||
const btVector3 n=cross(dl[0],dl[1]);
|
||||
const btVector3 n=btCross(dl[0],dl[1]);
|
||||
const btScalar l=n.length2();
|
||||
if(l>GJK_SIMPLEX3_EPS)
|
||||
{
|
||||
@@ -381,7 +381,7 @@ namespace gjkepa2_impl
|
||||
U subm;
|
||||
for(U i=0;i<3;++i)
|
||||
{
|
||||
if(dot(*vt[i],cross(dl[i],n))>0)
|
||||
if(btDot(*vt[i],btCross(dl[i],n))>0)
|
||||
{
|
||||
const U j=imd3[i];
|
||||
const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm));
|
||||
@@ -397,13 +397,13 @@ namespace gjkepa2_impl
|
||||
}
|
||||
if(mindist<0)
|
||||
{
|
||||
const btScalar d=dot(a,n);
|
||||
const btScalar d=btDot(a,n);
|
||||
const btScalar s=btSqrt(l);
|
||||
const btVector3 p=n*(d/l);
|
||||
mindist = p.length2();
|
||||
m = 7;
|
||||
w[0] = (cross(dl[1],b-p)).length()/s;
|
||||
w[1] = (cross(dl[2],c-p)).length()/s;
|
||||
w[0] = (btCross(dl[1],b-p)).length()/s;
|
||||
w[1] = (btCross(dl[2],c-p)).length()/s;
|
||||
w[2] = 1-(w[0]+w[1]);
|
||||
}
|
||||
return(mindist);
|
||||
@@ -420,7 +420,7 @@ namespace gjkepa2_impl
|
||||
const btVector3* vt[]={&a,&b,&c,&d};
|
||||
const btVector3 dl[]={a-d,b-d,c-d};
|
||||
const btScalar vl=det(dl[0],dl[1],dl[2]);
|
||||
const bool ng=(vl*dot(a,cross(b-c,a-b)))<=0;
|
||||
const bool ng=(vl*btDot(a,btCross(b-c,a-b)))<=0;
|
||||
if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
|
||||
{
|
||||
btScalar mindist=-1;
|
||||
@@ -429,7 +429,7 @@ namespace gjkepa2_impl
|
||||
for(U i=0;i<3;++i)
|
||||
{
|
||||
const U j=imd3[i];
|
||||
const btScalar s=vl*dot(d,cross(dl[i],dl[j]));
|
||||
const btScalar s=vl*btDot(d,btCross(dl[i],dl[j]));
|
||||
if(s>0)
|
||||
{
|
||||
const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
|
||||
@@ -601,7 +601,7 @@ namespace gjkepa2_impl
|
||||
bool valid=true;
|
||||
best->pass = (U1)(++pass);
|
||||
gjk.getsupport(best->n,*w);
|
||||
const btScalar wdist=dot(best->n,w->w)-best->d;
|
||||
const btScalar wdist=btDot(best->n,w->w)-best->d;
|
||||
if(wdist>EPA_ACCURACY)
|
||||
{
|
||||
for(U j=0;(j<3)&&valid;++j)
|
||||
@@ -628,11 +628,11 @@ namespace gjkepa2_impl
|
||||
m_result.c[0] = outer.c[0];
|
||||
m_result.c[1] = outer.c[1];
|
||||
m_result.c[2] = outer.c[2];
|
||||
m_result.p[0] = cross( outer.c[1]->w-projection,
|
||||
m_result.p[0] = btCross( outer.c[1]->w-projection,
|
||||
outer.c[2]->w-projection).length();
|
||||
m_result.p[1] = cross( outer.c[2]->w-projection,
|
||||
m_result.p[1] = btCross( outer.c[2]->w-projection,
|
||||
outer.c[0]->w-projection).length();
|
||||
m_result.p[2] = cross( outer.c[0]->w-projection,
|
||||
m_result.p[2] = btCross( outer.c[0]->w-projection,
|
||||
outer.c[1]->w-projection).length();
|
||||
const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
|
||||
m_result.p[0] /= sum;
|
||||
@@ -666,18 +666,18 @@ namespace gjkepa2_impl
|
||||
face->c[0] = a;
|
||||
face->c[1] = b;
|
||||
face->c[2] = c;
|
||||
face->n = cross(b->w-a->w,c->w-a->w);
|
||||
face->n = btCross(b->w-a->w,c->w-a->w);
|
||||
const btScalar l=face->n.length();
|
||||
const bool v=l>EPA_ACCURACY;
|
||||
face->p = btMin(btMin(
|
||||
dot(a->w,cross(face->n,a->w-b->w)),
|
||||
dot(b->w,cross(face->n,b->w-c->w))),
|
||||
dot(c->w,cross(face->n,c->w-a->w))) /
|
||||
btDot(a->w,btCross(face->n,a->w-b->w)),
|
||||
btDot(b->w,btCross(face->n,b->w-c->w))),
|
||||
btDot(c->w,btCross(face->n,c->w-a->w))) /
|
||||
(v?l:1);
|
||||
face->p = face->p>=-EPA_INSIDE_EPS?0:face->p;
|
||||
if(v)
|
||||
{
|
||||
face->d = dot(a->w,face->n)/l;
|
||||
face->d = btDot(a->w,face->n)/l;
|
||||
face->n /= l;
|
||||
if(forced||(face->d>=-EPA_PLANE_EPS))
|
||||
{
|
||||
@@ -715,7 +715,7 @@ namespace gjkepa2_impl
|
||||
if(f->pass!=pass)
|
||||
{
|
||||
const U e1=i1m3[e];
|
||||
if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
|
||||
if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
|
||||
{
|
||||
sFace* nf=newface(f->c[e1],f->c[e],w,false);
|
||||
if(nf)
|
||||
|
||||
@@ -299,6 +299,7 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
||||
btVector3 tmpPointOnA,tmpPointOnB;
|
||||
|
||||
gNumDeepPenetrationChecks++;
|
||||
m_cachedSeparatingAxis.setZero();
|
||||
|
||||
bool isValid2 = m_penetrationDepthSolver->calcPenDepth(
|
||||
*m_simplexSolver,
|
||||
@@ -308,23 +309,40 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
||||
debugDraw,input.m_stackAlloc
|
||||
);
|
||||
|
||||
|
||||
if (isValid2)
|
||||
{
|
||||
btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
|
||||
//only replace valid penetrations when the result is deeper (check)
|
||||
if (!isValid || (distance2 < distance))
|
||||
btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
|
||||
btScalar lenSqr = tmpNormalInB.length2();
|
||||
if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON))
|
||||
{
|
||||
distance = distance2;
|
||||
pointOnA = tmpPointOnA;
|
||||
pointOnB = tmpPointOnB;
|
||||
normalInB = m_cachedSeparatingAxis;
|
||||
isValid = true;
|
||||
m_lastUsedMethod = 3;
|
||||
} else
|
||||
tmpNormalInB = m_cachedSeparatingAxis;
|
||||
lenSqr = m_cachedSeparatingAxis.length2();
|
||||
}
|
||||
|
||||
if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
|
||||
{
|
||||
m_lastUsedMethod = 4;
|
||||
tmpNormalInB /= btSqrt(lenSqr);
|
||||
btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
|
||||
//only replace valid penetrations when the result is deeper (check)
|
||||
if (!isValid || (distance2 < distance))
|
||||
{
|
||||
distance = distance2;
|
||||
pointOnA = tmpPointOnA;
|
||||
pointOnB = tmpPointOnB;
|
||||
normalInB = tmpNormalInB;
|
||||
isValid = true;
|
||||
m_lastUsedMethod = 3;
|
||||
} else
|
||||
{
|
||||
m_lastUsedMethod = 8;
|
||||
}
|
||||
} else
|
||||
{
|
||||
m_lastUsedMethod = 9;
|
||||
}
|
||||
} else
|
||||
|
||||
{
|
||||
///this is another degenerate case, where the initial GJK calculation reports a degenerate case
|
||||
///EPA reports no penetration, and the second GJK (using the supporting vector without margin)
|
||||
@@ -333,21 +351,24 @@ void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result&
|
||||
///http://code.google.com/p/bullet/issues/detail?id=250
|
||||
|
||||
|
||||
btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin;
|
||||
//only replace valid distances when the distance is less
|
||||
if (!isValid || (distance2 < distance))
|
||||
if (m_cachedSeparatingAxis.length2() > btScalar(0.))
|
||||
{
|
||||
distance = distance2;
|
||||
pointOnA = tmpPointOnA;
|
||||
pointOnB = tmpPointOnB;
|
||||
pointOnA -= m_cachedSeparatingAxis * marginA ;
|
||||
pointOnB += m_cachedSeparatingAxis * marginB ;
|
||||
normalInB = m_cachedSeparatingAxis;
|
||||
isValid = true;
|
||||
m_lastUsedMethod = 6;
|
||||
} else
|
||||
{
|
||||
m_lastUsedMethod = 5;
|
||||
btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin;
|
||||
//only replace valid distances when the distance is less
|
||||
if (!isValid || (distance2 < distance))
|
||||
{
|
||||
distance = distance2;
|
||||
pointOnA = tmpPointOnA;
|
||||
pointOnB = tmpPointOnB;
|
||||
pointOnA -= m_cachedSeparatingAxis * marginA ;
|
||||
pointOnB += m_cachedSeparatingAxis * marginB ;
|
||||
normalInB = m_cachedSeparatingAxis;
|
||||
isValid = true;
|
||||
m_lastUsedMethod = 6;
|
||||
} else
|
||||
{
|
||||
m_lastUsedMethod = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user