test_stacktest.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include <stdio.h>
  2. #include <glut.h>
  3. #include "ode.h"
  4. #define NUMBODIES 80
  5. #define USE_SPHERE 0
  6. #define USE_HELIX 1
  7. #define USE_TORQUE 1
  8. #define USE_WEIRD_MATRIX_OPS 0
  9. #define CONTACTS 1
  10. dWorldID aWorld;
  11. dSpaceID aSpace;
  12. float cycle = 0, fade;
  13. dJointGroupID aContactGroup;
  14. dBodyID bodies[NUMBODIES];
  15. dGeomID geoms[NUMBODIES];
  16. GLfloat colors[NUMBODIES][4];
  17. unsigned int contactsThisFrame;
  18. void kglTransformByODEGeom(dGeomID geom) {
  19. const dReal *p = dGeomGetPosition(geom);
  20. const dReal *R = dGeomGetRotation(geom);
  21. GLdouble glm[16];
  22. glm[0] = R[0]; glm[1] = R[4]; glm[2] = R[8]; glm[3] = 0;
  23. glm[4] = R[1]; glm[5] = R[5]; glm[6] = R[9]; glm[7] = 0;
  24. glm[8] = R[2]; glm[9] = R[6]; glm[10] = R[10];glm[11] = 0;
  25. glm[12] = p[0]; glm[13] = p[1]; glm[14] = p[2]; glm[15] = 1;
  26. glMultMatrixd(glm);
  27. }
  28. static void odeNearCallback(void *data, dGeomID g1, dGeomID g2) {
  29. dBodyID b1 = dGeomGetBody(g1),
  30. b2 = dGeomGetBody(g2);
  31. dContact contact[CONTACTS];
  32. int contactsUsed, i;
  33. if (b1 && b2 && dAreConnected(b1, b2)) return;
  34. contactsUsed = dCollide(g1, g2, CONTACTS, &contact[0].geom,
  35. sizeof(dContact));
  36. if (contactsUsed > CONTACTS) contactsUsed = CONTACTS;
  37. for (i = 0; i < contactsUsed; i++) {
  38. contact[i].surface.mode = 0;
  39. contact[i].surface.mu = 20.0;
  40. dJointAttach(dJointCreateContact(aWorld, aContactGroup,
  41. &(contact[i])), b1, b2);
  42. contactsThisFrame++;
  43. }
  44. }
  45. void myGlutResize(int w, int h) {
  46. glViewport(0, 0, w, h);
  47. glMatrixMode(GL_PROJECTION);
  48. glLoadIdentity();
  49. gluPerspective(45.0, (GLfloat)w / h, 1.0, 120.0);
  50. glMatrixMode(GL_MODELVIEW);
  51. glLoadIdentity();
  52. glTranslatef(0, -6, -20);
  53. }
  54. void myGlutIdle(void) {
  55. const float step = 1.0/120;
  56. int i;
  57. cycle = fmod(cycle + step / 4, 1);
  58. fade = fabs(cycle * 2 - 1);
  59. contactsThisFrame = 0;
  60. dSpaceCollide(aSpace, NULL, &odeNearCallback);
  61. //printf("%u\n", contactsThisFrame);
  62. dWorldStep(aWorld, step);
  63. dJointGroupEmpty(aContactGroup);
  64. for (i = 0; i < NUMBODIES; i++) {
  65. const dReal *cvel = dBodyGetLinearVel(bodies[i]);
  66. dBodyAddForce(bodies[i],
  67. -cvel[0] * 0.5,
  68. -cvel[1] * 0.5,
  69. -cvel[2] * 0.5
  70. );
  71. }
  72. glutPostRedisplay();
  73. }
  74. void myGlutDisplay(void) {
  75. int i;
  76. glClearColor(fade * 0.15, 0, 0, 1);
  77. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  78. if (USE_WEIRD_MATRIX_OPS) glPushMatrix();
  79. for (i = 0; i < NUMBODIES; i++) {
  80. if (!USE_WEIRD_MATRIX_OPS) glPushMatrix();
  81. kglTransformByODEGeom(geoms[i]);
  82. glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, colors[i]);
  83. glColor3f(fade * 1.5, 0, 0);
  84. #if USE_SPHERE
  85. glRotatef(90, 1, 0, 0);
  86. glutSolidSphere(0.5, 9, 6);
  87. glDisable(GL_LIGHTING);
  88. glutWireSphere(0.5, 9, 6);
  89. #else
  90. glutSolidCube(1);
  91. glDisable(GL_LIGHTING);
  92. glutWireCube(1);
  93. #endif
  94. glEnable(GL_LIGHTING);
  95. if (!USE_WEIRD_MATRIX_OPS) glPopMatrix();
  96. }
  97. if (USE_WEIRD_MATRIX_OPS) glPopMatrix();
  98. glutSwapBuffers();
  99. }
  100. int main(int argc, char **argv) {
  101. printf("Initializing GLUT\n");
  102. glutInit(&argc, argv);
  103. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  104. glutInitWindowSize(400, 300);
  105. glutInitWindowPosition(100, 100);
  106. glutCreateWindow("ODE Crash Test");
  107. glutDisplayFunc(myGlutDisplay);
  108. glutReshapeFunc(myGlutResize);
  109. glutIdleFunc(myGlutIdle);
  110. glPolygonOffset(1, 1);
  111. glDepthFunc(GL_LEQUAL);
  112. glEnable(GL_POLYGON_OFFSET_FILL);
  113. glEnable(GL_DEPTH_TEST);
  114. glEnable(GL_CULL_FACE);
  115. glEnable(GL_LIGHTING);
  116. glEnable(GL_LIGHT0);
  117. myGlutResize(400, 300);
  118. printf("Creating ODE world\n");
  119. aWorld = dWorldCreate();
  120. aSpace = dHashSpaceCreate();
  121. aContactGroup = dJointGroupCreate(0);
  122. dCreatePlane(aSpace, 0, 1, 0, 0);
  123. dWorldSetGravity(aWorld, 0, -9.81, 0);
  124. dWorldSetERP(aWorld, 0.4);
  125. dWorldSetCFM(aWorld, 1e-10);
  126. printf("Creating objects\n");
  127. {
  128. int i;
  129. dMass mass;
  130. dMassSetBox(&mass, 1.0, 1, 1, 1);
  131. for (i = 0; i < NUMBODIES; i++) {
  132. float fraction = (float)i / NUMBODIES;
  133. bodies[i] = dBodyCreate(aWorld);
  134. dBodySetMass(bodies[i], &mass);
  135. #if USE_SPHERE
  136. geoms[i] = dCreateSphere(aSpace, 0.5);
  137. #else
  138. geoms[i] = dCreateBox(aSpace, 1, 1, 1);
  139. #endif
  140. dGeomSetBody(geoms[i], bodies[i]);
  141. if (USE_HELIX) {
  142. float r = (i % 3 - 1) * (1.5+4*(1 - fraction)),
  143. theta = (float)i / 4;
  144. dBodySetPosition(bodies[i],
  145. sin(theta) * r,
  146. (float)i + 1,
  147. cos(theta) * r
  148. );
  149. } else {
  150. dBodySetPosition(bodies[i], 0, (float)i * 2 + 1, 0);
  151. }
  152. if (USE_TORQUE) dBodyAddTorque(bodies[i], fraction*10, fraction*20, fraction*30);
  153. colors[i][0] = fraction;
  154. colors[i][1] = 1 - fraction;
  155. colors[i][2] = 1 - fabs(fraction * 2 - 1);
  156. colors[i][3] = 1;
  157. }
  158. }
  159. printf("Starting simulation\n");
  160. glutMainLoop();
  161. return 0;
  162. }