All pastes #250362 Raw Edit

Mine

public text v1 · immutable
#250362 ·published 2006-11-16 22:03 UTC
rendered paste body
extern "C" {
  #include "screen.h"
  #include "event.h"
  #include "util.h"
  #include "block.h"
}

#include <ode/ode.h>

#define TYPE_STATIC  0x00
#define TYPE_MOVABLE 0x01

struct object {
  unsigned char type;
  dGeomID geom;
  dBodyID body;
  struct block block;
};

struct screen screen;
dWorldID world;
dSpaceID space;
dJointGroupID contactgroup;

const char progname[] = "test1";

struct object objects[] = {
  { TYPE_STATIC,  0, 0, { "base1", 8.0, 1.0, 2.0, 10.0, 0, 0} },
  { TYPE_MOVABLE, 0, 0, { "drop",  1.0, 1.0, 1.2, 1.0,  0, 0} },
};

void init_ode()
{
  dMass dm;
  unsigned int ind;

  info("init_ode", "ode init");

  world = dWorldCreate();
  space = dHashSpaceCreate(0);
  contactgroup = dJointGroupCreate(0);

  dWorldSetGravity(world, 0, 9.81, 0);
  dWorldSetAutoDisableFlag(world, 1);
  dWorldSetContactMaxCorrectingVel(world, 0.1);

  for (ind = 0; ind < sizeof(objects) / sizeof(struct object); ++ind) {
    struct object *o = &objects[ind];
    o->body = 0;
    o->geom = dCreateBox(space, o->block.w, o->block.h, 1.0);
    if (o->type == TYPE_MOVABLE) {
      o->body = dBodyCreate(world);
      dBodySetPosition(o->body, o->block.x, o->block.y, 0.0);
      dMassSetZero(&dm);
      dMassSetBoxTotal(&dm, 1.0, o->block.w, o->block.h, 1.0);
      dBodySetMass(o->body, &dm);
    }
    dGeomSetPosition(o->geom, o->block.x, o->block.y, 0.0);
    dGeomSetBody(o->geom, o->body);
  }
}
void close_ode()
{
  info("close_ode", "ode close");

  dJointGroupDestroy(contactgroup);
  dSpaceDestroy(space);
  dWorldDestroy(world);
}

void near_callback(void *data, dGeomID o1, dGeomID o2)
{
  dContact contact[8];
  unsigned int ind;
  unsigned int nc;
  dBodyID b1;
  dBodyID b2;

  b1 = dGeomGetBody(o1);
  b2 = dGeomGetBody(o2);

  /* do nothing if the two bodies are connected by a joint */
  if (b1 && b2 && dAreConnectedExcluding(b1, b2, dJointTypeContact))
    return;

  for (ind = 0; ind < 8; ++ind) {
    contact[ind].surface.mode = dContactBounce | dContactSoftCFM;
    contact[ind].surface.mu = 0;
    contact[ind].surface.mu2 = 0;
    contact[ind].surface.bounce = 0.1;
    contact[ind].surface.bounce_vel = 0.1;
    contact[ind].surface.soft_cfm = 0.01;
  }
  nc = dCollide(o1, o2, 8, &contact[0].geom, sizeof(dContact));

  /* now what? */
  if (nc) {
    const dReal *xyz;
    const dReal *rot;
    xyz = dGeomGetPosition(o1);
    rot = dGeomGetRotation(o1);
    printf("o1    %f %f %f  %f %f %f\n",
                  xyz[0], xyz[1], xyz[2],
                  rot[0], rot[1], rot[2]);
    xyz = dGeomGetPosition(o2);
    rot = dGeomGetRotation(o2);
    printf("o2    %f %f %f  %f %f %f\n",
                  xyz[0], xyz[1], xyz[2],
                  rot[0], rot[1], rot[2]);
  }

  for (ind = 0; ind < nc; ++ind) {
    dJointID cnt;
    cnt = dJointCreateContact(world, contactgroup, contact + ind);
    dJointAttach(cnt, b1, b2);
  }
}
void move()
{
  const dReal *xyz;
  const dReal *rot;
  unsigned int ind;

  dSpaceCollide(space, 0, &near_callback);  
  dWorldQuickStep(world, 0.01);

  dJointGroupEmpty(contactgroup);

  for (ind = 0; ind < sizeof(objects) / sizeof(struct object); ++ind) {
    struct object *o = &objects[ind];
    xyz = dGeomGetPosition(o->geom);
    rot = dGeomGetRotation(o->geom);
    o->block.x = xyz[0];
    o->block.y = xyz[1];
  }
}
void draw()
{
  unsigned int ind;

  glClearColor(1.0, 1.0, 1.0, 1.0);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glColor3f(0.0, 0.0, 0.0);

  glLoadIdentity();

  for (ind = 0; ind < sizeof(objects) / sizeof(struct object); ++ind)
    block_draw(&objects[ind].block);

  SDL_GL_SwapBuffers();
}

int main()
{
  SDL_Event event;

  init_ode();
  if (atexit(close_ode) == -1)
    die("atexit", 0);

  screen.rect.w = 640;
  screen.rect.h = 480;
  screen.bpp = 32;

  if (!screen_init(&screen))
    die("screen_init", screen_error());
  if (atexit(screen_end) == -1)
    die("atexit", 0);
  if (!event_init())
    die("event_init", event_error());
  if (atexit(event_end) == -1)
    die("atexit", 0);

  init_gl();

  for (;;) {
    while (event_poll(&event)) {
      switch (event.type) { 
        case SDL_KEYUP:
          switch (event.key.keysym.sym) {
            case SDLK_ESCAPE: quit(); break;
            default: break;
          }
          break;
        case SDL_QUIT: quit(); break;
        default: break;
      }
    }
    move();
    draw();
    SDL_Delay(10);
  }

  close_ode();
  return 0;
}