// Called by Physics::Server when the Level is attached to the server. void CLevel::Activate() { TimeToSim = 0.0; // Initialize ODE //???per-Level? dInitODE(); ODEWorldID = dWorldCreate(); dWorldSetQuickStepNumIterations(ODEWorldID, 20); // FIXME(enno): is a quadtree significantly faster? -- can't count geoms with quadtree ODECommonSpaceID = dSimpleSpaceCreate(NULL); ODEDynamicSpaceID = dSimpleSpaceCreate(ODECommonSpaceID); ODEStaticSpaceID = dSimpleSpaceCreate(ODECommonSpaceID); dWorldSetGravity(ODEWorldID, Gravity.x, Gravity.y, Gravity.z); dWorldSetContactSurfaceLayer(ODEWorldID, 0.001f); dWorldSetContactMaxCorrectingVel(ODEWorldID, 100.0f); dWorldSetERP(ODEWorldID, 0.2f); // ODE's default value dWorldSetCFM(ODEWorldID, 0.001f); // the default is 10^-5 // setup autodisabling dWorldSetAutoDisableFlag(ODEWorldID, 1); dWorldSetAutoDisableSteps(ODEWorldID, 5); //dWorldSetAutoDisableTime(ODEWorldID, 1.f); dWorldSetAutoDisableLinearThreshold(ODEWorldID, 0.05f); // default is 0.01 dWorldSetAutoDisableAngularThreshold(ODEWorldID, 0.1f); // default is 0.01 // create a Contact group for joints ContactJointGroup = dJointGroupCreate(0); }
void PhysWorld::Initialize() { dInitODE(); mWorld = dWorldCreate(); mSpace = dSimpleSpaceCreate(0); isInitialized = true; }
void CPHGeometryOwner::CreateGroupSpace() { VERIFY(!m_group); m_group=dSimpleSpaceCreate(0); dSpaceSetCleanup(m_group,0); }
ODEDomain::ODEDomain(char const *space_type, Input *input) : BaseDomain(input) { printf("ODEDomain constructor\n"); dInitODE(); world = dWorldCreate(); contactgroup = dJointGroupCreate (0); //dWorldSetAutoDisableFlag(world,1); //dWorldSetCFM(world,1e-5); //Set and get the global CFM (constraint force mixing) value. Typical values are in the range 10-9 -- 1. The default is 10-5 if single precision is being used, or 10-10 if double precision is being used. //TODO HERE HAS TO BE ANOTHER PARAMETR //dWorldSetContactSurfaceLayer(world,0.001); //dWorldSetQuickStepNumIterations (world,ITERS); dRandSetSeed (time(NULL)); setGravity(m_input->gravity_v[0],m_input->gravity_v[1],m_input->gravity_v[2]); if (space_type == std::string("quad")) { dVector3 Center = {boundaries[0][0]+delta[0]*0.5, boundaries[1][0]+delta[1]*0.5, boundaries[2][0]+delta[2]*0.5, 0}; dVector3 Extents = {delta[0] * 0.55, delta[1] * 0.55, delta[2] * 0.55, 0}; printf(":::: Using Quad Tree Space\n"); space = dQuadTreeSpaceCreate (0, Center, Extents, 6); } else if (space_type == std::string("hash")) { printf(":::: Using Hash Space\n"); space = dHashSpaceCreate (0); //dHashSpaceSetLevels (space,-10,10); } else if (space_type == std::string("sap")) { printf(":::: Using Sweep And Prune Space\n"); space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); } else if (space_type == std::string("simple")) { printf(":::: Using Simple Space\n"); space = dSimpleSpaceCreate(0); } if (!space) { printf(":::: Using Sweep And Prune Space\n"); space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); } //TODO redo tests //I did tests: deposition of 10000 particles without& (~catBits[PARTICLES])& (~catBits[PARTICLES]) collisions. //SWAP: 6 sec //HASH: 7.15 sec //QUAD: 41.8 sec //SIMLE: 59 sec printf("ODE conf: %s", dGetConfiguration()); printf("\n:::: sizeof(dReal)=%lu\n\n", sizeof(dReal)); }
// initialize server (supply world dimensions) bool PhysicsServer::init(int groundSizeX, int groundSizeY) { if (groundSizeX <= 20 || groundSizeY <= 20) return false; // create global ODE world _world = dWorldCreate(); // create global space _space = dHashSpaceCreate(0); // create group for handling collisions _contactgroup = dJointGroupCreate (0); // make ground a bit slippery :) _envData.slip = 0.15; // TODO: let user specify ground surface properties // set world properties dWorldSetGravity (_world,0,0,-(PHYS_GRAVITY*PHYS_MASS_SCALE)); dWorldSetERP (_world, 0.6); // create ground and walls (0,0,0 is the ground's center) // and put them in their own space _envSpace = dSimpleSpaceCreate(_space); _ground = dCreatePlane (_envSpace,0, 0, 1, 0); dGeomSetData(_ground, (void*)&_envData); _wall[0] = dCreatePlane(_envSpace, 1, 0, 0, -(groundSizeX/2.0) ); // a,b,c,d _wall[1] = dCreatePlane(_envSpace, -1, 0, 0, -(groundSizeX/2.0) ); // a,b,c,d _wall[2] = dCreatePlane(_envSpace, 0, 1, 0, -(groundSizeY/2.0) ); // a,b,c,d _wall[3] = dCreatePlane(_envSpace, 0, -1, 0, -(groundSizeY/2.0) ); // a,b,c,d return true; }
int main( int argc, char **argv ) { // 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; // create world dInitODE2( 0 ); world = dWorldCreate(); space = dSimpleSpaceCreate( 0 ); contactgroup = dJointGroupCreate( 0 ); dWorldSetGravity( world,0,0,-0.5 ); dWorldSetCFM( world,1e-5 ); dCreatePlane( space,0,0,1,0 ); memset( obj,0,sizeof( obj ) ); // run simulation dsSimulationLoop( argc,argv,352,288,&fn ); dJointGroupDestroy( contactgroup ); dSpaceDestroy( space ); dWorldDestroy( world ); dCloseODE(); return 0; }
int main (int argc, char **argv) { // 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; // create world dInitODE(); world = dWorldCreate(); #if 1 space = dHashSpaceCreate (0); #elif 0 dVector3 center = {0,0,0}, extents = { 100, 100, 100}; space = dQuadTreeSpaceCreate(0, center, extents, 5); #elif 0 space = dSweepAndPruneSpaceCreate (0, dSAP_AXES_XYZ); #else space = dSimpleSpaceCreate(0); #endif contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); dWorldSetCFM (world,1e-5); dWorldSetLinearDamping(world, 0.00001); dWorldSetAngularDamping(world, 0.005); dWorldSetMaxAngularSpeed(world, 200); dWorldSetContactSurfaceLayer (world,0.001); ground = dCreatePlane (space,0,0,1,0); memset (obj,0,sizeof(obj)); // create lift platform platform = dCreateBox(space, 4, 4, 1); dGeomSetCategoryBits(ground, 1ul); dGeomSetCategoryBits(platform, 2ul); dGeomSetCollideBits(ground, ~2ul); dGeomSetCollideBits(platform, ~1ul); // run simulation dsSimulationLoop (argc,argv,352,288,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
int main (int argc, char **argv) { // 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; if(argc==2) { fn.path_to_textures = argv[1]; } // create world dInitODE2(0); world = dWorldCreate(); space = dSimpleSpaceCreate(0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); dWorldSetCFM (world,1e-5); dCreatePlane (space,0,0,1,0); memset (obj,0,sizeof(obj)); // note: can't share tridata if intending to trimesh-trimesh collide TriData1 = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(TriData1, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); TriData2 = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(TriData2, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); TriMesh1 = dCreateTriMesh(space, TriData1, 0, 0, 0); TriMesh2 = dCreateTriMesh(space, TriData2, 0, 0, 0); dGeomSetData(TriMesh1, TriData1); dGeomSetData(TriMesh2, TriData2); {dGeomSetPosition(TriMesh1, 0, 0, 0.9); dMatrix3 Rotation; dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); dGeomSetRotation(TriMesh1, Rotation);} {dGeomSetPosition(TriMesh2, 1, 0, 0.9); dMatrix3 Rotation; dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); dGeomSetRotation(TriMesh2, Rotation);} // run simulation dsSimulationLoop (argc,argv,352,288,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
void CPHShell::PresetActive() { VERIFY(!isActive()); if(!m_space) { m_space=dSimpleSpaceCreate(0); dSpaceSetCleanup(m_space,0); } }
void Robots::criarEspacoRobo(dSpaceID space) { this->robot_space = dSimpleSpaceCreate (space); dSpaceSetCleanup(this->robot_space,0); dSpaceAdd(this->robot_space,this->box[0]); dSpaceAdd(this->robot_space,this->box[1]); dSpaceAdd(this->robot_space,this->cylinder[0]); dSpaceAdd(this->robot_space,this->cylinder[1]); }
WorldManagerServer::WorldManagerServer() { dInitODE(); mWorld = dWorldCreate(); mGlobalSpace = dHashSpaceCreate(0); mContactGroup = dJointGroupCreate(0); dWorldSetGravity(mWorld, 0, -100, 0); mStaticSpace = dSimpleSpaceCreate(mGlobalSpace); }
StaticWorldObject::StaticWorldObject(ssgEntity *model, dSpaceID bigspace, sgVec3 initialpos) : WorldObject(model) { space = dSimpleSpaceCreate(bigspace); ssgTransform *trf = new ssgTransform(); trf->setTransform(initialpos); trf->addKid(model); entity = trf; name = "staticworldobject"; WalkTree(entity, initialpos); }
bool JointInteraction::loadConfig(std::string configFile) { world = dWorldCreate(); space = dSimpleSpaceCreate(0); isGrabbing = false; stepsPerFrame = 50; maxDist = 20; deltaTrans = identityTransformation(); this->configFile = configFile; return true; } // loadConfig
ODESpace::ODESpace() { // Create the Space without adding it to another Space. if (false) mSpaceID = dSimpleSpaceCreate(0); else { mSpaceID = dHashSpaceCreate(0); dHashSpaceSetLevels(mSpaceID, 3, 9); } mParentSpaceID = NULL; }
int main (int argc, char **argv) { static dMass m; dReal mass = 1.0; // set for drawing dsFunctions fn; fn.version = DS_VERSION; fn.start = &start; fn.step = &simLoop; fn.command = NULL; fn.stop = NULL; fn.path_to_textures = "../textures"; dInitODE(); // init ODE world = dWorldCreate(); // create a dynamic world space = dSimpleSpaceCreate (0); //@a box capsule = dBodyCreate (world); geom = dCreateCapsule (space,radius,length); //create geometry. dMassSetCapsule(&m,DENSITY,3,radius,length); dBodySetMass (capsule,&m); dGeomSetBody(geom,capsule); dBodySetPosition (capsule,0,4,1); //Gravedad y cosas de simulacion dWorldSetGravity(world,0,0,-9.81); dWorldSetCFM (world,1e-5); dCreatePlane (space,0,0,1,0); contactgroup = dJointGroupCreate (0); // the simulation dsSimulationLoop (argc,argv,960,480,&fn); //-- Destroy the world!!! dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
ODESimulator::ODESimulator() { timestep = 0; g_ODE_object.Init(); worldID = dWorldCreate(); contactGroupID = dJointGroupCreate(0); //envSpaceID = dHashSpaceCreate(0); //dHashSpaceSetLevels(envSpaceID,-2,1); envSpaceID = dSimpleSpaceCreate(0); dWorldSetERP(worldID,settings.errorReductionParameter); dWorldSetCFM(worldID,settings.dampedLeastSquaresParameter); dWorldSetGravity(worldID,settings.gravity[0],settings.gravity[1],settings.gravity[2]); }
//since this is just the base level construction, we'll just make a sphere (WHOO, EXCITING!!!!) bool Construction::Construct( char* descriptionFile, DynamicsSolver* solver, Screen3D& Screen,MeshManager& MM, Position& Location, ICollisionHandler* ch ) { //deconstruct any old stuff Deconstruct(); //save the solver pointer mySolver = solver; CollisionHandler = ch; //create the body list ObjectList = new DynamicsObject[1]; this->nObjects = 1; //Create the geom group GeomGroup = dSimpleSpaceCreate (solver->GetSpaceID(false)); //dCreateGeomGroup (solver->GetSpaceID(false)); //Create the actual body ( a sphere! ) ObjectList[0].CreateBody( solver ); dBodySetPosition ( ObjectList[0].Body, Location.x, Location.y, Location.z); dMassSetSphere ( &ObjectList[0].Mass, 1.0, 5.0 ); dMassAdjust (&ObjectList[0].Mass, 1.0 ); dBodySetMass( ObjectList[0].Body, &ObjectList[0].Mass); ObjectList[0].Geom = dCreateSphere (0,5.0); dGeomSetData( ObjectList[0].Geom, &ObjectList[0].SurfaceDesc ); dGeomSetBody (ObjectList[0].Geom,ObjectList[0].Body); dSpaceAdd (GeomGroup,ObjectList[0].Geom); ObjectList[0].HasGeom = true; //set owner for(int i=0; i<nObjects; i++) { ObjectList[i].SurfaceDesc.Owner = &ObjectList[i]; ObjectList[i].SurfaceDesc.ParentConstruction = this; ObjectList[i].Owner = this; //ObjectList[i].HasGeom = true; } LinearDisableEpsilon = .1; AngularDisableEpsilon = .01f; //create the mesh for drawing D3DXCreateSphere( Screen.D3DDevice, 5.5f, 10, 10, &DrawMesh, NULL ); return true; }
CDynamics3DEntity::CDynamics3DEntity(CDynamics3DEngine& c_engine, CEmbodiedEntity& c_entity) : CPhysicsEngineEntity(c_entity), m_cEngine(c_engine), m_tEngineWorld(c_engine.GetWorldID()), m_tEngineSpace(c_engine.GetSpaceID()), m_tBody(dBodyCreate(m_tEngineWorld)), m_tEntitySpace(dSimpleSpaceCreate(m_tEngineSpace)) { /* Zero the body mass */ dMassSetZero(&m_tMass); /* * Set the level of the body space * Necessary for dSpaceCollide2 to work properly */ dSpaceSetSublevel(m_tEngineSpace, 1); }
void PhysicsSim::initialize() { dInitODE(); dSetDebugHandler(ode_errorhandler); dSetErrorHandler(ode_errorhandler); dSetMessageHandler(ode_errorhandler); m_odeWorld = dWorldCreate(); dWorldSetGravity (m_odeWorld,0,0,0); m_odeSpace = dSimpleSpaceCreate(0); m_odeContactGroup = dJointGroupCreate(0); /* This is just to track haptics cursor during "grab" state. * We only need its position, so just use a generic OscObject. */ m_pCursor = new OscObject(NULL, "cursor", this); if (!m_pCursor) printf("Error creating PhysicsSim cursor.\n"); Simulation::initialize(); }
bool DynamicsSolver::Init( int spaceDim, Real spaceWidth, Real spaceHeight) { Shutdown(); spaceDim = 1; WorldID = dWorldCreate(); DynamicSpaceID = dHashSpaceCreate(0); ActiveSpaceID = dSimpleSpaceCreate(0); dSpaceSetCleanup ( ActiveSpaceID, 0 ); dSpaceSetCleanup ( DynamicSpaceID, 0 ); SpaceDim = spaceDim; SpaceWidth = spaceWidth; SpaceHeight = spaceHeight; nCachedConstructions = 0; StaticSpaceID = new dSpaceID[spaceDim*spaceDim]; SpaceDist = new int[spaceDim*spaceDim]; for (int i=0; i<spaceDim*spaceDim; i++) { StaticSpaceID[i] = dHashSpaceCreate(0); //dVector3 center = { spaceWidth*.5f, 0, spaceHeight*.5f, 1.0f }; //dVector3 extent = { spaceWidth, 10000, spaceHeight, 1.0f }; //StaticSpaceID[i] = dQuadTreeSpaceCreate(NULL, center, extent, 4); SpaceDist[i] = 0; } ContactGroup = dJointGroupCreate (0); dWorldSetGravity (WorldID,0,-90, 0); //dWorldSetERP (WorldID, 0.9 ); dWorldSetContactSurfaceLayer (WorldID, .01); IsSetup = true; return true; }
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(); // run simulation dsSimulationLoop (argc, argv, 640, 480, &fn); levels = 0; place_cards(); dJointGroupDestroy(contactgroup); dWorldDestroy(world); dGeomDestroy(ground); dSpaceDestroy(space); dCloseODE(); }
void Bola::construir(dWorldID world, dSpaceID space) { // Cria objeto e geometria this->corpo = dBodyCreate(world); this->geometria = dCreateSphere(0,BOLA_RAIO); // Define a posição do objeto dBodySetPosition(this->corpo, this->pegarX(), this->pegarY(), STARTZ); // Define a massa do objeto dMass m; dMassSetSphere(&m,1,BOLA_RAIO); dMassAdjust(&m,BOLA_MASSA); dBodySetMass(this->corpo,&m); // Associa o objeto à geometria dGeomSetBody(this->geometria,this->corpo); // Cria um espaço para a bola e a adiciona this->espaco = dSimpleSpaceCreate(space); dSpaceSetCleanup(this->espaco,0); dSpaceAdd(this->espaco,this->geometria); }
int main (int argc, char **argv) { // 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; if (argc >= 2 ) { for (int i=1; i < argc; ++i) { if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) Help (argv); if ( 0 == strcmp ("-p", argv[i]) || 0 == strcmp ("--PRJoint", argv[i]) ) type = dJointTypePR; if (0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) { int j = i+1; if ( j+1 > argc || // Check if we have enough arguments argv[j] == '\0' || // We should have a path here argv[j][0] == '-' ) // We should have a path not a command line Help (argv); else fn.path_to_textures = argv[++i]; // Increase i since we use this argument } } } dInitODE2(0); world.setERP (0.8); space = dSimpleSpaceCreate (0); contactgroup = dJointGroupCreate (0); geom[GROUND] = dCreatePlane (space, 0,0,1,0); dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); dGeomSetCollideBits (geom[GROUND], catBits[ALL]); dMass m; // Create the body attached to the World body[W].create (world); // Main axis of cylinder is along X=1 m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); m.adjust (Mass1); geom[W] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); dGeomSetBody (geom[W], body[W]); dGeomSetCategoryBits (geom[W], catBits[W]); dGeomSetCollideBits (geom[W], catBits[ALL] & (~catBits[W]) & (~catBits[JOINT]) ); body[W].setMass(m); // Create the dandling body body[D].create(world); // Main axis of capsule is along X=1 m.setBox (1, boxDim[X], boxDim[Y], boxDim[Z]); m.adjust (Mass1); geom[D] = dCreateBox (space, boxDim[X], boxDim[Y], boxDim[Z]); dGeomSetBody (geom[D], body[D]); dGeomSetCategoryBits (geom[D], catBits[D]); dGeomSetCollideBits (geom[D], catBits[ALL] & (~catBits[D]) & (~catBits[JOINT]) ); body[D].setMass(&m); // Create the external part of the slider joint geom[EXT] = dCreateBox (space, extDim[X], extDim[Y], extDim[Z]); dGeomSetCategoryBits (geom[EXT], catBits[EXT]); dGeomSetCollideBits (geom[EXT], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); // Create the internal part of the slider joint geom[INT] = dCreateBox (space, INT_EXT_RATIO*extDim[X], INT_EXT_RATIO*extDim[Y], INT_EXT_RATIO*extDim[Z]); dGeomSetCategoryBits (geom[INT], catBits[INT]); dGeomSetCollideBits (geom[INT], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); dMatrix3 R; dGeomID id; // Create the first axis of the universal joi9nt geom[AXIS1] = dCreateGeomTransform (space); //Rotation of 90deg around y dRFromAxisAndAngle (R, 0,1,0, 0.5*PI); dGeomSetRotation (geom[AXIS1], R); dGeomSetCategoryBits (geom[AXIS1], catBits[AXIS1]); dGeomSetCollideBits (geom[AXIS1], catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); id = geom[AXIS1]; dGeomTransformSetGeom (geom[AXIS1], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the second axis of the universal joint geom[AXIS2] = dCreateGeomTransform (space); //Rotation of 90deg around y dRFromAxisAndAngle (R, 1,0,0, 0.5*PI); dGeomSetRotation (geom[AXIS2], R); dGeomSetCategoryBits (geom[AXIS2], catBits[AXIS2]); dGeomSetCollideBits (geom[AXIS2], catBits[ALL] & ~catBits[JOINT] & ~catBits[W] & ~catBits[D]); id = geom[AXIS2]; dGeomTransformSetGeom (geom[AXIS2], dCreateCylinder (0, axDim[RADIUS], axDim[LENGTH]) ); // Create the anchor geom[ANCHOR] = dCreateBox (space, ancDim[X], ancDim[Y], ancDim[Z]); dGeomSetCategoryBits (geom[ANCHOR], catBits[ANCHOR]); dGeomSetCollideBits (geom[ANCHOR], catBits[ALL] & (~catBits[JOINT]) & (~catBits[W]) & (~catBits[D]) ); if (body[W]) { body[W].setPosition(0, 0, 5); } if (geom[EXT]) { dGeomSetPosition (geom[EXT], 0,0,3.8); } if (geom[INT]) { dGeomSetPosition (geom[INT], 0,0,2.6); } if (geom[AXIS1]) { dGeomSetPosition (geom[AXIS1], 0,0,2.5); } if (geom[AXIS2]) { dGeomSetPosition (geom[AXIS2], 0,0,2.5); } if (geom[ANCHOR]) { dGeomSetPosition (geom[ANCHOR], 0,0,2.25); } if (body[D]) { body[D].setPosition(0,0,1.5); } // Attache the upper box to the world dJointID fixed = dJointCreateFixed (world,0); dJointAttach (fixed , NULL, body[W]); dJointSetFixed (fixed ); if (type == dJointTypePR) { dPRJoint *pr = new dPRJoint (world, 0); pr->attach (body[W], body[D]); pr->setAxis1 (0, 0, -1); pr->setAxis2 (1, 0, 0); joint = pr; dJointSetPRAnchor (pr->id(), 0, 0, 2.5); } else { dPUJoint *pu = new dPUJoint (world, 0); pu->attach (body[W], body[D]); pu->setAxis1 (1, 0, 0); pu->setAxis2 (0, 1, 0); pu->setAxisP (0, 0, -1); joint = pu; dJointSetPUAnchor (pu->id(), 0, 0, 2.5); } // run simulation dsSimulationLoop (argc,argv,400,300,&fn); delete joint; dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
int main (int argc, char **argv) { // 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/textures"; if(argc==2) { fn.path_to_textures = argv[1]; } // create world dInitODE(); world = dWorldCreate(); space = dSimpleSpaceCreate(0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); dWorldSetCFM (world,1e-5); //dCreatePlane (space,0,0,1,0); memset (obj,0,sizeof(obj)); Size[0] = 5.0f; Size[1] = 5.0f; Size[2] = 2.5f; Vertices[0][0] = -Size[0]; Vertices[0][1] = -Size[1]; Vertices[0][2] = Size[2]; Vertices[1][0] = Size[0]; Vertices[1][1] = -Size[1]; Vertices[1][2] = Size[2]; Vertices[2][0] = Size[0]; Vertices[2][1] = Size[1]; Vertices[2][2] = Size[2]; Vertices[3][0] = -Size[0]; Vertices[3][1] = Size[1]; Vertices[3][2] = Size[2]; Vertices[4][0] = 0; Vertices[4][1] = 0; Vertices[4][2] = 0; Indices[0] = 0; Indices[1] = 1; Indices[2] = 4; Indices[3] = 1; Indices[4] = 2; Indices[5] = 4; Indices[6] = 2; Indices[7] = 3; Indices[8] = 4; Indices[9] = 3; Indices[10] = 0; Indices[11] = 4; dTriMeshDataID Data = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount); TriMesh = dCreateTriMesh(space, Data, 0, 0, 0); //dGeomSetPosition(TriMesh, 0, 0, 1.0); Ray = dCreateRay(space, 0.9); dVector3 Origin, Direction; Origin[0] = 0.0; Origin[1] = 0; Origin[2] = 0.5; Origin[3] = 0; Direction[0] = 0; Direction[1] = 1.1f; Direction[2] = -1; Direction[3] = 0; dNormalize3(Direction); dGeomRaySet(Ray, Origin[0], Origin[1], Origin[2], Direction[0], Direction[1], Direction[2]); // run simulation dsSimulationLoop (argc,argv,352,288,&fn); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
int main (int argc, char **argv) { dInitODE2(0); bool fixed = true; // 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; dVector3 offset; dSetZero (offset, 4); // Default test case if (argc >= 2 ) { for (int i=1; i < argc; ++i) { //static int tata = 0; if (1) { if ( 0 == strcmp ("-h", argv[i]) || 0 == strcmp ("--help", argv[i]) ) Help (argv); if ( 0 == strcmp ("-s", argv[i]) || 0 == strcmp ("--slider", argv[i]) ) type = dJointTypeSlider; if ( 0 == strcmp ("-t", argv[i]) || 0 == strcmp ("--texture-path", argv[i]) ) { int j = i+1; if ( j+1 > argc || // Check if we have enough arguments argv[j] == '\0' || // We should have a path here argv[j][0] == '-' ) // We should have a path not a command line Help (argv); else fn.path_to_textures = argv[++i]; // Increase i since we use this argument } } if ( 0 == strcmp ("-1", argv[i]) || 0 == strcmp ("--offset1", argv[i]) ) tc = 1; if ( 0 == strcmp ("-2", argv[i]) || 0 == strcmp ("--offset2", argv[i]) ) tc = 2; if ( 0 == strcmp ("-3", argv[i]) || 0 == strcmp ("--offset3", argv[i]) ) tc = 3; if (0 == strcmp ("-n", argv[i]) || 0 == strcmp ("--notFixed", argv[i]) ) fixed = false; } } world = dWorldCreate(); dWorldSetERP (world, 0.8); space = dSimpleSpaceCreate (0); contactgroup = dJointGroupCreate (0); geom[GROUND] = dCreatePlane (space, 0,0,1,0); dGeomSetCategoryBits (geom[GROUND], catBits[GROUND]); dGeomSetCollideBits (geom[GROUND], catBits[ALL]); dMass m; dMatrix3 R; // Create the Obstacle geom[OBS] = dCreateBox (space, OBS_SIDES[0], OBS_SIDES[1], OBS_SIDES[2]); dGeomSetCategoryBits (geom[OBS], catBits[OBS]); dGeomSetCollideBits (geom[OBS], catBits[ALL]); //Rotation of 45deg around y dRFromAxisAndAngle (R, 1,1,0, -0.25*PI); dGeomSetRotation (geom[OBS], R); dGeomSetPosition (geom[OBS], 1.95, -0.2, 0.5); //Rotation of 90deg around y // Will orient the Z axis along X dRFromAxisAndAngle (R, 0,1,0, -0.5*PI); // Create Body2 (Wiil be attached to the world) body[BODY2] = dBodyCreate (world); // Main axis of cylinder is along X=1 dMassSetBox (&m, 1, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); dMassAdjust (&m, Mass1); geom[BODY2] = dCreateBox (space, BODY2_SIDES[0], BODY2_SIDES[1], BODY2_SIDES[2]); dGeomSetBody (geom[BODY2], body[BODY2]); dGeomSetOffsetRotation (geom[BODY2], R); dGeomSetCategoryBits (geom[BODY2], catBits[BODY2]); dGeomSetCollideBits (geom[BODY2], catBits[ALL] & (~catBits[BODY1]) ); dBodySetMass (body[BODY2], &m); // Create Body 1 (Slider on the prismatic axis) body[BODY1] = dBodyCreate (world); // Main axis of capsule is along X=1 dMassSetCapsule (&m, 1, 1, RADIUS, BODY1_LENGTH); dMassAdjust (&m, Mass1); geom[BODY1] = dCreateCapsule (space, RADIUS, BODY1_LENGTH); dGeomSetBody (geom[BODY1], body[BODY1]); dGeomSetOffsetRotation (geom[BODY1], R); dGeomSetCategoryBits (geom[BODY1], catBits[BODY1]); dGeomSetCollideBits (geom[BODY1], catBits[ALL] & ~catBits[BODY2] & ~catBits[RECT]); dMass mRect; dMassSetBox (&mRect, 1, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); dMassAdd (&m, &mRect); // TODO: translate m? geom[RECT] = dCreateBox (space, RECT_SIDES[0], RECT_SIDES[1], RECT_SIDES[2]); dGeomSetBody (geom[RECT], body[BODY1]); dGeomSetOffsetPosition (geom[RECT], (BODY1_LENGTH-RECT_SIDES[0]) /2.0, 0.0, -RADIUS -RECT_SIDES[2]/2.0); dGeomSetCategoryBits (geom[RECT], catBits[RECT]); dGeomSetCollideBits (geom[RECT], catBits[ALL] & (~catBits[BODY1]) ); dBodySetMass (body[BODY1], &m); setPositionBodies (tc); if ( fixed ) { // Attache external cylinder to the world dJointID fixed = dJointCreateFixed (world,0); dJointAttach (fixed , NULL, body[BODY2]); dJointSetFixed (fixed ); dWorldSetGravity (world,0,0,-0.8); } else { dWorldSetGravity (world,0,0,0); } // The static is here only to help debugging switch (type) { case dJointTypeSlider : { dSliderJoint *sj = new dSliderJoint (world, 0); sj->attach (body[BODY1], body[BODY2]); sj->setAxis (1, 0, 0); joint = sj; } break; case dJointTypePiston : // fall through default default: { dPistonJoint *pj = new dPistonJoint (world, 0); pj->attach (body[BODY1], body[BODY2]); pj->setAxis (1, 0, 0); dJointSetPistonAnchor(pj->id(), anchor[X], anchor[Y], anchor[Z]); joint = pj; } break; }; // run simulation dsSimulationLoop (argc,argv,400,300,&fn); delete joint; dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
void Level::load_level(string file) { ifstream fin(file.c_str()); cout << "Reading " << file << endl; literal(fin, "left"); fin >> left; literal(fin, "bottom"); fin >> bottom; literal(fin, "right"); fin >> right; literal(fin, "top"); fin >> top; vec p1pos, p2pos; literal(fin, "p1"); fin >> p1pos.x >> p1pos.y; literal(fin, "p2"); fin >> p2pos.x >> p2pos.y; num gravity; literal(fin, "gravity"); fin >> gravity; literal(fin, "ropes"); fin >> max_ropes; literal(fin, "gunspeed"); fin >> fire_velocity; int boxes; literal(fin, "boxes"); fin >> boxes; list<BoxDef> boxen; for (int i = 0; i < boxes; i++) { BoxDef bx; literal(fin, "box"); fin >> bx.ll.x >> bx.ll.y >> bx.ur.x >> bx.ur.y; boxen.push_back(bx); } cout << "Building level\n"; world = dWorldCreate(); dWorldSetGravity(world, 0, -gravity, 0); collide_space = dSimpleSpaceCreate(0); contact_joints = dJointGroupCreate(0); manager = new ObjectManager; p1 = new Player(p1pos, Color(0,0,1)); manager->add(p1); p2 = new Player(p2pos, Color(1,0,0)); manager->add(p2); for (list<BoxDef>::iterator i = boxen.begin(); i != boxen.end(); ++i) { manager->add(new Wall(i->ll, i->ur)); } set_view(); player = P1_SCORE <= P2_SCORE ? p1 : p2; stepct_ = 5*int(1/STEP); }
WorldPhysics::WorldPhysics() { enable_complex=0; bulldozer_state=1; tmp_scalar=0; tmp_wait=0; qsrand(QTime::currentTime().msec()); dInitODE(); world = dWorldCreate(); space = dHashSpaceCreate (0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-9.81); //ground_cheat = dCreatePlane (space,0,0,1,0); wall1=dCreatePlane (space,-1,0,0,-100); wall2=dCreatePlane (space,1,0,0,0); wall3=dCreatePlane (space,0,-1,0,-100); wall4=dCreatePlane (space,0,1,0,0); // our heightfield floor dHeightfieldDataID heightid = dGeomHeightfieldDataCreate(); // Create an finite heightfield. dGeomHeightfieldDataBuildCallback( heightid, NULL, near_heightfield_callback, HFIELD_WIDTH, HFIELD_DEPTH, HFIELD_WSTEP, HFIELD_DSTEP, REAL( 1.0 ), REAL( 0.0 ), REAL( 0.0 ), 0 ); // Give some very bounds which, while conservative, // makes AABB computation more accurate than +/-INF. //dGeomHeightfieldDataSetBounds( heightid, REAL( -4.0 ), REAL( +6.0 ) ); gheight = dCreateHeightfield( space, heightid, 1 ); // Rotate so Z is up, not Y (which is the default orientation) dMatrix3 R; dRSetIdentity( R ); dRFromAxisAndAngle( R, 1, 0, 0, DEGTORAD * 90 ); dGeomSetRotation( gheight, R ); dGeomSetPosition( gheight, 50,50,0 ); // for (int i=0;i<MAX_ITEMS;i++) { // items.push_back(generateItem()); //} generateItems(); bulldozer_space = dSimpleSpaceCreate(space); dSpaceSetCleanup (bulldozer_space,0); bulldozer=new BoxItem(world,bulldozer_space,LENGTH,WIDTH,HEIGHT,CMASS); bulldozer->setPosition(STARTX,STARTY,STARTZ); bulldozer_cabin=new BoxItem(world,bulldozer_space,LENGTH/2,WIDTH/2,2*HEIGHT,CMASS/3); bulldozer_cabin->setPosition(-LENGTH/4+STARTX,STARTY,3.0/2.0*HEIGHT+STARTZ); bulldozer_bucket_c=new BoxItem(world,bulldozer_space,BUCKET_LENGTH,BUCKET_WIDTH,BUCKET_HEIGHT,CMASS/10); bulldozer_bucket_c->setPosition(LENGTH/2+BUCKET_LENGTH/2+RADIUS+STARTX,STARTY,STARTZ); bulldozer_bucket_l=new BoxItem(world,bulldozer_space,BUCKET_WIDTH/5,BUCKET_LENGTH,BUCKET_HEIGHT,CMASS/20); bulldozer_bucket_l->setPosition(LENGTH/2+BUCKET_LENGTH+RADIUS+BUCKET_WIDTH/10+STARTX,-BUCKET_WIDTH/2+BUCKET_LENGTH/2+STARTY,STARTZ); bulldozer_bucket_r=new BoxItem(world,bulldozer_space,BUCKET_WIDTH/5,BUCKET_LENGTH,BUCKET_HEIGHT,CMASS/20); bulldozer_bucket_r->setPosition(LENGTH/2+BUCKET_LENGTH+RADIUS+BUCKET_WIDTH/10+STARTX,BUCKET_WIDTH/2-BUCKET_LENGTH/2+STARTY,STARTZ); for (int i=0; i<4; i++) { dQuaternion q; dQFromAxisAndAngle(q,1,0,0,M_PI*0.5); wheels[i] = new WheelItem(world,bulldozer_space,q,RADIUS,WMASS); } dBodySetPosition (wheels[0]->body,0.5*LENGTH+STARTX,WIDTH*0.5+STARTY,STARTZ-HEIGHT*0.5); dBodySetPosition (wheels[1]->body,0.5*LENGTH+STARTX,-WIDTH*0.5+STARTY,STARTZ-HEIGHT*0.5); dBodySetPosition (wheels[2]->body,-0.5*LENGTH+STARTX, WIDTH*0.5+STARTY,STARTZ-HEIGHT*0.5); dBodySetPosition (wheels[3]->body,-0.5*LENGTH+STARTX,-WIDTH*0.5+STARTY,STARTZ-HEIGHT*0.5); cabin_joint=dJointCreateSlider(world,0); dJointAttach(cabin_joint,bulldozer->body,bulldozer_cabin->body); dJointSetSliderAxis(cabin_joint,0,0,1); dJointSetSliderParam(cabin_joint,dParamLoStop,0); dJointSetSliderParam(cabin_joint,dParamHiStop,0); bucket_joint_c=dJointCreateSlider(world,0); dJointAttach(bucket_joint_c,bulldozer->body,bulldozer_bucket_c->body); dJointSetSliderAxis(bucket_joint_c,0,0,1); dJointSetSliderParam(bucket_joint_c,dParamLoStop,0); dJointSetSliderParam(bucket_joint_c,dParamHiStop,0); bucket_joint_l=dJointCreateSlider(world,0); dJointAttach(bucket_joint_l,bulldozer->body,bulldozer_bucket_l->body); dJointSetSliderAxis(bucket_joint_l,0,0,1); dJointSetSliderParam(bucket_joint_l,dParamLoStop,0); dJointSetSliderParam(bucket_joint_l,dParamHiStop,0); bucket_joint_r=dJointCreateSlider(world,0); dJointAttach(bucket_joint_r,bulldozer->body,bulldozer_bucket_r->body); dJointSetSliderAxis(bucket_joint_r,0,0,1); dJointSetSliderParam(bucket_joint_r,dParamLoStop,0); dJointSetSliderParam(bucket_joint_r,dParamHiStop,0); // front and back wheel hinges for (int i=0; i<4; i++) { wheelJoints[i] = dJointCreateHinge2 (world,0); dJointAttach (wheelJoints[i],bulldozer->body,wheels[i]->body); const dReal *a = dBodyGetPosition (wheels[i]->body); dJointSetHinge2Anchor (wheelJoints[i],a[0],a[1],a[2]); dJointSetHinge2Axis1 (wheelJoints[i],0,0,1); dJointSetHinge2Axis2 (wheelJoints[i],0,1,0); } // seeting ERP & CRM for (int i=0; i<4; i++) { dJointSetHinge2Param (wheelJoints[i],dParamSuspensionERP,0.5); dJointSetHinge2Param (wheelJoints[i],dParamSuspensionCFM,0.8); } // block back axis !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! for (int i=0; i<2; i++) { dJointSetHinge2Param (wheelJoints[i],dParamLoStop,0); dJointSetHinge2Param (wheelJoints[i],dParamHiStop,0); } }
int main (int argc, char **argv) { // 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; // create world dInitODE2(0); world = dWorldCreate(); space = dSimpleSpaceCreate(0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); dWorldSetCFM (world,1e-5); //dCreatePlane (space,0,0,1,0); memset (obj,0,sizeof(obj)); Size[0] = 5.0f; Size[1] = 5.0f; Size[2] = 2.5f; Vertices[0][0] = -Size[0]; Vertices[0][1] = -Size[1]; Vertices[0][2] = Size[2]; Vertices[1][0] = Size[0]; Vertices[1][1] = -Size[1]; Vertices[1][2] = Size[2]; Vertices[2][0] = Size[0]; Vertices[2][1] = Size[1]; Vertices[2][2] = Size[2]; Vertices[3][0] = -Size[0]; Vertices[3][1] = Size[1]; Vertices[3][2] = Size[2]; Vertices[4][0] = 0; Vertices[4][1] = 0; Vertices[4][2] = 0; Indices[0] = 0; Indices[1] = 1; Indices[2] = 4; Indices[3] = 1; Indices[4] = 2; Indices[5] = 4; Indices[6] = 2; Indices[7] = 3; Indices[8] = 4; Indices[9] = 3; Indices[10] = 0; Indices[11] = 4; dTriMeshDataID Data = dGeomTriMeshDataCreate(); //dGeomTriMeshDataBuildSimple(Data, (dReal*)Vertices, VertexCount, Indices, IndexCount); dGeomTriMeshDataBuildSingle(Data, Vertices[0], 3 * sizeof(float), VertexCount, &Indices[0], IndexCount, 3 * sizeof(dTriIndex)); dGeomTriMeshDataPreprocess2(Data, (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES), NULL); TriMesh = dCreateTriMesh(space, Data, 0, 0, 0); //dGeomSetPosition(TriMesh, 0, 0, 1.0); Ray = dCreateRay(space, 0.9); dVector3 Origin, Direction; Origin[0] = 0.0; Origin[1] = 0; Origin[2] = 0.5; Origin[3] = 0; Direction[0] = 0; Direction[1] = 1.1f; Direction[2] = -1; Direction[3] = 0; dNormalize3(Direction); dGeomRaySet(Ray, Origin[0], Origin[1], Origin[2], Direction[0], Direction[1], Direction[2]); 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,352,288,&fn); dThreadingImplementationShutdownProcessing(threading); dThreadingFreeThreadPool(pool); dWorldSetStepThreadingImplementation(world, NULL, NULL); dThreadingFreeImplementation(threading); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
int main (int argc, char **argv) { // 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; // create world dInitODE2(0); world = dWorldCreate(); space = dSimpleSpaceCreate(0); contactgroup = dJointGroupCreate (0); dWorldSetGravity (world,0,0,-0.5); dWorldSetCFM (world,1e-5); dCreatePlane (space,0,0,1,0); memset (obj,0,sizeof(obj)); // note: can't share tridata if intending to trimesh-trimesh collide const unsigned preprocessFlags = (1U << dTRIDATAPREPROCESS_BUILD_CONCAVE_EDGES) | (1U << dTRIDATAPREPROCESS_BUILD_FACE_ANGLES); TriData1 = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(TriData1, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); dGeomTriMeshDataPreprocess2(TriData1, preprocessFlags, NULL); TriData2 = dGeomTriMeshDataCreate(); dGeomTriMeshDataBuildSingle(TriData2, &Vertices[0], 3 * sizeof(float), VertexCount, (dTriIndex*)&Indices[0], IndexCount, 3 * sizeof(dTriIndex)); dGeomTriMeshDataPreprocess2(TriData2, preprocessFlags, NULL); TriMesh1 = dCreateTriMesh(space, TriData1, 0, 0, 0); TriMesh2 = dCreateTriMesh(space, TriData2, 0, 0, 0); dGeomSetData(TriMesh1, TriData1); dGeomSetData(TriMesh2, TriData2); {dGeomSetPosition(TriMesh1, 0, 0, 0.9); dMatrix3 Rotation; dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); dGeomSetRotation(TriMesh1, Rotation);} {dGeomSetPosition(TriMesh2, 1, 0, 0.9); dMatrix3 Rotation; dRFromAxisAndAngle(Rotation, 1, 0, 0, M_PI / 2); dGeomSetRotation(TriMesh2, Rotation);} 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,352,288,&fn); dThreadingImplementationShutdownProcessing(threading); dThreadingFreeThreadPool(pool); dWorldSetStepThreadingImplementation(world, NULL, NULL); dThreadingFreeImplementation(threading); dJointGroupDestroy (contactgroup); dSpaceDestroy (space); dWorldDestroy (world); dCloseODE(); return 0; }
dSpaceID Space::addSimpleSpace(){ return dSimpleSpaceCreate(space); }