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

| 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 {
73 b2Body* other;
74 b2Contact* contact;
75 b2ContactEdge* prev;
76 b2ContactEdge* next;
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
227 inline b2Manifold* b2Contact::GetManifold()
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
269 inline b2Contact* b2Contact::GetNext()
270 {
271 return m_next;
272 }
273
274 inline const b2Contact* b2Contact::GetNext() const
275 {
276 return m_next;
277 }
278
279 inline b2Fixture* b2Contact::GetFixtureA()
280 {
281 return m_fixtureA;
282 }
283
284 inline const b2Fixture* b2Contact::GetFixtureA() const
285 {
286 return m_fixtureA;
287 }
288
289 inline b2Fixture* b2Contact::GetFixtureB()
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
309 inline void b2Contact::FlagForFiltering()
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
324 inline void b2Contact::ResetFriction()
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
339 inline void b2Contact::ResetRestitution()
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