[1919] | 1 | /* |
---|
| 2 | PhysicsFrameListener.h |
---|
| 3 | |
---|
| 4 | A very simple wrapper class for ODE |
---|
| 5 | primarily for the example car application |
---|
| 6 | */ |
---|
| 7 | #ifndef _PHYSICSFRAMELISTENER_H_ |
---|
| 8 | #define _PHYSICSFRAMELISTENER_H_ |
---|
| 9 | |
---|
[1923] | 10 | #include "OgreOdePreReqs.h" |
---|
| 11 | #include <OgreSceneQuery.h> |
---|
| 12 | #include <OgreFrameListener.h> |
---|
| 13 | |
---|
[1919] | 14 | // Uncomment this if you're planning to use the Plane2D joint |
---|
| 15 | // But you'll have to have modified ODE first! |
---|
| 16 | // #define INCLUDE_PLANE2D_JOINT |
---|
| 17 | |
---|
| 18 | /* |
---|
| 19 | A physical thing |
---|
| 20 | */ |
---|
[1923] | 21 | class PhysicalThing : public Ogre::RaySceneQueryListener |
---|
[1919] | 22 | { |
---|
| 23 | public: |
---|
| 24 | // Doesn't actually do anything |
---|
| 25 | PhysicalThing(dSpace *space); |
---|
| 26 | ~PhysicalThing(void); |
---|
| 27 | |
---|
| 28 | // Just create geoms |
---|
[1923] | 29 | void makePlane(Ogre::Real a, Ogre::Real b, Ogre::Real c, Ogre::Real d); // Plane |
---|
| 30 | void makeBox(Ogre::Real x, Ogre::Real y, Ogre::Real z, Ogre::Real lx, Ogre::Real ly, Ogre::Real lz); // Box |
---|
| 31 | void makeSphere(Ogre::Real x, Ogre::Real y, Ogre::Real z, Ogre::Real r); // Sphere |
---|
[1919] | 32 | |
---|
| 33 | // Create bodies and geoms |
---|
[1923] | 34 | void makePlane(dWorld *world, Ogre::SceneNode *node); |
---|
| 35 | void makeBox(dWorld *world, Ogre::SceneNode *node, Ogre::Real mass = 1, Ogre::Vector3 const &offs = Ogre::Vector3(0,0,0)); |
---|
| 36 | void makeSphere(dWorld *world, Ogre::SceneNode *node, Ogre::Real mass = 1); |
---|
| 37 | void makeTerrainTriMesh(dWorld *world, Ogre::SceneManager *mgr, Ogre::Real grid_size, Ogre::Real grid_spacing); |
---|
[1919] | 38 | |
---|
| 39 | // Callback functions for the ray scene query functionality |
---|
[1923] | 40 | virtual bool queryResult(Ogre::SceneQuery::WorldFragment *fragment, Ogre::Real distance); |
---|
| 41 | virtual bool queryResult(Ogre::MovableObject *obj, Ogre::Real distance); |
---|
[1919] | 42 | |
---|
| 43 | // Update the position and orientation of the scene node we're controlling |
---|
| 44 | void update(void); |
---|
| 45 | |
---|
| 46 | // Utility functions to get at internal stuff |
---|
[1923] | 47 | Ogre::SceneNode *getNode(void); |
---|
[1919] | 48 | dBodyID getBodyID(void); |
---|
| 49 | dSpaceID getSpaceID(void); |
---|
| 50 | |
---|
| 51 | protected: |
---|
| 52 | dGeom *_geom; |
---|
| 53 | dBody *_body; |
---|
| 54 | dSpace *_space; |
---|
[1923] | 55 | Ogre::SceneNode *_node; |
---|
[1919] | 56 | |
---|
[1923] | 57 | std::list<Ogre::Vector3> _frag; |
---|
[1919] | 58 | |
---|
| 59 | dVector3 *_vertices; |
---|
| 60 | int *_indices; |
---|
| 61 | }; |
---|
| 62 | |
---|
| 63 | /* |
---|
| 64 | A Frame listener that implements the physics |
---|
| 65 | */ |
---|
[1923] | 66 | class PhysicsFrameListener : public Ogre::FrameListener |
---|
[1919] | 67 | { |
---|
| 68 | protected: |
---|
| 69 | // All the stuff we need for ODE |
---|
| 70 | dWorld *world; |
---|
| 71 | dHashSpace *space; |
---|
| 72 | dJointGroup *contactgroup; |
---|
| 73 | dSpace *current_space; |
---|
| 74 | bool paused; |
---|
| 75 | |
---|
| 76 | // Keep track of anything we've created |
---|
| 77 | std::list<PhysicalThing*> things; |
---|
| 78 | std::list<dSimpleSpace*> spaces; |
---|
| 79 | std::list<dJoint*> joints; |
---|
| 80 | |
---|
| 81 | // Adjustable variables |
---|
[1923] | 82 | Ogre::Real total_time,step_size; |
---|
| 83 | Ogre::Real k_spring,k_damper,k_tyre,k_mu,k_erp,k_cfm; |
---|
[1919] | 84 | |
---|
| 85 | // Utility function to find the physical thing associated with an Ogre scene node |
---|
[1923] | 86 | dBodyID getBodyID(Ogre::SceneNode *node); |
---|
[1919] | 87 | |
---|
| 88 | public: |
---|
| 89 | // Standard constructor/destructor |
---|
| 90 | PhysicsFrameListener(void); |
---|
| 91 | ~PhysicsFrameListener(void); |
---|
| 92 | |
---|
| 93 | // Tell us when every frame's about to be started |
---|
[1923] | 94 | bool frameStarted(const Ogre::FrameEvent& evt); |
---|
[1919] | 95 | void pause(bool p = true); |
---|
| 96 | |
---|
| 97 | // Mainly so we can access internal stuff from the collision callback |
---|
| 98 | dWorld *getWorld(void){return world;}; |
---|
| 99 | dSpace *getSpace(void){return space;}; |
---|
| 100 | dJointGroup *getContactGroup(void){return contactgroup;}; |
---|
| 101 | |
---|
| 102 | // Create things manually, no physical bodies |
---|
| 103 | // so they won't move, but things will collide with them |
---|
[1923] | 104 | PhysicalThing *createPlane(Ogre::Real a,Ogre::Real b,Ogre::Real c,Ogre::Real d); |
---|
| 105 | PhysicalThing *createBox(Ogre::Real x,Ogre::Real y,Ogre::Real z,Ogre::Real lx,Ogre::Real ly,Ogre::Real lz); |
---|
| 106 | PhysicalThing *createSphere(Ogre::Real x,Ogre::Real y,Ogre::Real z,Ogre::Real r); |
---|
[1919] | 107 | |
---|
| 108 | // Create objects based on Ogre nodes, these nodes will then |
---|
| 109 | // come under control of the physics simulation and will move about |
---|
| 110 | // as if by magic! |
---|
| 111 | // Except for the plane, which can't actually be a physical body |
---|
| 112 | // and the trimesh which we're not going to allow to be a physical body |
---|
[1923] | 113 | PhysicalThing *createPlane(Ogre::SceneNode *node); |
---|
| 114 | PhysicalThing *createBox(Ogre::SceneNode *node,Ogre::Real mass = 1,Ogre::Vector3 const &offs = Ogre::Vector3(0,0,0)); |
---|
| 115 | PhysicalThing *createSphere(Ogre::SceneNode *node,Ogre::Real mass = 1); |
---|
| 116 | PhysicalThing *createTerrainTriMesh(Ogre::SceneManager *mgr,Ogre::Real grid_size,Ogre::Real grid_spacing); |
---|
[1919] | 117 | |
---|
| 118 | // Create and activate a new space inside the standard hash space |
---|
| 119 | // Things won't collide within a space so (for example) the objects |
---|
| 120 | // that make up a car won't collide with each other |
---|
| 121 | dSimpleSpace *createSpace(void); |
---|
| 122 | |
---|
| 123 | // Create joints between the nodes specified |
---|
| 124 | // The order of n1/n2 does matter; n1 is what you want attaching |
---|
| 125 | // and n2 is what you want it attaching to |
---|
[1923] | 126 | dJoint *createHinge2(Ogre::SceneNode *n1,Ogre::SceneNode *n2,const Ogre::Vector3 &suspension = Ogre::Vector3(0,1,0),const Ogre::Vector3 &axle = Ogre::Vector3(1,0,0)); |
---|
| 127 | dJoint *createHinge(Ogre::SceneNode *n1,Ogre::SceneNode *n2,const Ogre::Vector3 &axis = Ogre::Vector3(1,0,0)); |
---|
| 128 | dJoint *createSlider(Ogre::SceneNode *n1,Ogre::SceneNode *n2,const Ogre::Vector3 &axis = Ogre::Vector3(0,1,0)); |
---|
| 129 | dJoint *createBall(Ogre::SceneNode *n1,Ogre::SceneNode *n2); |
---|
[1919] | 130 | #ifdef INCLUDE_PLANE2D_JOINT |
---|
[1923] | 131 | dJoint *createPlane2D(Ogre::SceneNode *n); |
---|
[1919] | 132 | #endif |
---|
| 133 | |
---|
| 134 | // Apply forces to a body under our control |
---|
[1923] | 135 | void addTorque(Ogre::SceneNode *n,const Ogre::Vector3 &force); |
---|
[1919] | 136 | |
---|
| 137 | // Set the parameters used for the CFM/ERP joint parameters |
---|
[1923] | 138 | void setSuspension(Ogre::Real spring,Ogre::Real damper); |
---|
[1919] | 139 | |
---|
| 140 | // Set the acceleration due to gravity |
---|
[1923] | 141 | void setGravity(Ogre::Real g); |
---|
[1919] | 142 | |
---|
| 143 | // Get our constants |
---|
[1923] | 144 | Ogre::Real getTyre(void){return k_tyre;}; |
---|
| 145 | Ogre::Real getMu(void){return k_mu;}; |
---|
| 146 | Ogre::Real getCFM(void){return k_cfm;}; |
---|
| 147 | Ogre::Real getERP(void){return k_erp;}; |
---|
[1919] | 148 | |
---|
| 149 | // Static function for ODE to call when collisions (potentially) occur |
---|
| 150 | static void collisionCallback(void *data,dGeomID o1,dGeomID o2); |
---|
| 151 | }; |
---|
| 152 | |
---|
| 153 | #endif |
---|
| 154 | |
---|
| 155 | |
---|