00001
00002 #ifndef INCLUDED_PhysicsWorld_h_
00003 #define INCLUDED_PhysicsWorld_h_
00004
00005 #include "Shared/plist.h"
00006 #include "Motion/KinematicJoint.h"
00007 #include <map>
00008 #include <set>
00009
00010 class PhysicsBody;
00011 class MotorController;
00012 class btPoint2PointConstraint;
00013
00014
00015 class PhysicsWorld : public virtual plist::Dictionary {
00016 friend class PhysicsBody;
00017 friend class PhysicsState;
00018 public:
00019 PhysicsWorld()
00020 : plist::Dictionary(), gravity(-9.80665f), spaceScale(0.01f), massScale(1), solverIter(250),
00021 erp(0.25f), splitImpulse(false), linearDamping(0), angularDamping(0), collisionMargin(1),
00022 collisionConfiguration(NULL), dispatcher(NULL), broadphase(NULL), solver(NULL), dynamicsWorld(NULL), filter(NULL),
00023 bodies(), motorControllers(),
00024 gravityListener(gravity,*this,&PhysicsWorld::updateGravity,false),
00025 spaceScaleListener(spaceScale,*this,&PhysicsWorld::updateGravity,false),
00026 solverIterListener(solverIter,*this,&PhysicsWorld::updateSolverInfo,false),
00027 erpListener(erp,*this,&PhysicsWorld::updateSolverInfo,false)
00028 {
00029 addEntry("Gravity",gravity,"Controls the force of gravity along z vector in meters per second. (default -9.80665)");
00030 addEntry("SpaceScale",spaceScale,"Controls a spatial scaling factor for simulation stability, applied to millimeter scale used for graphics. (default 0.01, i.e. 10cm internal base unit for physics)");
00031 addEntry("MassScale",massScale,"Controls an inertial scaling factor for simulation stability, applied to kilogram scale (default 1, i.e. internal base unit of 1 kilogram for physics)");
00032 addEntry("SolverIterations",solverIter,"Maximum number of iterations for the constraint solver.\nIncreasing this will resolve 'breaking' constraints, such as servos under load");
00033 addEntry("ERP",erp,"Error resolution proportion, analgous to gradient descent step size.\nLarger values can help reduce solver iterations, but can cause jitter/instability if too high");
00034 addEntry("SplitImpulse",splitImpulse,"Causes the physics engine to solve for linear and angular constraints independently.");
00035 addEntry("LinearDamping",linearDamping,"The amount of damping to apply on translational motion.\nThis is a default value applied at object creation, run-time modification won't affect current objects.");
00036 addEntry("AngularDamping",angularDamping,"The amount of damping to apply on rotational motion.\nThis is a default value applied at object creation, run-time modification won't affect current objects.");
00037 addEntry("CollisionMargin",collisionMargin,"The collision margin (in mm) to apply to shapes to handle minor perterbations more efficiently.\nThis is a default value applied at object creation.");
00038 setLoadSavePolicy(FIXED,SYNC);
00039 initWorld();
00040 }
00041 ~PhysicsWorld();
00042
00043 plist::Primitive<float> gravity;
00044 plist::Primitive<float> spaceScale;
00045 plist::Primitive<float> massScale;
00046 plist::Primitive<unsigned int> solverIter;
00047 plist::Primitive<float> erp;
00048 plist::Primitive<bool> splitImpulse;
00049 plist::Primitive<float> linearDamping;
00050 plist::Primitive<float> angularDamping;
00051 plist::Primitive<float> collisionMargin;
00052
00053 size_t step(float t);
00054 size_t step(float t, float freq) { return step(t, static_cast<unsigned int>(t/freq)+1, freq); }
00055 size_t step(float t, unsigned int max, float freq);
00056
00057 PhysicsBody* getBody(const LinkComponent& info);
00058 class btDiscreteDynamicsWorld& getWorld() { return *dynamicsWorld; }
00059
00060 typedef btPoint2PointConstraint PointConstraint;
00061 PointConstraint* addPointConstraint(PhysicsBody* body, const fmat::Column<3>& worldPt);
00062 void removeConstraint(PointConstraint* cn);
00063
00064 typedef std::map<LinkComponent*, PhysicsBody*>::const_iterator body_iterator;
00065 body_iterator begin() const { return bodies.begin(); }
00066 body_iterator end() const { return bodies.end(); }
00067
00068 void updateControllers(float t);
00069
00070 protected:
00071 class btDefaultCollisionConfiguration* collisionConfiguration;
00072 class btCollisionDispatcher* dispatcher;
00073 class btBroadphaseInterface* broadphase;
00074 class btSequentialImpulseConstraintSolver* solver;
00075 class btDiscreteDynamicsWorld* dynamicsWorld;
00076
00077 class CollisionFilter* filter;
00078
00079 void initWorld();
00080 void updateGravity();
00081 void updateSolverInfo();
00082
00083 std::map<LinkComponent*, PhysicsBody*> bodies;
00084 std::set<MotorController*> motorControllers;
00085
00086
00087 plist::PrimitiveCallbackMember<PhysicsWorld> gravityListener;
00088 plist::PrimitiveCallbackMember<PhysicsWorld> spaceScaleListener;
00089 plist::PrimitiveCallbackMember<PhysicsWorld> solverIterListener;
00090 plist::PrimitiveCallbackMember<PhysicsWorld> erpListener;
00091
00092 private:
00093 PhysicsWorld(const PhysicsWorld&);
00094 PhysicsWorld& operator=(const PhysicsWorld&);
00095 };
00096
00097
00098
00099
00100
00101
00102 #endif