| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #include <stdio.h>
- #include <glut.h>
- #include "ode.h"
- #define NUMBODIES 80
- #define USE_SPHERE 0
- #define USE_HELIX 1
- #define USE_TORQUE 1
- #define USE_WEIRD_MATRIX_OPS 0
- #define CONTACTS 1
- dWorldID aWorld;
- dSpaceID aSpace;
- float cycle = 0, fade;
- dJointGroupID aContactGroup;
- dBodyID bodies[NUMBODIES];
- dGeomID geoms[NUMBODIES];
- GLfloat colors[NUMBODIES][4];
- 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);
- dContact contact[CONTACTS];
- int contactsUsed, i;
- if (b1 && b2 && dAreConnected(b1, b2)) return;
- contactsUsed = dCollide(g1, g2, CONTACTS, &contact[0].geom,
- sizeof(dContact));
- if (contactsUsed > CONTACTS) contactsUsed = CONTACTS;
- for (i = 0; i < contactsUsed; i++) {
- contact[i].surface.mode = 0;
- contact[i].surface.mu = 20.0;
-
- dJointAttach(dJointCreateContact(aWorld, aContactGroup,
- &(contact[i])), 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;
- int i;
- cycle = fmod(cycle + step / 4, 1);
- fade = fabs(cycle * 2 - 1);
- contactsThisFrame = 0;
- dSpaceCollide(aSpace, NULL, &odeNearCallback);
- //printf("%u\n", contactsThisFrame);
- dWorldStep(aWorld, step);
- dJointGroupEmpty(aContactGroup);
- for (i = 0; i < NUMBODIES; i++) {
- const dReal *cvel = dBodyGetLinearVel(bodies[i]);
- dBodyAddForce(bodies[i],
- -cvel[0] * 0.5,
- -cvel[1] * 0.5,
- -cvel[2] * 0.5
- );
- }
- glutPostRedisplay();
- }
- void myGlutDisplay(void) {
- int i;
- glClearColor(fade * 0.15, 0, 0, 1);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (USE_WEIRD_MATRIX_OPS) glPushMatrix();
- for (i = 0; i < NUMBODIES; i++) {
- if (!USE_WEIRD_MATRIX_OPS) glPushMatrix();
- kglTransformByODEGeom(geoms[i]);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colors[i]);
- glColor3f(fade * 1.5, 0, 0);
- #if USE_SPHERE
- glRotatef(90, 1, 0, 0);
- glutSolidSphere(0.5, 9, 6);
- glDisable(GL_LIGHTING);
- glutWireSphere(0.5, 9, 6);
- #else
- glutSolidCube(1);
- glDisable(GL_LIGHTING);
- glutWireCube(1);
- #endif
- glEnable(GL_LIGHTING);
- if (!USE_WEIRD_MATRIX_OPS) glPopMatrix();
- }
- if (USE_WEIRD_MATRIX_OPS) glPopMatrix();
-
- glutSwapBuffers();
- }
- int main(int argc, char **argv) {
- printf("Initializing GLUT\n");
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(400, 300);
- glutInitWindowPosition(100, 100);
- glutCreateWindow("ODE Crash Test");
-
- glutDisplayFunc(myGlutDisplay);
- glutReshapeFunc(myGlutResize);
- glutIdleFunc(myGlutIdle);
- 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);
- printf("Creating ODE world\n");
- aWorld = dWorldCreate();
- aSpace = dHashSpaceCreate();
- aContactGroup = dJointGroupCreate(0);
- dCreatePlane(aSpace, 0, 1, 0, 0);
- dWorldSetGravity(aWorld, 0, -9.81, 0);
- dWorldSetERP(aWorld, 0.4);
- dWorldSetCFM(aWorld, 1e-10);
-
- printf("Creating objects\n");
- {
- int i;
- dMass mass;
-
- dMassSetBox(&mass, 1.0, 1, 1, 1);
- for (i = 0; i < NUMBODIES; i++) {
- float fraction = (float)i / NUMBODIES;
-
- bodies[i] = dBodyCreate(aWorld);
- dBodySetMass(bodies[i], &mass);
- #if USE_SPHERE
- geoms[i] = dCreateSphere(aSpace, 0.5);
- #else
- geoms[i] = dCreateBox(aSpace, 1, 1, 1);
- #endif
- dGeomSetBody(geoms[i], bodies[i]);
-
- if (USE_HELIX) {
- float r = (i % 3 - 1) * (1.5+4*(1 - fraction)),
- theta = (float)i / 4;
- dBodySetPosition(bodies[i],
- sin(theta) * r,
- (float)i + 1,
- cos(theta) * r
- );
- } else {
- dBodySetPosition(bodies[i], 0, (float)i * 2 + 1, 0);
- }
- if (USE_TORQUE) dBodyAddTorque(bodies[i], fraction*10, fraction*20, fraction*30);
-
- colors[i][0] = fraction;
- colors[i][1] = 1 - fraction;
- colors[i][2] = 1 - fabs(fraction * 2 - 1);
- colors[i][3] = 1;
- }
- }
- printf("Starting simulation\n");
- glutMainLoop();
-
- return 0;
- }
|