Skip to content

Commit b07334b

Browse files
committed
begin and end sensor events
1 parent 5b72136 commit b07334b

File tree

2 files changed

+153
-29
lines changed

2 files changed

+153
-29
lines changed

samples/sample_stacking.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,43 @@
1616
class SingleBox : public Sample
1717
{
1818
public:
19+
#if 1
20+
explicit SingleBox( Settings& settings )
21+
: Sample( settings )
22+
{
23+
// todo_erin test me
24+
// https://discord.com/channels/460295137705197568/1064661081903075429/1330362522888437814
25+
assert( false );
26+
27+
if ( settings.restart == false )
28+
{
29+
g_camera.m_center = { 0.0f, 2.5f };
30+
g_camera.m_zoom = 3.5f;
31+
}
32+
33+
float extent = 0.5f;
34+
35+
{
36+
b2BodyDef bodyDef = b2DefaultBodyDef();
37+
b2Polygon box = b2MakeBox( extent, extent );
38+
bodyDef.position = { 0.0f, 20.0f };
39+
;
40+
bodyDef.type = b2_dynamicBody;
41+
b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );
42+
b2ShapeDef shapeDef = b2DefaultShapeDef();
43+
b2CreatePolygonShape( bodyId, &shapeDef, &box );
44+
}
45+
{
46+
b2BodyDef bodyDef = b2DefaultBodyDef();
47+
b2Polygon box = b2MakeBox( extent, extent );
48+
bodyDef.position = { 0.0f, 0.0f };
49+
bodyDef.type = b2_staticBody;
50+
b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );
51+
b2ShapeDef shapeDef = b2DefaultShapeDef();
52+
b2CreatePolygonShape( bodyId, &shapeDef, &box );
53+
}
54+
}
55+
#else
1956
explicit SingleBox( Settings& settings )
2057
: Sample( settings )
2158
{
@@ -43,6 +80,7 @@ class SingleBox : public Sample
4380
b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );
4481
b2CreatePolygonShape( bodyId, &shapeDef, &box );
4582
}
83+
#endif
4684

4785
void Step( Settings& settings ) override
4886
{

src/sensor.c

+115-29
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "array.h"
77
#include "body.h"
88
#include "contact.h"
9+
#include "ctz.h"
910
#include "shape.h"
1011
#include "world.h"
1112

@@ -14,7 +15,7 @@
1415
#include <stddef.h>
1516
#include <stdlib.h>
1617

17-
B2_ARRAY_SOURCE(b2Sensor, b2Sensor);
18+
B2_ARRAY_SOURCE( b2Sensor, b2Sensor );
1819

1920
struct b2SensorTaskContext
2021
{
@@ -48,6 +49,8 @@ struct b2SensorQueryContext
4849

4950
static bool b2SensorQueryCallback( int proxyId, int shapeId, void* context )
5051
{
52+
B2_MAYBE_UNUSED( proxyId );
53+
5154
struct b2SensorQueryContext* queryContext = context;
5255
b2Shape* sensorShape = queryContext->sensorShape;
5356
int sensorShapeId = sensorShape->id;
@@ -109,19 +112,19 @@ static int b2CompareShapeRefs( const void* a, const void* b )
109112
const b2ShapeRef* sa = a;
110113
const b2ShapeRef* sb = b;
111114

112-
if (sa->shapeId < sb->shapeId)
115+
if ( sa->shapeId < sb->shapeId )
113116
{
114117
return -1;
115118
}
116119

117-
if (sa->shapeId == sb->shapeId)
120+
if ( sa->shapeId == sb->shapeId )
118121
{
119-
if (sa->generation < sb->generation)
122+
if ( sa->generation < sb->generation )
120123
{
121124
return -1;
122125
}
123-
124-
if (sa->generation == sb->generation)
126+
127+
if ( sa->generation == sb->generation )
125128
{
126129
return 0;
127130
}
@@ -130,11 +133,6 @@ static int b2CompareShapeRefs( const void* a, const void* b )
130133
return 1;
131134
}
132135

133-
static bool b2AreShapeRefsEqual(const b2ShapeRef* a, const b2ShapeRef* b)
134-
{
135-
return a->shapeId == b->shapeId && a->generation == b->generation;
136-
}
137-
138136
void b2OverlapSensors( b2World* world )
139137
{
140138
int sensorCount = world->sensors.count;
@@ -182,34 +180,122 @@ void b2OverlapSensors( b2World* world )
182180

183181
int count1 = sensor->overlaps1.count;
184182
int count2 = sensor->overlaps2.count;
185-
int index1 = 0, index2 = 0;
186-
while (index1 < count1 && index2 < count2)
183+
if ( count1 != count2 )
187184
{
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 )
192191
{
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+
}
195201
}
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 )
197231
{
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+
}
199276

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 );
202284
index1 += 1;
203285
}
204-
else
286+
287+
while ( index2 < count2 )
205288
{
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 );
206294
index2 += 1;
207295
}
208296
}
209-
for (int index1 = 0; index1 < count1; ++index1)
210-
{
211-
}
212-
}
213297

214-
// Iterate sensors bits and publish events
298+
// Clear the smallest set bit
299+
word = word & ( word - 1 );
300+
}
215301
}

0 commit comments

Comments
 (0)