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