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
32class b2Body;
33class b2Contact;
34class b2Fixture;
35class b2World;
39
42inline float b2MixFriction(float friction1, float friction2)
43{
44 return b2Sqrt(friction1 * friction2);
45}
46
49inline float b2MixRestitution(float restitution1, float restitution2)
50{
51 return restitution1 > restitution2 ? restitution1 : restitution2;
52}
53
55inline float b2MixRestitutionThreshold(float threshold1, float threshold2)
56{
57 return threshold1 < threshold2 ? threshold1 : threshold2;
58}
59
60typedef b2Contact* b2ContactCreateFcn( b2Fixture* fixtureA, int32 indexA,
61 b2Fixture* fixtureB, int32 indexB,
62 b2BlockAllocator* allocator);
63typedef void b2ContactDestroyFcn(b2Contact* contact, b2BlockAllocator* allocator);
64
65struct B2_API b2ContactRegister
66{
67 b2ContactCreateFcn* createFcn;
68 b2ContactDestroyFcn* destroyFcn;
69 bool primary;
70};
71
77struct B2_API b2ContactEdge
78{
83};
84
88class B2_API b2Contact
89{
90public:
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
168protected:
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
249inline const b2Manifold* b2Contact::GetManifold() const
250{
251 return &m_manifold;
252}
253
254inline 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
264inline 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
276inline bool b2Contact::IsEnabled() const
277{
278 return (m_flags & e_enabledFlag) == e_enabledFlag;
279}
280
281inline bool b2Contact::IsTouching() const
282{
283 return (m_flags & e_touchingFlag) == e_touchingFlag;
284}
285
287{
288 return m_next;
289}
290
291inline const b2Contact* b2Contact::GetNext() const
292{
293 return m_next;
294}
295
297{
298 return m_fixtureA;
299}
300
301inline const b2Fixture* b2Contact::GetFixtureA() const
302{
303 return m_fixtureA;
304}
305
307{
308 return m_fixtureB;
309}
310
311inline int32 b2Contact::GetChildIndexA() const
312{
313 return m_indexA;
314}
315
316inline const b2Fixture* b2Contact::GetFixtureB() const
317{
318 return m_fixtureB;
319}
320
321inline int32 b2Contact::GetChildIndexB() const
322{
323 return m_indexB;
324}
325
327{
328 m_flags |= e_filterFlag;
329}
330
331inline void b2Contact::SetFriction(float friction)
332{
333 m_friction = friction;
334}
335
336inline 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
346inline void b2Contact::SetRestitution(float restitution)
347{
348 m_restitution = restitution;
349}
350
351inline 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
361inline 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
376inline void b2Contact::SetTangentSpeed(float speed)
377{
378 m_tangentSpeed = speed;
379}
380
381inline float b2Contact::GetTangentSpeed() const
382{
383 return m_tangentSpeed;
384}
385
386#endif
Definition: b2_block_allocator.h:38
A rigid body. These are created via b2World::CreateBody.
Definition: b2_body.h:129
const b2Transform & GetTransform() const
Definition: b2_body.h:479
Definition: b2_contact.h:89
void ResetRestitution()
Reset the restitution to the default value.
Definition: b2_contact.h:356
void FlagForFiltering()
Flag this contact for filtering. Filtering will occur the next time step.
Definition: b2_contact.h:326
bool IsTouching() const
Is this contact touching?
Definition: b2_contact.h:281
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:306
void SetRestitution(float restitution)
Definition: b2_contact.h:346
void SetFriction(float friction)
Definition: b2_contact.h:331
void SetEnabled(bool flag)
Definition: b2_contact.h:264
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:296
float GetRestitutionThreshold() const
Get the restitution threshold.
Definition: b2_contact.h:366
void GetWorldManifold(b2WorldManifold *worldManifold) const
Get the world manifold.
Definition: b2_contact.h:254
float GetRestitution() const
Get the restitution.
Definition: b2_contact.h:351
int32 GetChildIndexA() const
Get the child primitive index for fixture A.
Definition: b2_contact.h:311
int32 GetChildIndexB() const
Get the child primitive index for fixture B.
Definition: b2_contact.h:321
b2Manifold * GetManifold()
Definition: b2_contact.h:244
void SetRestitutionThreshold(float threshold)
Definition: b2_contact.h:361
void SetTangentSpeed(float speed)
Set the desired tangent speed for a conveyor belt behavior. In meters per second.
Definition: b2_contact.h:376
float GetTangentSpeed() const
Get the desired tangent speed. In meters per second.
Definition: b2_contact.h:381
void ResetRestitutionThreshold()
Reset the restitution threshold to the default value.
Definition: b2_contact.h:371
void ResetFriction()
Reset the friction mixture to the default value.
Definition: b2_contact.h:341
virtual void Evaluate(b2Manifold *manifold, const b2Transform &xfA, const b2Transform &xfB)=0
Evaluate this contact with your own manifold and transforms.
b2Contact * GetNext()
Get the next contact in the world's contact list.
Definition: b2_contact.h:286
float GetFriction() const
Get the friction.
Definition: b2_contact.h:336
bool IsEnabled() const
Has this contact been disabled?
Definition: b2_contact.h:276
Definition: b2_world_callbacks.h:87
Definition: b2_contact_manager.h:36
Definition: b2_fixture.h:117
b2Body * GetBody()
Definition: b2_fixture.h:283
b2Shape * GetShape()
Definition: b2_fixture.h:258
Definition: b2_shape.h:49
float m_radius
Definition: b2_shape.h:102
Definition: b2_stack_allocator.h:43
Definition: b2_world.h:47
Definition: b2_contact.h:78
b2Contact * contact
the contact
Definition: b2_contact.h:80
b2ContactEdge * prev
the previous contact edge in the body's contact list
Definition: b2_contact.h:81
b2Body * other
provides quick access to the other body attached.
Definition: b2_contact.h:79
b2ContactEdge * next
the next contact edge in the body's contact list
Definition: b2_contact.h:82
Definition: b2_contact.h:66
Definition: b2_collision.h:100
Definition: b2_math.h:339
This is used to compute the current state of a contact manifold.
Definition: b2_collision.h:117
void Initialize(const b2Manifold *manifold, const b2Transform &xfA, float radiusA, const b2Transform &xfB, float radiusB)