my first ODE program!
hi all!
this is my code:
--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <gl\glut.h>
#include <ode\ode.h>
dWorldID aWorld;
dSpaceID aSpace;
float cycle = 0, fade;
dJointGroupID aContactGroup;
dBodyID bodies;
dGeomID geoms;
GLfloat colors[4];
dGeomID baseGeoms;
unsigned int contactsThisFrame;
void kglTransformByODEGeom(dGeomID geom) {
const dReal *p = dGeomGetPosition(geom);
const dReal *R = dGeomGetRotation(geom);
GLdouble glm[16];
glm[0] = R[0]; glm[1] = R[4]; glm[2] = R[8]; glm[3] = 0;
glm[4] = R[1]; glm[5] = R[5]; glm[6] = R[9]; glm[7] = 0;
glm[8] = R[2]; glm[9] = R[6]; glm[10] = R[10];glm[11] = 0;
glm[12] = p[0]; glm[13] = p[1]; glm[14] = p[2]; glm[15] = 1;
glMultMatrixd(glm);
}
static void odeNearCallback(void *data, dGeomID g1, dGeomID g2) {
dBodyID b1 = dGeomGetBody(g1),
b2 = dGeomGetBody(g2);
if (b1 && b2 && dAreConnected(b1, b2))
return;
dContact contact;
dCollide(g1, g2, 1, &contact.geom, sizeof(dContact));
contact.surface.mode = 0;
contact.surface.mu = 20.0;
dJointAttach(dJointCreateContact(aWorld, aContactGroup, &contact), b1, b2);
contactsThisFrame++;
}
void myGlutResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w / h, 1.0, 120.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, -6, -20);
}
void myGlutIdle(void) {
const float step = 1.0/120;
cycle = fmod(cycle + step / 4, 1);
fade = fabs(cycle * 2 - 1);
contactsThisFrame = 0;
dSpaceCollide(aSpace, NULL, &odeNearCallback);
dWorldStep(aWorld, step);
dJointGroupEmpty(aContactGroup);
const dReal *cvel = dBodyGetLinearVel(bodies);
dBodyAddForce(bodies, -cvel[0] * 0.5, -cvel[1] * 0.5, -cvel[2] * 0.5);
glutPostRedisplay();
}
void myGlutDisplay(void) {
glClearColor(fade * 0.15, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
kglTransformByODEGeom(geoms);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colors);
glColor3f(fade * 1.5, 0, 0);
glRotatef(90, 1, 0, 0);
glutSolidSphere(0.5, 29, 29);
glEnable(GL_LIGHTING);
glPopMatrix();
glutSwapBuffers();
}
void specialkey (int key, int x, int y) {
switch (key) {
case GLUT_KEY_UP:
// improve here
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
// improve here
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
// improve here
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
// improve here
glutPostRedisplay();
break;
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test");
glutDisplayFunc(myGlutDisplay);
glutReshapeFunc(myGlutResize);
glutIdleFunc(myGlutIdle);
glutSpecialFunc (specialkey);
glPolygonOffset(1, 1);
glDepthFunc(GL_LEQUAL);
glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
myGlutResize(400, 300);
dInitODE();
aWorld = dWorldCreate();
aSpace = dHashSpaceCreate(aSpace);
aContactGroup = dJointGroupCreate(0);
baseGeoms = dCreatePlane(aSpace, 0, 1, 0, 0);
dWorldSetGravity(aWorld, 0, -9.81, 0);
dWorldSetERP(aWorld, 0.4);
dWorldSetCFM(aWorld, 1e-10);
dMass mass;
dMassSetBox(&mass, 1.0, 1, 1, 1);
bodies = dBodyCreate(aWorld);
dBodySetMass(bodies, &mass);
geoms = dCreateSphere(aSpace, 0.5);
dGeomSetBody(geoms, bodies);
dBodySetPosition(bodies, 0, 10, 0);
colors[0] = 1;
colors[1] = 0;
colors[2] = 0;
colors[3] = 1;
glutMainLoop();
return 0;
}
--------------------------------------------------------------------------------
It's a simple ball falling down on a plane.
Now, I want to improve the program adding a simple interaction: if I press an arrow, the plane under the ball should rotate around X and/or Z axis. I tried both setRotation and setParams functions related to baseGeoms, but the ball is thrown away from the plane, out of the viewport!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement