some more fixes to get msvc6 happy, and constraint solver: make non-randomizing solver default

This commit is contained in:
ejcoumans
2006-11-23 02:57:38 +00:00
parent 94abde9287
commit 7dc6aa215a
3 changed files with 95 additions and 49 deletions

View File

@@ -95,16 +95,19 @@ throw(object); }
template <typename T> static inline void Raise(const T&) {} template <typename T> static inline void Raise(const T&) {}
#endif #endif
//
// StackAlloc
//
struct StackAlloc
{
struct Block struct Block
{ {
Block* previous; Block* previous;
U1* address; U1* address;
}; };
//
// StackAlloc
//
struct StackAlloc
{
StackAlloc() { ctor(); } StackAlloc() { ctor(); }
StackAlloc(U size) { ctor();Create(size); } StackAlloc(U size) { ctor();Create(size); }
~StackAlloc() { Free(); } ~StackAlloc() { Free(); }
@@ -123,9 +126,20 @@ struct StackAlloc
usedsize = 0; usedsize = 0;
} else Raise(L"StackAlloc is still in use"); } else Raise(L"StackAlloc is still in use");
} }
U1* Allocate(U size)
{
const U nus(usedsize+size);
if(nus<totalsize)
{
usedsize=nus;
return(data+(usedsize-size));
}
Raise(L"Not enough memory");
return(0);
}
Block* BeginBlock() Block* BeginBlock()
{ {
Block* pb((Block*)Allocate(sizeof(Block))); Block* pb = (Block*)Allocate(sizeof(Block));
pb->previous = current; pb->previous = current;
pb->address = data+usedsize; pb->address = data+usedsize;
current = pb; current = pb;
@@ -139,17 +153,7 @@ struct StackAlloc
usedsize = (U)((block->address-data)-sizeof(Block)); usedsize = (U)((block->address-data)-sizeof(Block));
} else Raise(L"Unmatched blocks"); } else Raise(L"Unmatched blocks");
} }
U1* Allocate(U size)
{
const U nus(usedsize+size);
if(nus<totalsize)
{
usedsize=nus;
return(data+(usedsize-size));
}
Raise(L"Not enough memory");
return(0);
}
private: private:
void ctor() void ctor()
{ {
@@ -182,7 +186,7 @@ struct GJK
He* n; He* n;
}; };
StackAlloc* sa; StackAlloc* sa;
StackAlloc::Block* sablock; Block* sablock;
He* table[GJK_hashsize]; He* table[GJK_hashsize];
Rotation wrotations[2]; Rotation wrotations[2];
Vector3 positions[2]; Vector3 positions[2];
@@ -234,7 +238,7 @@ struct GJK
inline Z FetchSupport() inline Z FetchSupport()
{ {
const U h(Hash(ray)); const U h(Hash(ray));
He* e(table[h]); He* e = (He*)(table[h]);
while(e) { if(e->v==ray) { --order;return(false); } else e=e->n; } while(e) { if(e->v==ray) { --order;return(false); } else e=e->n; }
e=(He*)sa->Allocate(sizeof(He));e->v=ray;e->n=table[h];table[h]=e; e=(He*)sa->Allocate(sizeof(He));e->v=ray;e->n=table[h];table[h]=e;
Support(ray,simplex[++order]); Support(ray,simplex[++order]);
@@ -426,10 +430,10 @@ struct EPA
// //
inline Face* FindBest() const inline Face* FindBest() const
{ {
Face* bf(0); Face* bf = 0;
if(root) if(root)
{ {
Face* cf(root); Face* cf = root;
F bd(cstInf); F bd(cstInf);
do { do {
if(cf->d<bd) { bd=cf->d;bf=cf; } if(cf->d<bd) { bd=cf->d;bf=cf; }
@@ -457,7 +461,7 @@ c) const
// //
inline Face* NewFace(const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* c) inline Face* NewFace(const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* c)
{ {
Face* pf((Face*)sa->Allocate(sizeof(Face))); Face* pf = (Face*)sa->Allocate(sizeof(Face));
if(Set(pf,a,b,c)) if(Set(pf,a,b,c))
{ {
if(root) root->prev=pf; if(root) root->prev=pf;
@@ -499,7 +503,7 @@ c) const
// //
GJK::Mkv* Support(const Vector3& w) const GJK::Mkv* Support(const Vector3& w) const
{ {
GJK::Mkv* v((GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv))); GJK::Mkv* v =(GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv));
gjk->Support(w,*v); gjk->Support(w,*v);
return(v); return(v);
} }
@@ -514,7 +518,7 @@ ff)
const U e1(mod3[e+1]); const U e1(mod3[e+1]);
if((f.n.dot(w->w)+f.d)>0) if((f.n.dot(w->w)+f.d)>0)
{ {
Face* nf(NewFace(f.v[e1],f.v[e],w)); Face* nf = NewFace(f.v[e1],f.v[e],w);
Link(nf,0,&f,e); Link(nf,0,&f,e);
if(cf) Link(cf,1,nf,2); else ff=nf; if(cf) Link(cf,1,nf,2); else ff=nf;
cf=nf;ne=1; cf=nf;ne=1;
@@ -533,8 +537,8 @@ ff)
// //
inline F EvaluatePD(F accuracy=EPA_accuracy) inline F EvaluatePD(F accuracy=EPA_accuracy)
{ {
StackAlloc::Block* sablock(sa->BeginBlock()); Block* sablock = sa->BeginBlock();
Face* bestface(0); Face* bestface = 0;
U markid(1); U markid(1);
depth = -cstInf; depth = -cstInf;
normal = Vector3(0,0,0); normal = Vector3(0,0,0);
@@ -545,10 +549,10 @@ ff)
/* Prepare hull */ /* Prepare hull */
if(gjk->EncloseOrigin()) if(gjk->EncloseOrigin())
{ {
const U* pfidx(0); const U* pfidx = 0;
U nfidx(0); U nfidx= 0;
const U* peidx(0); const U* peidx = 0;
U neidx(0); U neidx = 0;
GJK::Mkv* basemkv[5]; GJK::Mkv* basemkv[5];
Face* basefaces[6]; Face* basefaces[6];
switch(gjk->order) switch(gjk->order)
@@ -569,13 +573,15 @@ U eidx[9][4]={{0,0,4,0},{0,1,2,1},{0,2,1,2},{1,1,5,2},{1,0,2,0},{2,2,3,2},{3,1,5
pfidx=(const U*)fidx;nfidx=6;peidx=(const U*)eidx;neidx=9; pfidx=(const U*)fidx;nfidx=6;peidx=(const U*)eidx;neidx=9;
} break; } break;
} }
for(U i=0;i<=gjk->order;++i) { U i;
for( i=0;i<=gjk->order;++i) {
basemkv[i]=(GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv));*basemkv[i]=gjk->simplex[i]; basemkv[i]=(GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv));*basemkv[i]=gjk->simplex[i];
} }
for(U i=0;i<nfidx;++i,pfidx+=3) { for( i=0;i<nfidx;++i,pfidx+=3) {
basefaces[i]=NewFace(basemkv[pfidx[0]],basemkv[pfidx[1]],basemkv[pfidx[2]]); basefaces[i]=NewFace(basemkv[pfidx[0]],basemkv[pfidx[1]],basemkv[pfidx[2]]);
} }
for(U i=0;i<neidx;++i,peidx+=4) { for( i=0;i<neidx;++i,peidx+=4) {
Link(basefaces[peidx[0]],peidx[1],basefaces[peidx[2]],peidx[3]); } Link(basefaces[peidx[0]],peidx[1],basefaces[peidx[2]],peidx[3]); }
} }
if(0==nfaces) if(0==nfaces)
@@ -586,17 +592,17 @@ Link(basefaces[peidx[0]],peidx[1],basefaces[peidx[2]],peidx[3]); }
/* Expand hull */ /* Expand hull */
for(;iterations<EPA_maxiterations;++iterations) for(;iterations<EPA_maxiterations;++iterations)
{ {
Face* bf(FindBest()); Face* bf = FindBest();
if(bf) if(bf)
{ {
GJK::Mkv* w(Support(-bf->n)); GJK::Mkv* w = Support(-bf->n);
const F d(bf->n.dot(w->w)+bf->d); const F d(bf->n.dot(w->w)+bf->d);
bestface = bf; bestface = bf;
if(d<-accuracy) if(d<-accuracy)
{ {
Face* cf(0); Face* cf =0;
Face* ff(0); Face* ff =0;
U nf(0); U nf = 0;
Detach(bf); Detach(bf);
bf->mark=++markid; bf->mark=++markid;
for(U i=0;i<3;++i) { for(U i=0;i<3;++i) {

View File

@@ -47,10 +47,47 @@ unsigned long btRand2()
return btSeed2; return btSeed2;
} }
//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
int btRandInt2 (int n) int btRandInt2 (int n)
{
// seems good; xor-fold and modulus
const unsigned long un = n;
unsigned long r = btRand2();
// note: probably more aggressive than it needs to be -- might be
// able to get away without one or two of the innermost branches.
if (un <= 0x00010000UL) {
r ^= (r >> 16);
if (un <= 0x00000100UL) {
r ^= (r >> 8);
if (un <= 0x00000010UL) {
r ^= (r >> 4);
if (un <= 0x00000004UL) {
r ^= (r >> 2);
if (un <= 0x00000002UL) {
r ^= (r >> 1);
}
}
}
}
}
return (int) (r % un);
}
int btRandIntWrong (int n)
{ {
float a = float(n) / 4294967296.0f; float a = float(n) / 4294967296.0f;
return (int) (float(btRand2()) * a); // printf("n = %d\n",n);
// printf("a = %f\n",a);
int res = (int) (float(btRand2()) * a);
// printf("res=%d\n",res);
return res;
} }
bool MyContactDestroyedCallback(void* userPersistentData) bool MyContactDestroyedCallback(void* userPersistentData)
@@ -63,14 +100,14 @@ bool MyContactDestroyedCallback(void* userPersistentData)
return true; return true;
} }
btSequentialImpulseConstraintSolver2::btSequentialImpulseConstraintSolver2() btSequentialImpulseConstraintSolver3::btSequentialImpulseConstraintSolver3()
{ {
setSolverMode(SOLVER_USE_WARMSTARTING); setSolverMode(SOLVER_RANDMIZE_ORDER);
} }
btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
:m_solverMode(SOLVER_RANDMIZE_ORDER) :m_solverMode(SOLVER_USE_WARMSTARTING)
{ {
gContactDestroyedCallback = &MyContactDestroyedCallback; gContactDestroyedCallback = &MyContactDestroyedCallback;
@@ -86,7 +123,7 @@ btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
} }
/// btSequentialImpulseConstraintSolver Sequentially applies impulses /// btSequentialImpulseConstraintSolver Sequentially applies impulses
float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) float btSequentialImpulseConstraintSolver3::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
{ {
btContactSolverInfo info = infoGlobal; btContactSolverInfo info = infoGlobal;
@@ -105,6 +142,7 @@ float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** man
{ {
btPersistentManifold* manifold = manifoldPtr[j]; btPersistentManifold* manifold = manifoldPtr[j];
prepareConstraints(manifold,info,debugDrawer); prepareConstraints(manifold,info,debugDrawer);
for (int p=0;p<manifoldPtr[j]->getNumContacts();p++) for (int p=0;p<manifoldPtr[j]->getNumContacts();p++)
{ {
gOrder[totalPoints].m_manifoldIndex = j; gOrder[totalPoints].m_manifoldIndex = j;
@@ -159,7 +197,7 @@ float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** man
/// btSequentialImpulseConstraintSolver Sequentially applies impulses /// btSequentialImpulseConstraintSolver Sequentially applies impulses
float btSequentialImpulseConstraintSolver2::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) float btSequentialImpulseConstraintSolver::solveGroup(btPersistentManifold** manifoldPtr, int numManifolds,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer)
{ {
btContactSolverInfo info = infoGlobal; btContactSolverInfo info = infoGlobal;
@@ -292,7 +330,9 @@ void btSequentialImpulseConstraintSolver::prepareConstraints(btPersistentManifol
} else } else
{ {
cpd = new btConstraintPersistentData(); cpd = new btConstraintPersistentData;
assert(cpd);
totalCpd ++; totalCpd ++;
//printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd); //printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd);
cp.m_userPersistentData = cpd; cp.m_userPersistentData = cpd;

View File

@@ -82,11 +82,11 @@ public:
}; };
/// Small variation on btSequentialImpulseConstraintSolver: warmstarting, separate friction, non-randomized ordering /// Small variation on btSequentialImpulseConstraintSolver: warmstarting, separate friction, non-randomized ordering
class btSequentialImpulseConstraintSolver2 : public btSequentialImpulseConstraintSolver class btSequentialImpulseConstraintSolver3 : public btSequentialImpulseConstraintSolver
{ {
public: public:
btSequentialImpulseConstraintSolver2(); btSequentialImpulseConstraintSolver3();
virtual float solveGroup(btPersistentManifold** manifold,int numManifolds,const btContactSolverInfo& info, btIDebugDraw* debugDrawer=0); virtual float solveGroup(btPersistentManifold** manifold,int numManifolds,const btContactSolverInfo& info, btIDebugDraw* debugDrawer=0);