| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- /*************************************************************************
- * *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith. *
- * All rights reserved. Email: [email protected] Web: www.q12.org *
- * *
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of EITHER: *
- * (1) The GNU Lesser General Public License as published by the Free *
- * Software Foundation; either version 2.1 of the License, or (at *
- * your option) any later version. The text of the GNU Lesser *
- * General Public License is included with this library in the *
- * file LICENSE.TXT. *
- * (2) The BSD-style license that is included with this library in *
- * the file LICENSE-BSD.TXT. *
- * *
- * This library is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details. *
- * *
- *************************************************************************/
- #include <vector>
- #include <ode/ode.h>
- #include <drawstuff/drawstuff.h>
- #include "texturepath.h"
- #ifdef dDOUBLE
- #define dsDrawBox dsDrawBoxD
- #endif
- static int levels = 5;
- static int ncards = 0;
- static dSpaceID space;
- static dWorldID world;
- static dJointGroupID contactgroup;
- struct Card {
- dBodyID body;
- dGeomID geom;
- static const dReal sides[3];
- Card()
- {
- body = dBodyCreate(world);
- geom = dCreateBox(space, sides[0], sides[1], sides[2]);
- dGeomSetBody(geom, body);
- dGeomSetData(geom, this);
- dMass mass;
- mass.setBox(1, sides[0], sides[1], sides[2]);
- dBodySetMass(body, &mass);
- }
- ~Card()
- {
- dBodyDestroy(body);
- dGeomDestroy(geom);
- }
-
- void draw() const
- {
- dsDrawBox(dBodyGetPosition(body),
- dBodyGetRotation(body), sides);
- }
- };
- static const dReal cwidth=.5, cthikness=.02, clength=1;
- const dReal Card::sides[3] = { cwidth, cthikness, clength };
- std::vector<Card*> cards;
- int getncards(int levels)
- {
- return (3*levels*levels + levels) / 2;
- }
- void place_cards()
- {
- ncards = getncards(levels);
- // destroy removed cards (if any)
- int oldcards = cards.size();
- for (int i=ncards; i<oldcards; ++i)
- delete cards[i];
- cards.resize(ncards);
- // construct new cards (if any)
- for (int i=oldcards; i<ncards; ++i)
- cards[i] = new Card;
-
- // for each level
- int c = 0;
- dMatrix3 right, left, hrot;
- dReal angle = 20*M_PI/180.;
- dRFromAxisAndAngle(right, 1, 0, 0, -angle);
- dRFromAxisAndAngle(left, 1, 0, 0, angle);
- dRFromAxisAndAngle(hrot, 1, 0, 0, 91*M_PI/180.);
-
- dReal eps = 0.05;
- dReal vstep = cos(angle)*clength + eps;
- dReal hstep = sin(angle)*clength + eps;
-
- for (int lvl=0; lvl<levels; ++lvl) {
- // there are 3*(levels-lvl)-1 cards in each level, except last
- int n = (levels-lvl);
- dReal height = (lvl)*vstep + vstep/2;
- // inclined cards
- for (int i=0; i<2*n; ++i, ++c) {
- dBodySetPosition(cards[c]->body,
- 0,
- -n*hstep + hstep*i,
- height
- );
- if (i%2)
- dBodySetRotation(cards[c]->body, left);
- else
- dBodySetRotation(cards[c]->body, right);
- }
-
- if (n==1) // top of the house
- break;
-
- // horizontal cards
- for (int i=0; i<n-1; ++i, ++c) {
- dBodySetPosition(cards[c]->body,
- 0,
- -(n-1 - (clength-hstep)/2)*hstep + 2*hstep*i,
- height + vstep/2);
- dBodySetRotation(cards[c]->body, hrot);
- }
- }
-
- }
- void start()
- {
- puts("Controls:");
- puts(" SPACE - reposition cards");
- puts(" - - one less level");
- puts(" = - one more level");
- }
- static void nearCallback (void *, dGeomID o1, dGeomID o2)
- {
- // exit without doing anything if the two bodies are connected by a joint
- dBodyID b1 = dGeomGetBody(o1);
- dBodyID b2 = dGeomGetBody(o2);
- const int MAX_CONTACTS = 8;
- dContact contact[MAX_CONTACTS];
-
- int numc = dCollide (o1, o2, MAX_CONTACTS,
- &contact[0].geom,
- sizeof(dContact));
-
- for (int i=0; i<numc; i++) {
- contact[i].surface.mode = dContactApprox1;
- contact[i].surface.mu = 5;
- dJointID c = dJointCreateContact (world, contactgroup, contact+i);
- dJointAttach (c, b1, b2);
- }
- }
- void simLoop(int pause)
- {
- if (!pause) {
- dSpaceCollide (space, 0, &nearCallback);
- dWorldQuickStep(world, 0.01);
- dJointGroupEmpty(contactgroup);
- }
-
- dsSetColor (1,1,0);
- for (int i=0; i<ncards; ++i) {
- dsSetColor (1, dReal(i)/ncards, 0);
- cards[i]->draw();
- }
-
- }
- void command(int c)
- {
- switch (c) {
- case '=':
- levels++;
- place_cards();
- break;
- case '-':
- levels--;
- if (levels <= 0)
- levels++;
- place_cards();
- break;
- case ' ':
- place_cards();
- break;
- }
- }
- int main(int argc, char **argv)
- {
- dInitODE();
-
- // setup pointers to drawstuff callback functions
- dsFunctions fn;
- fn.version = DS_VERSION;
- fn.start = &start;
- fn.step = &simLoop;
- fn.command = &command;
- fn.stop = 0;
- fn.path_to_textures = DRAWSTUFF_TEXTURE_PATH;
-
-
- world = dWorldCreate();
- dWorldSetGravity(world, 0, 0, -0.5);
- dWorldSetQuickStepNumIterations(world, 50); // <-- increase for more stability
-
- space = dSimpleSpaceCreate(0);
- contactgroup = dJointGroupCreate(0);
- dGeomID ground = dCreatePlane(space, 0, 0, 1, 0);
-
- place_cards();
-
- dThreadingImplementationID threading = dThreadingAllocateMultiThreadedImplementation();
- dThreadingThreadPoolID pool = dThreadingAllocateThreadPool(4, 0, dAllocateFlagBasicData, NULL);
- dThreadingThreadPoolServeMultiThreadedImplementation(pool, threading);
- // dWorldSetStepIslandsProcessingMaxThreadCount(world, 1);
- dWorldSetStepThreadingImplementation(world, dThreadingImplementationGetFunctions(threading), threading);
- // run simulation
- dsSimulationLoop (argc, argv, DS_SIMULATION_DEFAULT_WIDTH, DS_SIMULATION_DEFAULT_HEIGHT, &fn);
-
- dThreadingImplementationShutdownProcessing(threading);
- dThreadingFreeThreadPool(pool);
- dWorldSetStepThreadingImplementation(world, NULL, NULL);
- dThreadingFreeImplementation(threading);
- levels = 0;
- place_cards();
-
- dJointGroupDestroy(contactgroup);
- dWorldDestroy(world);
- dGeomDestroy(ground);
- dSpaceDestroy(space);
-
- dCloseODE();
- }
|