| 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 | |