Box2D  2.4.0
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 
54 typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA,
55  b2Fixture* fixtureB, int32 indexB,
56  b2BlockAllocator* allocator);
57 typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
58 
59 struct B2_API b2ContactRegister
60 {
61  b2ContactCreateFcn* createFcn;
62  b2ContactDestroyFcn* destroyFcn;
63  bool primary;
64 };
65 
71 struct B2_API b2ContactEdge
72 {
77 };
78 
82 class B2_API b2Contact
83 {
84 public:
85 
88  b2Manifold* GetManifold();
89  const b2Manifold* GetManifold() const;
90 
92  void GetWorldManifold(b2WorldManifold* worldManifold) const;
93 
95  bool IsTouching() const;
96 
100  void SetEnabled(bool flag);
101 
103  bool IsEnabled() const;
104 
106  b2Contact* GetNext();
107  const b2Contact* GetNext() const;
108 
110  b2Fixture* GetFixtureA();
111  const b2Fixture* GetFixtureA() const;
112 
114  int32 GetChildIndexA() const;
115 
117  b2Fixture* GetFixtureB();
118  const b2Fixture* GetFixtureB() const;
119 
121  int32 GetChildIndexB() const;
122 
125  void SetFriction(float friction);
126 
128  float GetFriction() const;
129 
131  void ResetFriction();
132 
135  void SetRestitution(float restitution);
136 
138  float GetRestitution() const;
139 
141  void ResetRestitution();
142 
144  void SetTangentSpeed(float speed);
145 
147  float GetTangentSpeed() const;
148 
150  virtual void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB) = 0;
151 
152 protected:
153  friend class b2ContactManager;
154  friend class b2World;
155  friend class b2ContactSolver;
156  friend class b2Body;
157  friend class b2Fixture;
158 
159  // Flags stored in m_flags
160  enum
161  {
162  // Used when crawling contact graph when forming islands.
163  e_islandFlag = 0x0001,
164 
165  // Set when the shapes are touching.
166  e_touchingFlag = 0x0002,
167 
168  // This contact can be disabled (by user)
169  e_enabledFlag = 0x0004,
170 
171  // This contact needs filtering because a fixture filter was changed.
172  e_filterFlag = 0x0008,
173 
174  // This bullet contact had a TOI event
175  e_bulletHitFlag = 0x0010,
176 
177  // This contact has a valid TOI in m_toi
178  e_toiFlag = 0x0020
179  };
180 
182  void FlagForFiltering();
183 
184  static void AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destroyFcn,
185  b2Shape::Type typeA, b2Shape::Type typeB);
186  static void InitializeRegisters();
187  static b2Contact* Create(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB, b2BlockAllocator* allocator);
188  static void Destroy(b2Contact* contact, b2Shape::Type typeA, b2Shape::Type typeB, b2BlockAllocator* allocator);
189  static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
190 
191  b2Contact() : m_fixtureA(nullptr), m_fixtureB(nullptr) {}
192  b2Contact(b2Fixture* fixtureA, int32 indexA, b2Fixture* fixtureB, int32 indexB);
193  virtual ~b2Contact() {}
194 
195  void Update(b2ContactListener* listener);
196 
197  static b2ContactRegister s_registers[b2Shape::e_typeCount][b2Shape::e_typeCount];
198  static bool s_initialized;
199 
200  uint32 m_flags;
201 
202  // World pool and list pointers.
203  b2Contact* m_prev;
204  b2Contact* m_next;
205 
206  // Nodes for connecting bodies.
207  b2ContactEdge m_nodeA;
208  b2ContactEdge m_nodeB;
209 
210  b2Fixture* m_fixtureA;
211  b2Fixture* m_fixtureB;
212 
213  int32 m_indexA;
214  int32 m_indexB;
215 
216  b2Manifold m_manifold;
217 
218  int32 m_toiCount;
219  float m_toi;
220 
221  float m_friction;
222  float m_restitution;
223 
224  float m_tangentSpeed;
225 };
226 
228 {
229  return &m_manifold;
230 }
231 
232 inline const b2Manifold* b2Contact::GetManifold() const
233 {
234  return &m_manifold;
235 }
236 
237 inline void b2Contact::GetWorldManifold(b2WorldManifold* worldManifold) const
238 {
239  const b2Body* bodyA = m_fixtureA->GetBody();
240  const b2Body* bodyB = m_fixtureB->GetBody();
241  const b2Shape* shapeA = m_fixtureA->GetShape();
242  const b2Shape* shapeB = m_fixtureB->GetShape();
243 
244  worldManifold->Initialize(&m_manifold, bodyA->GetTransform(), shapeA->m_radius, bodyB->GetTransform(), shapeB->m_radius);
245 }
246 
247 inline void b2Contact::SetEnabled(bool flag)
248 {
249  if (flag)
250  {
251  m_flags |= e_enabledFlag;
252  }
253  else
254  {
255  m_flags &= ~e_enabledFlag;
256  }
257 }
258 
259 inline bool b2Contact::IsEnabled() const
260 {
261  return (m_flags & e_enabledFlag) == e_enabledFlag;
262 }
263 
264 inline bool b2Contact::IsTouching() const
265 {
266  return (m_flags & e_touchingFlag) == e_touchingFlag;
267 }
268 
270 {
271  return m_next;
272 }
273 
274 inline const b2Contact* b2Contact::GetNext() const
275 {
276  return m_next;
277 }
278 
280 {
281  return m_fixtureA;
282 }
283 
284 inline const b2Fixture* b2Contact::GetFixtureA() const
285 {
286  return m_fixtureA;
287 }
288 
290 {
291  return m_fixtureB;
292 }
293 
294 inline int32 b2Contact::GetChildIndexA() const
295 {
296  return m_indexA;
297 }
298 
299 inline const b2Fixture* b2Contact::GetFixtureB() const
300 {
301  return m_fixtureB;
302 }
303 
304 inline int32 b2Contact::GetChildIndexB() const
305 {
306  return m_indexB;
307 }
308 
310 {
311  m_flags |= e_filterFlag;
312 }
313 
314 inline void b2Contact::SetFriction(float friction)
315 {
316  m_friction = friction;
317 }
318 
319 inline float b2Contact::GetFriction() const
320 {
321  return m_friction;
322 }
323 
325 {
326  m_friction = b2MixFriction(m_fixtureA->m_friction, m_fixtureB->m_friction);
327 }
328 
329 inline void b2Contact::SetRestitution(float restitution)
330 {
331  m_restitution = restitution;
332 }
333 
334 inline float b2Contact::GetRestitution() const
335 {
336  return m_restitution;
337 }
338 
340 {
341  m_restitution = b2MixRestitution(m_fixtureA->m_restitution, m_fixtureB->m_restitution);
342 }
343 
344 inline void b2Contact::SetTangentSpeed(float speed)
345 {
346  m_tangentSpeed = speed;
347 }
348 
349 inline float b2Contact::GetTangentSpeed() const
350 {
351  return m_tangentSpeed;
352 }
353 
355 extern B2_API bool g_blockSolve;
356 
357 #endif
b2Contact::ResetRestitution
void ResetRestitution()
Reset the restitution to the default value.
Definition: b2_contact.h:339
b2Body
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:133
b2ContactEdge::next
b2ContactEdge * next
the next contact edge in the body's contact list
Definition: b2_contact.h:76
b2Contact::GetNext
b2Contact * GetNext()
Get the next contact in the world's contact list.
Definition: b2_contact.h:269
b2ContactManager
Definition: b2_contact_manager.h:36
b2Contact::Evaluate
virtual void Evaluate(b2Manifold *manifold, const b2Transform &xfA, const b2Transform &xfB)=0
Evaluate this contact with your own manifold and transforms.
b2Contact::ResetFriction
void ResetFriction()
Reset the friction mixture to the default value.
Definition: b2_contact.h:324
b2Fixture::GetBody
b2Body * GetBody()
Definition: b2_fixture.h:279
b2Body::GetTransform
const b2Transform & GetTransform() const
Definition: b2_body.h:483
b2Contact::GetFixtureB
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:289
b2Contact::GetTangentSpeed
float GetTangentSpeed() const
Get the desired tangent speed. In meters per second.
Definition: b2_contact.h:349
b2ContactListener
Definition: b2_world_callbacks.h:87
b2Transform
Definition: b2_math.h:339
b2Contact::SetRestitution
void SetRestitution(float restitution)
Definition: b2_contact.h:329
b2Manifold
Definition: b2_collision.h:100
b2Contact::GetFriction
float GetFriction() const
Get the friction.
Definition: b2_contact.h:319
b2Contact::IsTouching
bool IsTouching() const
Is this contact touching?
Definition: b2_contact.h:264
b2ContactEdge::other
b2Body * other
provides quick access to the other body attached.
Definition: b2_contact.h:73
b2Contact::GetFixtureA
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:279
b2StackAllocator
Definition: b2_stack_allocator.h:43
b2Contact::GetChildIndexB
int32 GetChildIndexB() const
Get the child primitive index for fixture B.
Definition: b2_contact.h:304
b2Shape::m_radius
float m_radius
Definition: b2_shape.h:102
b2Contact::GetManifold
b2Manifold * GetManifold()
Definition: b2_contact.h:227
b2WorldManifold
This is used to compute the current state of a contact manifold.
Definition: b2_collision.h:117
b2Fixture
Definition: b2_fixture.h:113
b2BlockAllocator
Definition: b2_block_allocator.h:38
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:344
b2ContactRegister
Definition: b2_contact.h:60
b2ContactEdge::prev
b2ContactEdge * prev
the previous contact edge in the body's contact list
Definition: b2_contact.h:75
b2Contact
Definition: b2_contact.h:83
b2Contact::IsEnabled
bool IsEnabled() const
Has this contact been disabled?
Definition: b2_contact.h:259
b2World
Definition: b2_world.h:47
b2Contact::GetChildIndexA
int32 GetChildIndexA() const
Get the child primitive index for fixture A.
Definition: b2_contact.h:294
b2Contact::SetFriction
void SetFriction(float friction)
Definition: b2_contact.h:314
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:309
b2ContactEdge::contact
b2Contact * contact
the contact
Definition: b2_contact.h:74
b2Shape
Definition: b2_shape.h:49
b2Fixture::GetShape
b2Shape * GetShape()
Definition: b2_fixture.h:249
b2ContactEdge
Definition: b2_contact.h:72
b2Contact::GetWorldManifold
void GetWorldManifold(b2WorldManifold *worldManifold) const
Get the world manifold.
Definition: b2_contact.h:237
b2Contact::GetRestitution
float GetRestitution() const
Get the restitution.
Definition: b2_contact.h:334
b2Contact::SetEnabled
void SetEnabled(bool flag)
Definition: b2_contact.h:247