1 | /* |
2 | * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * Permission is granted to anyone to use this software for any purpose, |
8 | * including commercial applications, and to alter it and redistribute it |
9 | * freely, subject to the following restrictions: |
10 | * 1. The origin of this software must not be misrepresented; you must not |
11 | * claim that you wrote the original software. If you use this software |
12 | * in a product, an acknowledgment in the product documentation would be |
13 | * appreciated but is not required. |
14 | * 2. Altered source versions must be plainly marked as such, and must not be |
15 | * misrepresented as being the original software. |
16 | * 3. This notice may not be removed or altered from any source distribution. |
17 | */ |
18 | |
19 | #ifndef B2_WORLD_H |
20 | #define B2_WORLD_H |
21 | |
22 | #include <Box2D/Common/b2Math.h> |
23 | #include <Box2D/Common/b2BlockAllocator.h> |
24 | #include <Box2D/Common/b2StackAllocator.h> |
25 | #include <Box2D/Dynamics/b2ContactManager.h> |
26 | #include <Box2D/Dynamics/b2WorldCallbacks.h> |
27 | #include <Box2D/Dynamics/b2TimeStep.h> |
28 | |
29 | struct b2AABB; |
30 | struct b2BodyDef; |
31 | struct b2Color; |
32 | struct b2JointDef; |
33 | class b2Body; |
34 | class b2Draw; |
35 | class b2Fixture; |
36 | class b2Joint; |
37 | |
38 | /// The world class manages all physics entities, dynamic simulation, |
39 | /// and asynchronous queries. The world also contains efficient memory |
40 | /// management facilities. |
41 | class b2World |
42 | { |
43 | public: |
44 | /// Construct a world object. |
45 | /// @param gravity the world gravity vector. |
46 | b2World(const b2Vec2& gravity); |
47 | |
48 | /// Destruct the world. All physics entities are destroyed and all heap memory is released. |
49 | ~b2World(); |
50 | |
51 | /// Register a destruction listener. The listener is owned by you and must |
52 | /// remain in scope. |
53 | void SetDestructionListener(b2DestructionListener* listener); |
54 | |
55 | /// Register a contact filter to provide specific control over collision. |
56 | /// Otherwise the default filter is used (b2_defaultFilter). The listener is |
57 | /// owned by you and must remain in scope. |
58 | void SetContactFilter(b2ContactFilter* filter); |
59 | |
60 | /// Register a contact event listener. The listener is owned by you and must |
61 | /// remain in scope. |
62 | void SetContactListener(b2ContactListener* listener); |
63 | |
64 | /// Register a routine for debug drawing. The debug draw functions are called |
65 | /// inside with b2World::DrawDebugData method. The debug draw object is owned |
66 | /// by you and must remain in scope. |
67 | void SetDebugDraw(b2Draw* debugDraw); |
68 | |
69 | /// Create a rigid body given a definition. No reference to the definition |
70 | /// is retained. |
71 | /// @warning This function is locked during callbacks. |
72 | b2Body* CreateBody(const b2BodyDef* def); |
73 | |
74 | /// Destroy a rigid body given a definition. No reference to the definition |
75 | /// is retained. This function is locked during callbacks. |
76 | /// @warning This automatically deletes all associated shapes and joints. |
77 | /// @warning This function is locked during callbacks. |
78 | void DestroyBody(b2Body* body); |
79 | |
80 | /// Create a joint to constrain bodies together. No reference to the definition |
81 | /// is retained. This may cause the connected bodies to cease colliding. |
82 | /// @warning This function is locked during callbacks. |
83 | b2Joint* CreateJoint(const b2JointDef* def); |
84 | |
85 | /// Destroy a joint. This may cause the connected bodies to begin colliding. |
86 | /// @warning This function is locked during callbacks. |
87 | void DestroyJoint(b2Joint* joint); |
88 | |
89 | /// Take a time step. This performs collision detection, integration, |
90 | /// and constraint solution. |
91 | /// @param timeStep the amount of time to simulate, this should not vary. |
92 | /// @param velocityIterations for the velocity constraint solver. |
93 | /// @param positionIterations for the position constraint solver. |
94 | void Step( float32 timeStep, |
95 | int32 velocityIterations, |
96 | int32 positionIterations); |
97 | |
98 | /// Manually clear the force buffer on all bodies. By default, forces are cleared automatically |
99 | /// after each call to Step. The default behavior is modified by calling SetAutoClearForces. |
100 | /// The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain |
101 | /// a fixed sized time step under a variable frame-rate. |
102 | /// When you perform sub-stepping you will disable auto clearing of forces and instead call |
103 | /// ClearForces after all sub-steps are complete in one pass of your game loop. |
104 | /// @see SetAutoClearForces |
105 | void ClearForces(); |
106 | |
107 | /// Call this to draw shapes and other debug draw data. This is intentionally non-const. |
108 | void DrawDebugData(); |
109 | |
110 | /// Query the world for all fixtures that potentially overlap the |
111 | /// provided AABB. |
112 | /// @param callback a user implemented callback class. |
113 | /// @param aabb the query box. |
114 | void QueryAABB(b2QueryCallback* callback, const b2AABB& aabb) const; |
115 | |
116 | /// Ray-cast the world for all fixtures in the path of the ray. Your callback |
117 | /// controls whether you get the closest point, any point, or n-points. |
118 | /// The ray-cast ignores shapes that contain the starting point. |
119 | /// @param callback a user implemented callback class. |
120 | /// @param point1 the ray starting point |
121 | /// @param point2 the ray ending point |
122 | void RayCast(b2RayCastCallback* callback, const b2Vec2& point1, const b2Vec2& point2) const; |
123 | |
124 | /// Get the world body list. With the returned body, use b2Body::GetNext to get |
125 | /// the next body in the world list. A NULL body indicates the end of the list. |
126 | /// @return the head of the world body list. |
127 | b2Body* GetBodyList(); |
128 | const b2Body* GetBodyList() const; |
129 | |
130 | /// Get the world joint list. With the returned joint, use b2Joint::GetNext to get |
131 | /// the next joint in the world list. A NULL joint indicates the end of the list. |
132 | /// @return the head of the world joint list. |
133 | b2Joint* GetJointList(); |
134 | const b2Joint* GetJointList() const; |
135 | |
136 | /// Get the world contact list. With the returned contact, use b2Contact::GetNext to get |
137 | /// the next contact in the world list. A NULL contact indicates the end of the list. |
138 | /// @return the head of the world contact list. |
139 | /// @warning contacts are created and destroyed in the middle of a time step. |
140 | /// Use b2ContactListener to avoid missing contacts. |
141 | b2Contact* GetContactList(); |
142 | const b2Contact* GetContactList() const; |
143 | |
144 | /// Enable/disable sleep. |
145 | void SetAllowSleeping(bool flag); |
146 | bool GetAllowSleeping() const { return m_allowSleep; } |
147 | |
148 | /// Enable/disable warm starting. For testing. |
149 | void SetWarmStarting(bool flag) { m_warmStarting = flag; } |
150 | bool GetWarmStarting() const { return m_warmStarting; } |
151 | |
152 | /// Enable/disable continuous physics. For testing. |
153 | void SetContinuousPhysics(bool flag) { m_continuousPhysics = flag; } |
154 | bool GetContinuousPhysics() const { return m_continuousPhysics; } |
155 | |
156 | /// Enable/disable single stepped continuous physics. For testing. |
157 | void SetSubStepping(bool flag) { m_subStepping = flag; } |
158 | bool GetSubStepping() const { return m_subStepping; } |
159 | |
160 | /// Get the number of broad-phase proxies. |
161 | int32 GetProxyCount() const; |
162 | |
163 | /// Get the number of bodies. |
164 | int32 GetBodyCount() const; |
165 | |
166 | /// Get the number of joints. |
167 | int32 GetJointCount() const; |
168 | |
169 | /// Get the number of contacts (each may have 0 or more contact points). |
170 | int32 GetContactCount() const; |
171 | |
172 | /// Get the height of the dynamic tree. |
173 | int32 GetTreeHeight() const; |
174 | |
175 | /// Get the balance of the dynamic tree. |
176 | int32 GetTreeBalance() const; |
177 | |
178 | /// Get the quality metric of the dynamic tree. The smaller the better. |
179 | /// The minimum is 1. |
180 | float32 GetTreeQuality() const; |
181 | |
182 | /// Change the global gravity vector. |
183 | void SetGravity(const b2Vec2& gravity); |
184 | |
185 | /// Get the global gravity vector. |
186 | b2Vec2 GetGravity() const; |
187 | |
188 | /// Is the world locked (in the middle of a time step). |
189 | bool IsLocked() const; |
190 | |
191 | /// Set flag to control automatic clearing of forces after each time step. |
192 | void SetAutoClearForces(bool flag); |
193 | |
194 | /// Get the flag that controls automatic clearing of forces after each time step. |
195 | bool GetAutoClearForces() const; |
196 | |
197 | /// Shift the world origin. Useful for large worlds. |
198 | /// The body shift formula is: position -= newOrigin |
199 | /// @param newOrigin the new origin with respect to the old origin |
200 | void ShiftOrigin(const b2Vec2& newOrigin); |
201 | |
202 | /// Get the contact manager for testing. |
203 | const b2ContactManager& GetContactManager() const; |
204 | |
205 | /// Get the current profile. |
206 | const b2Profile& GetProfile() const; |
207 | |
208 | /// Dump the world into the log file. |
209 | /// @warning this should be called outside of a time step. |
210 | void Dump(); |
211 | |
212 | private: |
213 | |
214 | // m_flags |
215 | enum |
216 | { |
217 | e_newFixture = 0x0001, |
218 | e_locked = 0x0002, |
219 | e_clearForces = 0x0004 |
220 | }; |
221 | |
222 | friend class b2Body; |
223 | friend class b2Fixture; |
224 | friend class b2ContactManager; |
225 | friend class b2Controller; |
226 | |
227 | void Solve(const b2TimeStep& step); |
228 | void SolveTOI(const b2TimeStep& step); |
229 | |
230 | void DrawJoint(b2Joint* joint); |
231 | void DrawShape(b2Fixture* shape, const b2Transform& xf, const b2Color& color); |
232 | |
233 | b2BlockAllocator m_blockAllocator; |
234 | b2StackAllocator m_stackAllocator; |
235 | |
236 | int32 m_flags; |
237 | |
238 | b2ContactManager m_contactManager; |
239 | |
240 | b2Body* m_bodyList; |
241 | b2Joint* m_jointList; |
242 | |
243 | int32 m_bodyCount; |
244 | int32 m_jointCount; |
245 | |
246 | b2Vec2 m_gravity; |
247 | bool m_allowSleep; |
248 | |
249 | b2DestructionListener* m_destructionListener; |
250 | b2Draw* g_debugDraw; |
251 | |
252 | // This is used to compute the time step ratio to |
253 | // support a variable time step. |
254 | float32 m_inv_dt0; |
255 | |
256 | // These are for debugging the solver. |
257 | bool m_warmStarting; |
258 | bool m_continuousPhysics; |
259 | bool m_subStepping; |
260 | |
261 | bool m_stepComplete; |
262 | |
263 | b2Profile m_profile; |
264 | }; |
265 | |
266 | inline b2Body* b2World::GetBodyList() |
267 | { |
268 | return m_bodyList; |
269 | } |
270 | |
271 | inline const b2Body* b2World::GetBodyList() const |
272 | { |
273 | return m_bodyList; |
274 | } |
275 | |
276 | inline b2Joint* b2World::GetJointList() |
277 | { |
278 | return m_jointList; |
279 | } |
280 | |
281 | inline const b2Joint* b2World::GetJointList() const |
282 | { |
283 | return m_jointList; |
284 | } |
285 | |
286 | inline b2Contact* b2World::GetContactList() |
287 | { |
288 | return m_contactManager.m_contactList; |
289 | } |
290 | |
291 | inline const b2Contact* b2World::GetContactList() const |
292 | { |
293 | return m_contactManager.m_contactList; |
294 | } |
295 | |
296 | inline int32 b2World::GetBodyCount() const |
297 | { |
298 | return m_bodyCount; |
299 | } |
300 | |
301 | inline int32 b2World::GetJointCount() const |
302 | { |
303 | return m_jointCount; |
304 | } |
305 | |
306 | inline int32 b2World::GetContactCount() const |
307 | { |
308 | return m_contactManager.m_contactCount; |
309 | } |
310 | |
311 | inline void b2World::SetGravity(const b2Vec2& gravity) |
312 | { |
313 | m_gravity = gravity; |
314 | } |
315 | |
316 | inline b2Vec2 b2World::GetGravity() const |
317 | { |
318 | return m_gravity; |
319 | } |
320 | |
321 | inline bool b2World::IsLocked() const |
322 | { |
323 | return (m_flags & e_locked) == e_locked; |
324 | } |
325 | |
326 | inline void b2World::SetAutoClearForces(bool flag) |
327 | { |
328 | if (flag) |
329 | { |
330 | m_flags |= e_clearForces; |
331 | } |
332 | else |
333 | { |
334 | m_flags &= ~e_clearForces; |
335 | } |
336 | } |
337 | |
338 | /// Get the flag that controls automatic clearing of forces after each time step. |
339 | inline bool b2World::GetAutoClearForces() const |
340 | { |
341 | return (m_flags & e_clearForces) == e_clearForces; |
342 | } |
343 | |
344 | inline const b2ContactManager& b2World::GetContactManager() const |
345 | { |
346 | return m_contactManager; |
347 | } |
348 | |
349 | inline const b2Profile& b2World::GetProfile() const |
350 | { |
351 | return m_profile; |
352 | } |
353 | |
354 | #endif |
355 | |