Box2D: /build/box2d/src/box2d-2.4.1/include/box2d/b2_contact.h Source File

| 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 {
79 b2Body* other;
80 b2Contact* contact;
81 b2ContactEdge* prev;
82 b2ContactEdge* next;
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
244 inline b2Manifold* b2Contact::GetManifold()
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
286 inline b2Contact* b2Contact::GetNext()
287 {
288 return m_next;
289 }
290
291 inline const b2Contact* b2Contact::GetNext() const
292 {
293 return m_next;
294 }
295
296 inline b2Fixture* b2Contact::GetFixtureA()
297 {
298 return m_fixtureA;
299 }
300
301 inline const b2Fixture* b2Contact::GetFixtureA() const
302 {
303 return m_fixtureA;
304 }
305
306 inline b2Fixture* b2Contact::GetFixtureB()
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
326 inline void b2Contact::FlagForFiltering()
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
341 inline void b2Contact::ResetFriction()
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
356 inline void b2Contact::ResetRestitution()
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
366 inline float b2Contact::GetRestitutionThreshold() const
367 {
368 return m_restitutionThreshold;
369 }
370
371 inline void b2Contact::ResetRestitutionThreshold()
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::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:129
b2ContactEdge::next
b2ContactEdge * next
the next contact edge in the body's contact list
Definition: b2_contact.h:82
b2Contact::GetNext
b2Contact * GetNext()
Get the next contact in the world's contact list.
Definition: b2_contact.h:286
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:341
b2Fixture::GetBody
b2Body * GetBody()
Definition: b2_fixture.h:283
b2Body::GetTransform
const b2Transform & GetTransform() const
Definition: b2_body.h:479
b2Contact::GetFixtureB
b2Fixture * GetFixtureB()
Get fixture B in this contact.
Definition: b2_contact.h:306
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:87
b2Transform
Definition: b2_math.h:339
b2Contact::SetRestitution
void SetRestitution(float restitution)
Definition: b2_contact.h:346
b2Manifold
Definition: b2_collision.h:100
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
b2Contact::GetFixtureA
b2Fixture * GetFixtureA()
Get fixture A in this contact.
Definition: b2_contact.h:296
b2StackAllocator
Definition: b2_stack_allocator.h:43
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
b2Contact::GetManifold
b2Manifold * GetManifold()
Definition: b2_contact.h:244
b2WorldManifold
This is used to compute the current state of a contact manifold.
Definition: b2_collision.h:117
b2Fixture
Definition: b2_fixture.h:117
b2Contact::ResetRestitutionThreshold
void ResetRestitutionThreshold()
Reset the restitution threshold to the default value.
Definition: b2_contact.h:371
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:376
b2ContactRegister
Definition: b2_contact.h:66
b2ContactEdge::prev
b2ContactEdge * prev
the previous contact edge in the body's contact list
Definition: b2_contact.h:81
b2Contact
Definition: b2_contact.h:89
b2Contact::IsEnabled
bool IsEnabled() const
Has this contact been disabled?
Definition: b2_contact.h:276
b2World
Definition: b2_world.h:47
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:49
b2Fixture::GetShape
b2Shape * GetShape()
Definition: b2_fixture.h:258
b2ContactEdge
Definition: b2_contact.h:78
b2Contact::GetWorldManifold
void GetWorldManifold(b2WorldManifold *worldManifold) const
Get the world manifold.
Definition: b2_contact.h:254
b2Contact::GetRestitution
float GetRestitution() const
Get the restitution.
Definition: b2_contact.h:351
b2Contact::SetEnabled
void SetEnabled(bool flag)
Definition: b2_contact.h:264