Advertisement
Guest User

Balls

a guest
May 2nd, 2023
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | Source Code | 0 0
  1. #define dDOUBLE
  2. #include <ode/ode.h>
  3. #include <drawstuff/drawstuff.h>
  4.  
  5. #include <vector>
  6.  
  7. using namespace std;
  8.  
  9. uint32_t colors[] = { // -std=c++11
  10.   0xcccccccc, 0xcc9933cc, 0x33cc99cc, 0x9933cccc,
  11.   0x3399cccc, 0x99cc33cc, 0xcc3399cc, 0x999999cc,
  12.   0x666666cc, 0x996633cc, 0x339966cc, 0x663399cc,
  13.   0x336699cc, 0x669933cc, 0x993366cc, 0x333333cc
  14. };
  15.  
  16. inline
  17. void vec4fromU32(dVector4 &c, uint32_t col)
  18. {
  19.   for(int j = 0; j < 4; ++j)
  20.     c[j] = (dReal)*((unsigned char *)&col + (3 - j)) / 255.0; // little endian
  21. }
  22.  
  23. inline
  24. void vec4fromV4(dVector4 &dst, dVector4 &src)
  25. {
  26.   for(int i = 0; i < 4; ++i) dst[i] = src[i];
  27. }
  28.  
  29. typedef struct {
  30.   dWorldID world;
  31.   dSpaceID space;
  32.   dGeomID ground;
  33.   dJointGroupID contactgroup;
  34. } Gws;
  35.  
  36. typedef struct {
  37.   dBodyID body;
  38.   dGeomID geom;
  39.   dVector4 col;
  40. } Obg;
  41.  
  42. static Gws gws;
  43. static vector<Obg *> obgs;
  44. const dReal mass = 1.0, radius = 0.2;
  45. const dReal tDelta = 0.002;
  46.  
  47. void createWorld(Gws *gws)
  48. {
  49.   dInitODE2(0);
  50.   gws->world = dWorldCreate();
  51.   dWorldSetGravity(gws->world, 0, 0, -9.8);
  52.   gws->space = dHashSpaceCreate(0);
  53.   dSpaceSetCleanup(gws->space, 1);
  54.   gws->ground = dCreatePlane(gws->space, 0, 0, 1, 0);
  55.   gws->contactgroup = dJointGroupCreate(0);
  56. }
  57.  
  58. void destroyWorld(Gws *gws)
  59. {
  60.   dSpaceDestroy(gws->space);
  61.   dWorldDestroy(gws->world);
  62.   dCloseODE();
  63. }
  64.  
  65. void destroyObg(Obg *obg)
  66. {
  67.   dGeomDestroy(obg->geom);
  68.   dBodyDestroy(obg->body);
  69. }
  70.  
  71. void clearObgs()
  72. {
  73.   for(vector<Obg *>::iterator it = obgs.begin(); it != obgs.end(); ++it){
  74.     destroyObg(*it);
  75.   }
  76.   obgs.clear();
  77. }
  78.  
  79. Obg *mkSphere(Gws *gws, dReal m, dReal r, dVector4 &col, dVector3 &pos)
  80. {
  81.   dMass mass;
  82.   dMassSetZero(&mass);
  83.   dMassSetSphereTotal(&mass, m, r);
  84.   Obg *obg = new Obg;
  85.   vec4fromV4(obg->col, col);
  86.   obg->body = dBodyCreate(gws->world);
  87.   dBodySetMass(obg->body, &mass);
  88.   obg->geom = dCreateSphere(gws->space, r);
  89.   dGeomSetBody(obg->geom, obg->body);
  90.   dBodySetPosition(obg->body, pos[0], pos[1], pos[2]);
  91.   return obg;
  92. }
  93.  
  94. void nearCallback(void *dat, dGeomID o1, dGeomID o2)
  95. {
  96.   // if(!(gws.ground == o1 || gws.ground == o2)) return;
  97.   const int num = 40;
  98.   dContact contacts[num];
  99.   int n = dCollide(o1, o2, num, &contacts[0].geom, sizeof(dContact));
  100.   for(int i = 0; i < n; ++i){
  101.     dContact cntct = contacts[i];
  102.     cntct.surface.mu = dInfinity;
  103.     cntct.surface.mode = dContactBounce;
  104.     cntct.surface.bounce = 0.95;
  105.     cntct.surface.bounce_vel = 0.0;
  106.     dJointID c = dJointCreateContact(gws.world, gws.contactgroup, &cntct);
  107.     dJointAttach(c, dGeomGetBody(cntct.geom.g1), dGeomGetBody(cntct.geom.g2));
  108.   }
  109. }
  110.  
  111. void simLoop(int pause)
  112. {
  113.   if(pause != 1){
  114.     dSpaceCollide(gws.space, 0, nearCallback);
  115.     dWorldStep(gws.world, tDelta);
  116.     dJointGroupEmpty(gws.contactgroup);
  117.   }
  118.   for(vector<Obg *>::iterator it = obgs.begin(); it != obgs.end(); ++it){
  119.     dVector4 &c = (*it)->col;
  120.     dsSetColorAlpha(c[0], c[1], c[2], c[3]);
  121.     dGeomID geom = (*it)->geom;
  122.     dBodyID body = dGeomGetBody(geom);
  123.     int cls = dGeomGetClass(geom);
  124.     switch(cls){
  125.     case dSphereClass: {
  126.       const dReal *pos = dBodyGetPosition(body);
  127.       const dReal *rot = dBodyGetRotation(body);
  128.       const dReal radius = dGeomSphereGetRadius(geom);
  129.       dsDrawSphereD(pos, rot, radius);
  130.     } break;
  131.     default: {
  132.       printf("unknown class: %d\n", cls);
  133.     }
  134.     }
  135.   }
  136. }
  137.  
  138. void startCallback()
  139. {
  140.   static float xyz[3] = {4.0, 3.0, 5.0};
  141.   static float hpr[3] = {-150.0, -30.0, 3.0};
  142.   dsSetViewpoint(xyz, hpr);
  143. }
  144.  
  145. int main(int ac, char **av)
  146. {
  147.   createWorld(&gws);
  148.   for(int i = 0; i < 16; ++i){
  149.     dVector4 c;
  150.     vec4fromU32(c, colors[i]);
  151.     dVector3 p{i % 4 - 1.5, i / 4 - 1.5, 2.0, 1.0};
  152.     obgs.push_back(mkSphere(&gws, mass, radius, c, p));
  153.   }
  154.   dVector4 c{1.0, 1.0, 0.0, 0.8};
  155.   dVector3 p{0.0, 0.0, 10.0, 1.0};
  156.   obgs.push_back(mkSphere(&gws, 0.1, 1.0, c, p));
  157.  
  158.   dsFunctions fn;
  159.   fn.version = DS_VERSION;
  160.   fn.start = startCallback;
  161.   fn.step = simLoop;
  162.   fn.command = NULL;
  163.   fn.stop = NULL;
  164.   fn.path_to_textures = "./resources";
  165.   dsSimulationLoop(ac, av, 640, 480, &fn);
  166.  
  167.   clearObgs();
  168.   destroyWorld(&gws);
  169.   return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement