[ODE] patch: auto-disable implemented
Aras Pranckevicius
nearaz at interamotion.com
Tue Oct 21 10:08:44 MST 2003
Hi,
Auto-disabling of inactive bodies was supposed to be in StepFast - the docs
and function prototypes are present, but the actual implementation is not.
Some time ago I've implemented auto-disabling in ODE 0.35, now finally I've
got some time and did that on current ODE from CVS.
I guess the 'proper' thing would be to conditionally enable/disable this
feature at compilation time (similar to trimesh) - as it adds several
members to each body, and has some (very small) overhead. For my usual
stuff, auto-disabling is great, don't know about the others :)
Here, what should be done:
-----------------------------------------------------
objects.h (the one internal to ode sources):
approx. at line 40, add to body flags enum:
dxBodyAutoDisable = 16 // enable auto-disable on body
approx. at line 80, add to struct dxBody:
// auto-disabling
dReal autodis_threshold;
int autodis_steps;
int autodis_counter;
-----------------------------------------------------
ode.cpp
in processIslands, add to the start of initial
body visiting loop ["for (bb=world->firstbody; bb;
bb=(dxBody*)bb->next)"]:
if( (bb->flags&dxBodyAutoDisable) && !(bb->flags&dxBodyDisabled) ) {
bool disable = true;
const dReal *lvel = bb->lvel;;
dReal lspeed = dDOT(lvel,lvel);
if( lspeed > bb->autodis_threshold ) {
disable = false;
} else {
const dReal *avel = bb->avel;
dReal aspeed = dDOT(avel,avel);
if( aspeed > bb->autodis_threshold ) {
disable = false;
}
}
if( disable )
++bb->autodis_counter;
else
bb->autodis_counter = 0;
if( bb->autodis_counter > bb->autodis_steps ) {
bb->flags |= dxBodyDisabled;
continue;
}
}
in the same processIslands, in "traverse and tag all body's joints,
add...",
add to inside of "if (n->body && !n->body->tag) {":
n->body->flags &= ~dxBodyDisabled;
n->body->autodis_counter = 0;
in dBodyCreate(), add initialization:
b->autodis_threshold = REAL(0.003);
b->autodis_steps = 10;
b->autodis_counter = 0;
add implementation of auto-disable functions:
void dBodySetAutoDisableThresholdSF1( dBodyID b, dReal threshold )
{
dAASSERT(b);
b->autodis_threshold = threshold;
}
dReal dBodyGetAutoDisableThresholdSF1( dBodyID b )
{
dAASSERT(b);
return b->autodis_threshold;
}
void dBodySetAutoDisableStepsSF1( dBodyID b, int steps )
{
dAASSERT(b);
b->autodis_steps = steps;
}
int dBodyGetAutoDisableStepsSF1( dBodyID b )
{
dAASSERT(b);
return b->autodis_steps;
}
void dBodySetAutoDisableSF1( dBodyID b, int doAutoDisable )
{
dAASSERT(b);
if( !doAutoDisable ) b->flags &= ~dxBodyAutoDisable;
else b->flags |= dxBodyAutoDisable;
}
int dBodyGetAutoDisableSF1( dBodyID b )
{
dAASSERT(b);
return ((b->flags & dxBodyAutoDisable) != 0);
}
-----------------------------------------------------
stepfast.cpp: similar to ode.cpp
in processIslandsFast, add to the start of initial body
visiting loop, just after
[#ifdef TIMING dTimerNow ("Island Processing); #endif]:
if( (bb->flags&dxBodyAutoDisable) && !(bb->flags&dxBodyDisabled) ) {
bool disable = true;
const dReal *lvel = bb->lvel;;
dReal lspeed = dDOT(lvel,lvel);
if( lspeed > bb->autodis_threshold ) {
disable = false;
} else {
const dReal *avel = bb->avel;
dReal aspeed = dDOT(avel,avel);
if( aspeed > bb->autodis_threshold ) {
disable = false;
}
}
if( disable )
++bb->autodis_counter;
else
bb->autodis_counter = 0;
if( bb->autodis_counter > bb->autodis_steps ) {
bb->flags |= dxBodyDisabled;
continue;
}
}
in the same processIslandsFast, in "traverse and tag all body's joints,
add untagged...", after "n->body->flags &= ~dxBodyDisabled;" add:
n->body->autodis_counter = 0;
That should be it. Works for me in classic and iterative solvers like a
charm. The code is rather trivial, so it shouldn't contain severe bugs :)
Aras Pranckevicius aka NeARAZ
http://www.gim.ktu.lt/nesnausk/nearaz/
More information about the ODE
mailing list