b2Contact.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. * Copyright (c) 2006-2009 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. #ifndef B2_CONTACT_H
  19. #define B2_CONTACT_H
  20. #include <Box2D/Common/b2Math.h>
  21. #include <Box2D/Collision/b2Collision.h>
  22. #include <Box2D/Collision/Shapes/b2Shape.h>
  23. #include <Box2D/Dynamics/b2Fixture.h>
  24. class b2Body;
  25. class b2Contact;
  26. class b2Fixture;
  27. class b2World;
  28. class b2BlockAllocator;
  29. class b2StackAllocator;
  30. class b2ContactListener;
  31. /// Friction mixing law. The idea is to allow either fixture to drive the restitution to zero.
  32. /// For example, anything slides on ice.
  33. inline float32 b2MixFriction(float32 friction1, float32 friction2)
  34. {
  35. return b2Sqrt(friction1 * friction2);
  36. }
  37. /// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
  38. /// For example, a superball bounces on anything.
  39. inline float32 b2MixRestitution(float32 restitution1, float32 restitution2)
  40. {
  41. return restitution1 > restitution2 ? restitution1 : restitution2;
  42. }
  43. typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA,
  44. b2Fixture* fixtureB, int32 indexB,
  45. b2BlockAllocator* allocator);
  46. typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
  47. struct b2ContactRegister
  48. {
  49. b2ContactCreateFcn* createFcn;
  50. b2ContactDestroyFcn* destroyFcn;
  51. bool primary;
  52. };
  53. /// A contact edge is used to connect bodies and contacts together
  54. /// in a contact graph where each body is a node and each contact
  55. /// is an edge. A contact edge belongs to a doubly linked list
  56. /// maintained in each attached body. Each contact has two contact
  57. /// nodes, one for each attached body.
  58. struct b2ContactEdge
  59. {
  60. b2Body* other; ///< provides quick access to the other body attached.
  61. b2Contact* contact; ///< the contact
  62. b2ContactEdge* prev; ///< the previous contact edge in the body's contact list
  63. b2ContactEdge* next; ///< the next contact edge in the body's contact list
  64. };
  65. /// The class manages contact between two shapes. A contact exists for each overlapping
  66. /// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
  67. /// that has no contact points.
  68. class b2Contact
  69. {
  70. public:
  71. /// Get the contact manifold. Do not modify the manifold unless you understand the
  72. /// internals of Box2D.
  73. b2Manifold* GetManifold();
  74. const b2Manifold* GetManifold() const;
  75. /// Get the world manifold.
  76. void GetWorldManifold(b2WorldManifold* worldManifold) const;
  77. /// Is this contact touching?
  78. bool IsTouching() const;
  79. /// Enable/disable this contact. This can be used inside the pre-solve
  80. /// contact listener. The contact is only disabled for the current
  81. /// time step (or sub-step in continuous collisions).
  82. void SetEnabled(bool flag);
  83. /// Has this contact been disabled?
  84. bool IsEnabled() const;
  85. /// Get the next contact in the world's contact list.
  86. b2Contact* GetNext();
  87. const b2Contact* GetNext() const;
  88. /// Get fixture A in this contact.
  89. b2Fixture* GetFixtureA();
  90. const b2Fixture* GetFixtureA() const;
  91. /// Get the child primitive index for fixture A.
  92. int32 GetChildIndexA() const;
  93. /// Get fixture B in this contact.
  94. b2Fixture* GetFixtureB();
  95. const b2Fixture* GetFixtureB() const;
  96. /// Get the child primitive index for fixture B.
  97. int32 GetChildIndexB() const;
  98. /// Override the default friction mixture. You can call this in b2ContactListener::PreSolve.
  99. /// This value persists until set or reset.
  100. void SetFriction(float32 friction);
  101. /// Get the friction.
  102. float32 GetFriction() const;
  103. /// Reset the friction mixture to the default value.
  104. void ResetFriction();
  105. /// Override the default restitution mixture. You can call this in b2ContactListener::PreSolve.
  106. /// The value persists until you set or reset.
  107. void SetRestitution(float32 restitution);
  108. /// Get the restitution.
  109. float32 GetRestitution() const;
  110. /// Reset the restitution to the default value.
  111. void ResetRestitution();
  112. /// Set the desired tangent speed for a conveyor belt behavior. In meters per second.
  113. void SetTangentSpeed(float32 speed);
  114. /// Get the desired tangent speed. In meters per second.
  115. float32 GetTangentSpeed() const;
  116. /// Evaluate this contact with your own manifold and transforms.
  117. virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
  118. protected:
  119. friend class b2ContactManager;
  120. friend class b2World;
  121. friend class b2ContactSolver;
  122. friend class b2Body;
  123. friend class b2Fixture;
  124. // Flags stored in m_flags
  125. enum
  126. {
  127. // Used when crawling contact graph when forming islands.
  128. e_islandFlag = 0x0001,
  129. // Set when the shapes are touching.
  130. e_touchingFlag = 0x0002,
  131. // This contact can be disabled (by user)
  132. e_enabledFlag = 0x0004,
  133. // This contact needs filtering because a fixture filter was changed.
  134. e_filterFlag = 0x0008,
  135. // This bullet contact had a TOI event
  136. e_bulletHitFlag = 0x0010,
  137. // This contact has a valid TOI in m_toi
  138. e_toiFlag = 0x0020
  139. };
  140. /// Flag this contact for filtering. Filtering will occur the next time step.
  141. void FlagForFiltering();
  142. static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
  143. b2Shape::Type typeA, b2Shape::Type typeB);
  144. static void InitializeRegisters();
  145. static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
  146. static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
  147. static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
  148. b2Contact() : m_fixtureA(NULL), m_fixtureB(NULL) {}
  149. b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
  150. virtual ~b2Contact() {}
  151. void Update(b2ContactListener* listener);
  152. static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
  153. static bool s_initialized;
  154. uint32 m_flags;
  155. // World pool and list pointers.
  156. b2Contact* m_prev;
  157. b2Contact* m_next;
  158. // Nodes for connecting bodies.
  159. b2ContactEdge m_nodeA;
  160. b2ContactEdge m_nodeB;
  161. b2Fixture* m_fixtureA;
  162. b2Fixture* m_fixtureB;
  163. int32 m_indexA;
  164. int32 m_indexB;
  165. b2Manifold m_manifold;
  166. int32 m_toiCount;
  167. float32 m_toi;
  168. float32 m_friction;
  169. float32 m_restitution;
  170. float32 m_tangentSpeed;
  171. };
  172. inline b2Manifold* b2Contact::GetManifold()
  173. {
  174. return &m_manifold;
  175. }
  176. inline const b2Manifold* b2Contact::GetManifold() const
  177. {
  178. return &m_manifold;
  179. }
  180. inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
  181. {
  182. const b2Body* bodyA = m_fixtureA->GetBody();
  183. const b2Body* bodyB = m_fixtureB->GetBody();
  184. const b2Shape* shapeA = m_fixtureA->GetShape();
  185. const b2Shape* shapeB = m_fixtureB->GetShape();
  186. worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
  187. }
  188. inline void b2Contact::SetEnabled(bool flag)
  189. {
  190. if (flag)
  191. {
  192. m_flags |= e_enabledFlag;
  193. }
  194. else
  195. {
  196. m_flags &= ~e_enabledFlag;
  197. }
  198. }
  199. inline bool b2Contact::IsEnabled() const
  200. {
  201. return (m_flags & e_enabledFlag) == e_enabledFlag;
  202. }
  203. inline bool b2Contact::IsTouching() const
  204. {
  205. return (m_flags & e_touchingFlag) == e_touchingFlag;
  206. }
  207. inline b2Contact* b2Contact::GetNext()
  208. {
  209. return m_next;
  210. }
  211. inline const b2Contact* b2Contact::GetNext() const
  212. {
  213. return m_next;
  214. }
  215. inline b2Fixture* b2Contact::GetFixtureA()
  216. {
  217. return m_fixtureA;
  218. }
  219. inline const b2Fixture* b2Contact::GetFixtureA() const
  220. {
  221. return m_fixtureA;
  222. }
  223. inline b2Fixture* b2Contact::GetFixtureB()
  224. {
  225. return m_fixtureB;
  226. }
  227. inline int32 b2Contact::GetChildIndexA() const
  228. {
  229. return m_indexA;
  230. }
  231. inline const b2Fixture* b2Contact::GetFixtureB() const
  232. {
  233. return m_fixtureB;
  234. }
  235. inline int32 b2Contact::GetChildIndexB() const
  236. {
  237. return m_indexB;
  238. }
  239. inline void b2Contact::FlagForFiltering()
  240. {
  241. m_flags |= e_filterFlag;
  242. }
  243. inline void b2Contact::SetFriction(float32 friction)
  244. {
  245. m_friction = friction;
  246. }
  247. inline float32 b2Contact::GetFriction() const
  248. {
  249. return m_friction;
  250. }
  251. inline void b2Contact::ResetFriction()
  252. {
  253. m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
  254. }
  255. inline void b2Contact::SetRestitution(float32 restitution)
  256. {
  257. m_restitution = restitution;
  258. }
  259. inline float32 b2Contact::GetRestitution() const
  260. {
  261. return m_restitution;
  262. }
  263. inline void b2Contact::ResetRestitution()
  264. {
  265. m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
  266. }
  267. inline void b2Contact::SetTangentSpeed(float32 speed)
  268. {
  269. m_tangentSpeed = speed;
  270. }
  271. inline float32 b2Contact::GetTangentSpeed() const
  272. {
  273. return m_tangentSpeed;
  274. }
  275. #endif