6
6
#include "array.h"
7
7
#include "body.h"
8
8
#include "contact.h"
9
+ #include "ctz.h"
9
10
#include "shape.h"
10
11
#include "world.h"
11
12
14
15
#include <stddef.h>
15
16
#include <stdlib.h>
16
17
17
- B2_ARRAY_SOURCE (b2Sensor , b2Sensor );
18
+ B2_ARRAY_SOURCE ( b2Sensor , b2Sensor );
18
19
19
20
struct b2SensorTaskContext
20
21
{
@@ -48,6 +49,8 @@ struct b2SensorQueryContext
48
49
49
50
static bool b2SensorQueryCallback ( int proxyId , int shapeId , void * context )
50
51
{
52
+ B2_MAYBE_UNUSED ( proxyId );
53
+
51
54
struct b2SensorQueryContext * queryContext = context ;
52
55
b2Shape * sensorShape = queryContext -> sensorShape ;
53
56
int sensorShapeId = sensorShape -> id ;
@@ -109,19 +112,19 @@ static int b2CompareShapeRefs( const void* a, const void* b )
109
112
const b2ShapeRef * sa = a ;
110
113
const b2ShapeRef * sb = b ;
111
114
112
- if (sa -> shapeId < sb -> shapeId )
115
+ if ( sa -> shapeId < sb -> shapeId )
113
116
{
114
117
return -1 ;
115
118
}
116
119
117
- if (sa -> shapeId == sb -> shapeId )
120
+ if ( sa -> shapeId == sb -> shapeId )
118
121
{
119
- if (sa -> generation < sb -> generation )
122
+ if ( sa -> generation < sb -> generation )
120
123
{
121
124
return -1 ;
122
125
}
123
-
124
- if (sa -> generation == sb -> generation )
126
+
127
+ if ( sa -> generation == sb -> generation )
125
128
{
126
129
return 0 ;
127
130
}
@@ -130,11 +133,6 @@ static int b2CompareShapeRefs( const void* a, const void* b )
130
133
return 1 ;
131
134
}
132
135
133
- static bool b2AreShapeRefsEqual (const b2ShapeRef * a , const b2ShapeRef * b )
134
- {
135
- return a -> shapeId == b -> shapeId && a -> generation == b -> generation ;
136
- }
137
-
138
136
void b2OverlapSensors ( b2World * world )
139
137
{
140
138
int sensorCount = world -> sensors .count ;
@@ -182,34 +180,122 @@ void b2OverlapSensors( b2World* world )
182
180
183
181
int count1 = sensor -> overlaps1 .count ;
184
182
int count2 = sensor -> overlaps2 .count ;
185
- int index1 = 0 , index2 = 0 ;
186
- while (index1 < count1 && index2 < count2 )
183
+ if ( count1 != count2 )
187
184
{
188
- b2ShapeRef * s1 = sensor -> overlaps1 .data + index1 ;
189
- b2ShapeRef * s2 = sensor -> overlaps2 .data + index2 ;
190
-
191
- if ( s1 -> shapeId == s2 -> shapeId && s1 -> generation == s2 -> generation )
185
+ // something changed
186
+ b2SetBit ( & taskContext .sensorEventBits , sensorIndex );
187
+ }
188
+ else
189
+ {
190
+ for ( int i = 0 ; i < count1 ; ++ i )
192
191
{
193
- index1 += 1 ;
194
- index2 += 1 ;
192
+ b2ShapeRef * s1 = sensor -> overlaps1 .data + i ;
193
+ b2ShapeRef * s2 = sensor -> overlaps2 .data + i ;
194
+
195
+ if ( s1 -> shapeId != s2 -> shapeId || s1 -> generation != s2 -> generation )
196
+ {
197
+ // something changed
198
+ b2SetBit ( & taskContext .sensorEventBits , sensorIndex );
199
+ break ;
200
+ }
195
201
}
196
- else
202
+ }
203
+ }
204
+
205
+ // Iterate sensors bits and publish events
206
+ // Process contact state changes. Iterate over set bits
207
+ uint64_t * bits = taskContext .sensorEventBits .bits ;
208
+ uint32_t blockCount = taskContext .sensorEventBits .blockCount ;
209
+
210
+ for ( uint32_t k = 0 ; k < blockCount ; ++ k )
211
+ {
212
+ uint64_t word = bits [k ];
213
+ while ( word != 0 )
214
+ {
215
+ uint32_t ctz = b2CTZ64 ( word );
216
+ int sensorIndex = (int )( 64 * k + ctz );
217
+
218
+ b2Sensor * sensor = b2SensorArray_Get ( & world -> sensors , sensorIndex );
219
+ b2Shape * sensorShape = b2ShapeArray_Get ( & world -> shapes , sensor -> shapeId );
220
+ b2ShapeId sensorId = { sensor -> shapeId + 1 , world -> worldId , sensorShape -> generation };
221
+
222
+ int count1 = sensor -> overlaps1 .count ;
223
+ int count2 = sensor -> overlaps2 .count ;
224
+ const b2ShapeRef * refs1 = sensor -> overlaps1 .data ;
225
+ const b2ShapeRef * refs2 = sensor -> overlaps2 .data ;
226
+
227
+ // overlaps1 can have overlaps that end
228
+ // overlaps2 can have overlaps that begin
229
+ int index1 = 0 , index2 = 0 ;
230
+ while ( index1 < count1 && index2 < count2 )
197
231
{
198
- b2SetBit ( & taskContext .sensorEventBits , sensorIndex );
232
+ const b2ShapeRef * r1 = refs1 + index1 ;
233
+ const b2ShapeRef * r2 = refs2 + index2 ;
234
+ if ( r1 -> shapeId == r2 -> shapeId )
235
+ {
236
+ if ( r1 -> generation < r2 -> generation )
237
+ {
238
+ // end
239
+ b2ShapeId visitorId = { r1 -> shapeId + 1 , world -> worldId , r1 -> generation };
240
+ b2SensorEndTouchEvent event = { sensorId , visitorId };
241
+ b2SensorEndTouchEventArray_Push ( & world -> sensorEndEvents [world -> endEventArrayIndex ], event );
242
+ index1 += 1 ;
243
+ }
244
+ else if ( r1 -> generation > r2 -> generation )
245
+ {
246
+ // begin
247
+ b2ShapeId visitorId = { r2 -> shapeId + 1 , world -> worldId , r2 -> generation };
248
+ b2SensorBeginTouchEvent event = { sensorId , visitorId };
249
+ b2SensorBeginTouchEventArray_Push ( & world -> sensorBeginEvents , event );
250
+ index2 += 1 ;
251
+ }
252
+ else
253
+ {
254
+ // persisted
255
+ index1 += 1 ;
256
+ index2 += 1 ;
257
+ }
258
+ }
259
+ else if ( r1 -> shapeId < r2 -> shapeId )
260
+ {
261
+ // end
262
+ b2ShapeId visitorId = { r1 -> shapeId + 1 , world -> worldId , r1 -> generation };
263
+ b2SensorEndTouchEvent event = { sensorId , visitorId };
264
+ b2SensorEndTouchEventArray_Push ( & world -> sensorEndEvents [world -> endEventArrayIndex ], event );
265
+ index1 += 1 ;
266
+ }
267
+ else
268
+ {
269
+ // begin
270
+ b2ShapeId visitorId = { r2 -> shapeId + 1 , world -> worldId , r2 -> generation };
271
+ b2SensorBeginTouchEvent event = { sensorId , visitorId };
272
+ b2SensorBeginTouchEventArray_Push ( & world -> sensorBeginEvents , event );
273
+ index2 += 1 ;
274
+ }
275
+ }
199
276
200
- // Begin event
201
- b2BitSet_Set ( & taskContext .sensorEventBits , sensorIndex );
277
+ while ( index1 < count1 )
278
+ {
279
+ // end
280
+ const b2ShapeRef * r1 = refs1 + index1 ;
281
+ b2ShapeId visitorId = { r1 -> shapeId + 1 , world -> worldId , r1 -> generation };
282
+ b2SensorEndTouchEvent event = { sensorId , visitorId };
283
+ b2SensorEndTouchEventArray_Push ( & world -> sensorEndEvents [world -> endEventArrayIndex ], event );
202
284
index1 += 1 ;
203
285
}
204
- else
286
+
287
+ while ( index2 < count2 )
205
288
{
289
+ // begin
290
+ const b2ShapeRef * r2 = refs2 + index2 ;
291
+ b2ShapeId visitorId = { r2 -> shapeId + 1 , world -> worldId , r2 -> generation };
292
+ b2SensorBeginTouchEvent event = { sensorId , visitorId };
293
+ b2SensorBeginTouchEventArray_Push ( & world -> sensorBeginEvents , event );
206
294
index2 += 1 ;
207
295
}
208
296
}
209
- for (int index1 = 0 ; index1 < count1 ; ++ index1 )
210
- {
211
- }
212
- }
213
297
214
- // Iterate sensors bits and publish events
298
+ // Clear the smallest set bit
299
+ word = word & ( word - 1 );
300
+ }
215
301
}
0 commit comments