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
147
148
149
150
151
152
153
154
155
156
157
// 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,
// One of the shapes is a sensor
b2_contactSensorFlag = 0x0000004,
// Set when a sensor is touching
// todo this is not used, perhaps have b2Body_GetSensorContactData()
b2_contactSensorTouchingFlag = 0x00000008,
// This contact wants sensor events
b2_contactEnableSensorEvents = 0x00000010,
// This contact wants contact events
b2_contactEnableContactEvents = 0x00000020,
};
// 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;
b2ContactEdge edges[2];
int shapeIdA;
int shapeIdB;
// A contact only belongs to an island if touching, otherwise B2_NULL_INDEX.
int islandPrev;
int islandNext;
int islandId;
int contactId;
// b2ContactFlags
uint32_t flags;
bool isMarked;
} b2Contact;
// Shifted to be distinct from b2ContactFlags
enum b2ContactSimFlags
{
// Set when the shapes are touching, including sensors
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
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;
// todo for conveyor belts
float tangentSpeed;
// b2ContactSimFlags
uint32_t simFlags;
b2DistanceCache 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 b2ShouldShapesCollide( b2Filter filterA, b2Filter filterB );
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 );