#ifndef ODEWORLD_H #define ODEWORLD_H #include #include #include #include #include "refptr/refptr.h" #ifdef DEBUG_AMOTOR #include using namespace std; #endif class OdeWorld { public: enum GeomType { BOX, SPHERE, PLANE, CYLINDER, CAPSULE }; class Object { public: Object(bool is_static, OdeWorld * ode_world, dWorldID world, dSpaceID space, float scale = 1.0f); Object(const Object & orig); ~Object(); void setPosition(double x, double y, double z); void getPosition(double * x, double * y, double * z); void setRotation(dReal x, dReal y, dReal z); const dReal * getPosition(); const dReal * getRotation(); bool addBox(refptr< std::vector > args); bool addSphere(refptr< std::vector > args); bool addCylinder(refptr< std::vector > args); bool addCapsule(refptr< std::vector > args); bool addPlane(refptr< std::vector > args); void addForce(dReal fx, dReal fy, dReal fz); void addForceRel(dReal fx, dReal fy, dReal fz); void addTorque(dReal fx, dReal fy, dReal fz); void addTorqueRel(dReal fx, dReal fy, dReal fz); void finalize(); dReal getMass() { return m_mass.mass; } void setMass(dReal newmass); void enableBody(); dBodyID getBody() { return m_body; } void setGravityMode(bool enabled) { if (m_body != 0) { dBodySetGravityMode(m_body, enabled); } } void setUserData(void * user_data) { m_user_data = user_data; } void * getUserData() { return m_user_data; } std::vector & getGeoms() { return m_geoms; } protected: bool m_is_static; dBodyID m_body; dMass m_mass; dWorldID m_world; dSpaceID m_space; std::vector m_geoms; float m_scale; dReal m_position[3]; dReal m_rotation[12]; OdeWorld * m_ode_world; void * m_user_data; void setupGeom(dGeomID geom, dMass * mass, float locx, float locy, float locz, float rotx, float roty, float rotz); dGeomID cloneGeom(dGeomID geom, dBodyID body); }; class PickedObject { public: Object * obj; float dist; float pos[3]; float normal[3]; PickedObject(dGeomID geom, dContactGeom & contact) { obj = (Object *) dGeomGetData(geom); dist = contact.depth; pos[0] = contact.pos[0]; pos[1] = contact.pos[1]; pos[2] = contact.pos[2]; normal[0] = contact.normal[0]; normal[1] = contact.normal[1]; normal[2] = contact.normal[2]; } }; typedef refptr PickedObjectRef; OdeWorld(); ~OdeWorld(); Object * createObject(bool is_static, float scale = 1.0f); void setGravity(float x, float y, float z) { dWorldSetGravity(m_world, x, y, z); enableAllBodies(); } void step(); void enableAllBodies(); dWorldID getWorldID() { return m_world; } dJointID createAMotor(dBodyID b1, dBodyID b2); dJointID createHinge(dBodyID b1, dBodyID b2, dReal anchor_x, dReal anchor_y, dReal anchor_z, dReal axis_x, dReal axis_y, dReal axis_z); void setAMotorNumAxes(dJointID j, int num_axes) { #ifdef DEBUG_AMOTOR cout << "num axes: " << num_axes << endl; #endif dJointSetAMotorNumAxes(j, num_axes); } void setAMotorAngle(dJointID j, int anum, dReal val) { #ifdef DEBUG_AMOTOR cout << "angle: " << val << endl; #endif dJointSetAMotorAngle(j, anum, val); } void setAMotorAxis(dJointID j, int anum, int rel, dReal x, dReal y, dReal z) { #ifdef DEBUG_AMOTOR cout << "axis: " << anum << ", " << rel << ", (" << x << ", " << y << ", " << z << ")" << endl; #endif dJointSetAMotorAxis(j, anum, rel, x, y, z); } void setAMotorLoStop(dJointID j, dReal val) { #ifdef DEBUG_AMOTOR cout << "lo stop: " << val << endl; #endif dJointSetAMotorParam(j, dParamLoStop, val); } void setAMotorHiStop(dJointID j, dReal val) { #ifdef DEBUG_AMOTOR cout << "hi stop: " << val << endl; #endif dJointSetAMotorParam(j, dParamHiStop, val); } void setAMotorVel(dJointID j, dReal val) { #ifdef DEBUG_AMOTOR cout << "vel: " << val << endl; #endif dJointSetAMotorParam(j, dParamVel, val); } void setAMotorFMax(dJointID j, dReal val) { #ifdef DEBUG_AMOTOR cout << "fmax: " << val << endl; #endif dJointSetAMotorParam(j, dParamFMax, val); } void setAMotorBounce(dJointID j, dReal val) { #ifdef DEBUG_AMOTOR cout << "bounce: " << val << endl; #endif dJointSetAMotorParam(j, dParamBounce, val); } refptr< std::vector > pickObjects( float start_x, float start_y, float start_z, float dir_x, float dir_y, float dir_z); PickedObjectRef pickOne( float start_x, float start_y, float start_z, float dir_x, float dir_y, float dir_z, Object * o); friend void OdeWorld_collide_callback(void * data, dGeomID o1, dGeomID o2); friend void OdeWorld_pick_collide_callback(void * data, dGeomID o1, dGeomID o2); static void pushTransform(const dReal * pos, const dReal * R); protected: dBodyID createBody(); void destroyBody(dBodyID body); dWorldID m_world; dSpaceID m_space; dJointGroupID m_contactJointGroup; std::map m_bodies; dGeomID m_pick_ray; std::vector< refptr > m_pick_points; }; #endif