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
29struct b2AABB;
30struct b2BodyDef;
31struct b2Color;
32struct b2JointDef;
33class b2Body;
34class b2Draw;
35class b2Fixture;
36class 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.
41class b2World
42{
43public:
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
212private:
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
266inline b2Body* b2World::GetBodyList()
267{
268 return m_bodyList;
269}
270
271inline const b2Body* b2World::GetBodyList() const
272{
273 return m_bodyList;
274}
275
276inline b2Joint* b2World::GetJointList()
277{
278 return m_jointList;
279}
280
281inline const b2Joint* b2World::GetJointList() const
282{
283 return m_jointList;
284}
285
286inline b2Contact* b2World::GetContactList()
287{
288 return m_contactManager.m_contactList;
289}
290
291inline const b2Contact* b2World::GetContactList() const
292{
293 return m_contactManager.m_contactList;
294}
295
296inline int32 b2World::GetBodyCount() const
297{
298 return m_bodyCount;
299}
300
301inline int32 b2World::GetJointCount() const
302{
303 return m_jointCount;
304}
305
306inline int32 b2World::GetContactCount() const
307{
308 return m_contactManager.m_contactCount;
309}
310
311inline void b2World::SetGravity(const b2Vec2& gravity)
312{
313 m_gravity = gravity;
314}
315
316inline b2Vec2 b2World::GetGravity() const
317{
318 return m_gravity;
319}
320
321inline bool b2World::IsLocked() const
322{
323 return (m_flags & e_locked) == e_locked;
324}
325
326inline 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.
339inline bool b2World::GetAutoClearForces() const
340{
341 return (m_flags & e_clearForces) == e_clearForces;
342}
343
344inline const b2ContactManager& b2World::GetContactManager() const
345{
346 return m_contactManager;
347}
348
349inline const b2Profile& b2World::GetProfile() const
350{
351 return m_profile;
352}
353
354#endif
355