[ODE] Box/trimesh collision problem
Brad
braddabug at comcast.net
Sat Jun 18 00:48:10 MST 2005
I've created a little test application that shows what I'm talking about
it. It just creates a plane and drops either a box or a sphere onto it.
The graphical code is very basic, just enough to show the position of
the sphere/box. The sphere behaves but the box does not. It requires
OpenGL, GLU, and SDL (and ODE, of course). If you see anything wrong
with my code I'd LOVE to know about it, but I really can't see what I'm
doing wrong.
// This is an example of my problem. Spheres work fine, but boxes do not.
// The spheres drop, hit the plane, bounce a little, and eventually come
// to rest. The boxes hit the plane and go nuts. If you are able to get the
// box resting calmly on the plane, try dragging the window. The box
// will go nuts. Try the same thing with the sphere and it just
// sits there like it's supposed to.
#include <iostream>
using namespace std;
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <ode/ode.h>
dWorldID world;
dJointGroupID contacts;
int initgraphics(int width, int height, int depth)
{
SDL_Init(SDL_INIT_VIDEO);
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 6 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_SetVideoMode (width, height, depth, SDL_OPENGL);
float ratio = (float) width / (float) height;
glShadeModel( GL_SMOOTH );
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST);
glCullFace( GL_BACK );
glFrontFace( GL_CCW );
glEnable( GL_CULL_FACE );
glClearColor( 0.5, 0.5, 1.0, 0 );
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
gluPerspective( 60.0, ratio, 1.0, 5000.0 );
gluLookAt(-40, 0, 0, 0, 0, 0, 0, 1, 0);
}
void flip()
{
SDL_GL_SwapBuffers();
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
void cnear(void *data, dGeomID geom1, dGeomID geom2)
{
const int maxcontacts = 5;
dContact mycontacts[maxcontacts];
int num = dCollide(geom1, geom2, maxcontacts, &mycontacts[0].geom,
sizeof(dContactGeom));
for (int i = 0; i < num; i++)
{
mycontacts[i].surface.mu = 10;
mycontacts[i].surface.mode = dContactApprox1 | dContactSoftERP |
dContactSoftCFM;
mycontacts[i].surface.soft_erp = 0.8;
mycontacts[i].surface.soft_cfm = 0.01;
dJointID c = dJointCreateContact(world, contacts, &mycontacts[i]);
dJointAttach(c, dGeomGetBody(geom1), dGeomGetBody(geom2));
}
}
int main()
{
initgraphics(640, 480, 16);
world = dWorldCreate();
dWorldSetGravity(world, 0, -1, 0);
dSpaceID space = dSimpleSpaceCreate(0);
dGeomID ground = dCreatePlane(space, 0, 1, 0, 0);
// create a box
dMass m;
dBodyID body = dBodyCreate(world);
dMassSetBoxTotal(&m, 20.5, 2, 2, 2);
dBodySetMass(body, &m);
// if you create a box, it acts really unstable. If you create
// a sphere, it works prefectly
dGeomID geom = dCreateBox(space, 2, 2, 2);
//dGeomID geom = dCreateSphere(space, 1);
dGeomSetBody(geom, body);
dBodySetPosition(body, 0, 20, 0);
contacts = dJointGroupCreate(0);
GLUquadricObj *quadric = gluNewQuadric();
SDL_Event event;
while(true)
{
if(SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
return 0;
}
}
dJointGroupEmpty(contacts);
dSpaceCollide(space, contacts, cnear);
// go ahead, play with the stepsize. It won't do any good.
dWorldQuickStep(world, 1 / 120.0f);
const dReal *pos = dBodyGetPosition(body);
glPushMatrix();
glTranslatef(pos[0], pos[1], pos[2]);
gluCylinder(quadric, 1, 1, 1, 4, 1);
glPopMatrix();
flip();
}
}
More information about the ODE
mailing list