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