Box2D  2.4.1
A 2D physics engine for games
b2_contact.h
1 // MIT License
2 
3 // Copyright (c) 2019 Erin Catto
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 // SOFTWARE.
22 
23 #ifndef B2_CONTACT_H
24 #define B2_CONTACT_H
25 
26 #include "b2_api.h"
27 #include "b2_collision.h"
28 #include "b2_fixture.h"
29 #include "b2_math.h"
30 #include "b2_shape.h"
31 
32 class b2Body;
33 class b2Contact;
34 class b2Fixture;
35 class b2World;
36 class b2BlockAllocator;
37 class b2StackAllocator;
38 class b2ContactListener;
39 
42 inline float b2MixFriction(float friction1, float friction2)
43 {
44  return b2Sqrt(friction1 * friction2);
45 }
46 
49 inline float b2MixRestitution(float restitution1, float restitution2)
50 {
51  return restitution1 > restitution2 ? restitution1 : restitution2;
52 }
53 
55 inline float b2MixRestitutionThreshold(float threshold1, float threshold2)
56 {
57  return threshold1 < threshold2 ? threshold1 : threshold2;
58 }
59 
60 typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA,
61  b2Fixture* fixtureB, int32 indexB,
62  b2BlockAllocator* allocator);
63 typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
64 
65 struct B2_API b2ContactRegister
66 {
67  b2ContactCreateFcn* createFcn;
68  b2ContactDestroyFcn* destroyFcn;
69  bool primary;
70 };
71 
77 struct B2_API b2ContactEdge
78 {
83 };
84 
88 class B2_API b2Contact
89 {
90 public:
91 
94  b2Manifold* GetManifold();
95  const b2Manifold* GetManifold() const;
96 
98  void GetWorldManifold(b2WorldManifold* worldManifold) const;
99 
101  bool IsTouching() const;
102 
106  void SetEnabled(bool flag);
107 
109  bool IsEnabled() const;
110 
112  b2Contact* GetNext();
113  const b2Contact* GetNext() const;
114 
116  b2Fixture* GetFixtureA();
117  const b2Fixture* GetFixtureA() const;
118 
120  int32 GetChildIndexA() const;
121 
123  b2Fixture* GetFixtureB();
124  const b2Fixture* GetFixtureB() const;
125 
127  int32 GetChildIndexB() const;
128 
131  void SetFriction(float friction);
132 
134  float GetFriction() const;
135 
137  void ResetFriction();
138 
141  void SetRestitution(float restitution);
142 
144  float GetRestitution() const;
145 
147  void ResetRestitution();
148 
151  void SetRestitutionThreshold(float threshold);
152 
154  float GetRestitutionThreshold() const;
155 
157  void ResetRestitutionThreshold();
158 
160  void SetTangentSpeed(float speed);
161 
163  float GetTangentSpeed() const;
164 
166  virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
167 
168 protected:
169  friend class b2ContactManager;
170  friend class b2World;
171  friend class b2ContactSolver;
172  friend class b2Body;
173  friend class b2Fixture;
174 
175  // Flags stored in m_flags
176  enum
177  {
178  // Used when crawling contact graph when forming islands.
179  e_islandFlag = 0x0001,
180 
181  // Set when the shapes are touching.
182  e_touchingFlag = 0x0002,
183 
184  // This contact can be disabled (by user)
185  e_enabledFlag = 0x0004,
186 
187  // This contact needs filtering because a fixture filter was changed.
188  e_filterFlag = 0x0008,
189 
190  // This bullet contact had a TOI event
191  e_bulletHitFlag = 0x0010,
192 
193  // This contact has a valid TOI in m_toi
194  e_toiFlag = 0x0020
195  };
196 
198  void FlagForFiltering();
199 
200  static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
201  b2Shape::Type typeA, b2Shape::Type typeB);
202  static void InitializeRegisters();
203  static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
204  static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
205  static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
206 
207  b2Contact() : m_fixtureA(nullptr), m_fixtureB(nullptr) {}
208  b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
209  virtual ~b2Contact() {}
210 
211  void Update(b2ContactListener* listener);
212 
213  static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
214  static bool s_initialized;
215 
216  uint32 m_flags;
217 
218  // World pool and list pointers.
219  b2Contact* m_prev;
220  b2Contact* m_next;
221 
222  // Nodes for connecting bodies.
223  b2ContactEdge m_nodeA;
224  b2ContactEdge m_nodeB;
225 
226  b2Fixture* m_fixtureA;
227  b2Fixture* m_fixtureB;
228 
229  int32 m_indexA;
230  int32 m_indexB;
231 
232  b2Manifold m_manifold;
233 
234  int32 m_toiCount;
235  float m_toi;
236 
237  float m_friction;
238  float m_restitution;
239  float m_restitutionThreshold;
240 
241  float m_tangentSpeed;
242 };
243 
245 {
246  return &m_manifold;
247 }
248 
249 inline const b2Manifold* b2Contact::GetManifold() const
250 {
251  return &m_manifold;
252 }
253 
254 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
255 {
256  const b2Body* bodyA = m_fixtureA->GetBody();
257  const b2Body* bodyB = m_fixtureB->GetBody();
258  const b2Shape* shapeA = m_fixtureA->GetShape();
259  const b2Shape* shapeB = m_fixtureB->GetShape();
260 
261  worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
262 }
263 
264 inline void b2Contact::SetEnabled(bool flag)
265 {
266  if (flag)
267  {
268  m_flags |= e_enabledFlag;
269  }
270  else
271  {
272  m_flags &= ~e_enabledFlag;
273  }
274 }
275 
276 inline bool b2Contact::IsEnabled() const
277 {
278  return (m_flags & e_enabledFlag) == e_enabledFlag;
279 }
280 
281 inline bool b2Contact::IsTouching() const
282 {
283  return (m_flags & e_touchingFlag) == e_touchingFlag;
284 }
285 
287 {
288  return m_next;
289 }
290 
291 inline const b2Contact* b2Contact::GetNext() const
292 {
293  return m_next;
294 }
295 
297 {
298  return m_fixtureA;
299 }
300 
301 inline const b2Fixture* b2Contact::GetFixtureA() const
302 {
303  return m_fixtureA;
304 }
305 
307 {
308  return m_fixtureB;
309 }
310 
311 inline int32 b2Contact::GetChildIndexA() const
312 {
313  return m_indexA;
314 }
315 
316 inline const b2Fixture* b2Contact::GetFixtureB() const
317 {
318  return m_fixtureB;
319 }
320 
321 inline int32 b2Contact::GetChildIndexB() const
322 {
323  return m_indexB;
324 }
325 
327 {
328  m_flags |= e_filterFlag;
329 }
330 
331 inline void b2Contact::SetFriction(float friction)
332 {
333  m_friction = friction;
334 }
335 
336 inline float b2Contact::GetFriction() const
337 {
338  return m_friction;
339 }
340 
342 {
343  m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
344 }
345 
346 inline void b2Contact::SetRestitution(float restitution)
347 {
348  m_restitution = restitution;
349 }
350 
351 inline float b2Contact::GetRestitution() const
352 {
353  return m_restitution;
354 }
355 
357 {
358  m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
359 }
360 
361 inline void b2Contact::SetRestitutionThreshold(float threshold)
362 {
363  m_restitutionThreshold = threshold;
364 }
365 
367 {
368  return m_restitutionThreshold;
369 }
370 
372 {
373  m_restitutionThreshold = b2MixRestitutionThreshold(m_fixtureA->m_restitutionThreshold, m_fixtureB->m_restitutionThreshold);
374 }
375 
376 inline void b2Contact::SetTangentSpeed(float speed)
377 {
378  m_tangentSpeed = speed;
379 }
380 
381 inline float b2Contact::GetTangentSpeed() const
382 {
383  return m_tangentSpeed;
384 }
385 
386 #endif
b2Contact::GetManifold
b2Manifold * GetManifold()
Definition: b2_contact.h:244
b2Contact::ResetRestitution
void ResetRestitution()
Reset the restitution to the default value.
Definition: b2_contact.h:356
b2Body
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:128
b2ContactEdge::next
b2ContactEdge * next
the next contact edge in the body's contact list
Definition: b2_contact.h:82
b2ContactManager
Definition: b2_contact_manager.h:35
b2Contact::ResetFriction
void ResetFriction()
Reset the friction mixture to the default value.
Definition: b2_contact.h:341
b2Fixture::GetShape
b2Shape * GetShape()
Definition: b2_fixture.h:258
b2Body::GetTransform
const b2Transform & GetTransform() const
Definition: b2_body.h:479
b2Contact::GetTangentSpeed
float GetTangentSpeed() const
Get the desired tangent speed. In meters per second.
Definition: b2_contact.h:381
b2ContactListener
Definition: b2_world_callbacks.h:86
b2Transform
Definition: b2_math.h:338
b2Contact::SetRestitution
void SetRestitution(float restitution)
Definition: b2_contact.h:346
b2Manifold
Definition: b2_collision.h:99
b2Contact::GetRestitutionThreshold
float GetRestitutionThreshold() const
Get the restitution threshold.
Definition: b2_contact.h:366
b2Contact::GetFriction
float GetFriction() const
Get the friction.
Definition: b2_contact.h:336
b2Contact::IsTouching
bool IsTouching() const
Is this contact touching?
Definition: b2_contact.h:281
b2ContactEdge::other
b2Body * other
provides quick access to the other body attached.
Definition: b2_contact.h:79
b2StackAllocator
Definition: b2_stack_allocator.h:42
b2Contact::SetRestitutionThreshold
void SetRestitutionThreshold(float threshold)
Definition: b2_contact.h:361
b2Contact::GetChildIndexB
int32 GetChildIndexB() const
Get the child primitive index for fixture B.
Definition: b2_contact.h:321
b2Shape::m_radius
float m_radius
Definition: b2_shape.h:102
b2WorldManifold
This is used to compute the current state of a contact manifold.
Definition: b2_collision.h:116
b2Contact::GetFixtureB
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:306
b2Fixture
Definition: b2_fixture.h:116
b2Contact::ResetRestitutionThreshold
void ResetRestitutionThreshold()
Reset the restitution threshold to the default value.
Definition: b2_contact.h:371
b2BlockAllocator
Definition: b2_block_allocator.h:37
b2_collision.h
b2Contact::SetTangentSpeed
void SetTangentSpeed(float speed)
Set the desired tangent speed for a conveyor belt behavior. In meters per second.
Definition: b2_contact.h:376
b2ContactRegister
Definition: b2_contact.h:65
b2ContactEdge::prev
b2ContactEdge * prev
the previous contact edge in the body's contact list
Definition: b2_contact.h:81
b2Contact
Definition: b2_contact.h:88
b2Contact::IsEnabled
bool IsEnabled() const
Has this contact been disabled?
Definition: b2_contact.h:276
b2World
Definition: b2_world.h:46
b2Contact::GetChildIndexA
int32 GetChildIndexA() const
Get the child primitive index for fixture A.
Definition: b2_contact.h:311
b2Contact::SetFriction
void SetFriction(float friction)
Definition: b2_contact.h:331
b2WorldManifold::Initialize
void Initialize(const b2Manifold *manifold, const b2Transform &xfA, float radiusA, const b2Transform &xfB, float radiusB)
b2Contact::FlagForFiltering
void FlagForFiltering()
Flag this contact for filtering. Filtering will occur the next time step.
Definition: b2_contact.h:326
b2ContactEdge::contact
b2Contact * contact
the contact
Definition: b2_contact.h:80
b2Shape
Definition: b2_shape.h:48
b2Contact::GetNext
b2Contact * GetNext()
Get the next contact in the world's contact list.
Definition: b2_contact.h:286
b2ContactEdge
Definition: b2_contact.h:77
b2Contact::GetWorldManifold
void GetWorldManifold(b2WorldManifold *worldManifold) const
Get the world manifold.
Definition: b2_contact.h:254
b2Fixture::GetBody
b2Body * GetBody()
Definition: b2_fixture.h:283
b2Contact::GetFixtureA
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:296
b2Contact::GetRestitution
float GetRestitution() const
Get the restitution.
Definition: b2_contact.h:351
b2Contact::SetEnabled
void SetEnabled(bool flag)
Definition: b2_contact.h:264