1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-FileCopyrightText: 2023 Erin Catto
// SPDX-License-Identifier: MIT
#pragma once
#include "array.h"
#include "core.h"
#include "box2d/collision.h"
#include "box2d/types.h"
typedef struct b2Shape b2Shape;
typedef struct b2World b2World;
enum b2ContactFlags
{
// Set when the solid shapes are touching.
b2_contactTouchingFlag = 0x00000001,
// Contact has a hit event
b2_contactHitEventFlag = 0x00000002,
// This contact wants contact events
b2_contactEnableContactEvents = 0x00000004,
};
// A contact edge is used to connect bodies and contacts together
// in a contact graph where each body is a node and each contact
// is an edge. A contact edge belongs to a doubly linked list
// maintained in each attached body. Each contact has two contact
// edges, one for each attached body.
typedef struct b2ContactEdge
{
int bodyId;
int prevKey;
int nextKey;
} b2ContactEdge;
// Cold contact data. Used as a persistent handle and for persistent island
// connectivity.
typedef struct b2Contact
{
// index of simulation set stored in b2World
// B2_NULL_INDEX when slot is free
int setIndex;
// index into the constraint graph color array
// B2_NULL_INDEX for non-touching or sleeping contacts
// B2_NULL_INDEX when slot is free
int colorIndex;
// contact index within set or graph color
// B2_NULL_INDEX when slot is free
int localIndex;
int shapeIdA;
int shapeIdB;
int contactId;
// A contact only belongs to an island if touching, otherwise B2_NULL_INDEX.
b2ContactEdge edges[2];
int islandPrev;
int islandNext;
int islandId;
// b2ContactFlags
uint32_t flags;
// This is monotonically advanced when a contact is allocated in this slot
// Used to check for invalid b2ContactId
uint32_t generation;
} b2Contact;
// Shifted to be distinct from b2ContactFlags
enum b2ContactSimFlags
{
// Set when the shapes are touching
b2_simTouchingFlag = 0x00010000,
// This contact no longer has overlapping AABBs
b2_simDisjoint = 0x00020000,
// This contact started touching
b2_simStartedTouching = 0x00040000,
// This contact stopped touching
b2_simStoppedTouching = 0x00080000,
// This contact has a hit event
b2_simEnableHitEvent = 0x00100000,
// This contact wants pre-solve events
b2_simEnablePreSolveEvents = 0x00200000,
};
/// The class manages contact between two shapes. A contact exists for each overlapping
/// AABB in the broad-phase (except if filtered). Therefore a contact object may exist
/// that has no contact points.
typedef struct b2ContactSim
{
int contactId;
#if B2_VALIDATE
int bodyIdA;
int bodyIdB;
#endif
// Transient body indices
int bodySimIndexA;
int bodySimIndexB;
int shapeIdA;
int shapeIdB;
float invMassA;
float invIA;
float invMassB;
float invIB;
b2Manifold manifold;
// Mixed friction and restitution
float friction;
float restitution;
float rollingResistance;
float tangentSpeed;
// b2ContactSimFlags
uint32_t simFlags;
b2SimplexCache cache;
} b2ContactSim;
void b2InitializeContactRegisters( void );
void b2CreateContact( b2World* world, b2Shape* shapeA, b2Shape* shapeB );
void b2DestroyContact( b2World* world, b2Contact* contact, bool wakeBodies );
b2ContactSim* b2GetContactSim( b2World* world, b2Contact* contact );
bool b2UpdateContact( b2World* world, b2ContactSim* contactSim, b2Shape* shapeA, b2Transform transformA, b2Vec2 centerOffsetA,
b2Shape* shapeB, b2Transform transformB, b2Vec2 centerOffsetB );
B2_ARRAY_INLINE( b2Contact, b2Contact )
B2_ARRAY_INLINE( b2ContactSim, b2ContactSim )