Jump to content
  • Advertisement
Sign in to follow this  
BradDaBug

Box/plane collisions in ODE

This topic is 4867 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having trouble getting box/plane collisions to work in my game. I've made this tiny little app and it's doing the same thing. The box drops and hits the plane then flies off. Spheres work perfectly. Does anyone see anything I'm doing wrong? If anyone wants to compile and run this thing to see what I'm talking about it requires SDL, OpenGL, GLU, and ODE.
// 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.surface.mu = 10;
        mycontacts.surface.mode = dContactApprox1 | dContactSoftERP | 
dContactSoftCFM;
        mycontacts.surface.soft_erp = 0.8;
        mycontacts.surface.soft_cfm = 0.01;
       
        dJointID c = dJointCreateContact(world, contacts, &mycontacts);
        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();
    }
}

Share this post


Link to post
Share on other sites
Advertisement
Fixed it. If you take a look at this line:
int num = dCollide(geom1, geom2, maxcontacts, &mycontacts[0].geom, sizeof(dContactGeom));

you'll see that there's a bug. The bug is that I'm sending sizeof(dContactGeom) instead of sizeof(dContact), so every contact after the first one is corrupt.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!