reflexion 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/reflex/application.cpp +2 -0
- data/.doc/ext/reflex/device.cpp +2 -1
- data/.doc/ext/reflex/ellipse_shape.cpp +2 -0
- data/.doc/ext/reflex/filter.cpp +2 -0
- data/.doc/ext/reflex/image_view.cpp +2 -0
- data/.doc/ext/reflex/line_shape.cpp +2 -0
- data/.doc/ext/reflex/midi.cpp +2 -1
- data/.doc/ext/reflex/polygon_shape.cpp +2 -0
- data/.doc/ext/reflex/rect_shape.cpp +2 -0
- data/.doc/ext/reflex/shape.cpp +1 -0
- data/.doc/ext/reflex/timer.cpp +1 -0
- data/.doc/ext/reflex/view.cpp +1 -0
- data/.doc/ext/reflex/window.cpp +2 -0
- data/CLAUDE.md +1 -1
- data/ChangeLog.md +16 -0
- data/Rakefile +3 -2
- data/Reflex.podspec +108 -0
- data/VERSION +1 -1
- data/ext/reflex/application.cpp +2 -0
- data/ext/reflex/device.cpp +2 -1
- data/ext/reflex/ellipse_shape.cpp +2 -0
- data/ext/reflex/filter.cpp +2 -0
- data/ext/reflex/image_view.cpp +2 -0
- data/ext/reflex/line_shape.cpp +2 -0
- data/ext/reflex/midi.cpp +2 -1
- data/ext/reflex/polygon_shape.cpp +2 -0
- data/ext/reflex/rect_shape.cpp +2 -0
- data/ext/reflex/shape.cpp +1 -0
- data/ext/reflex/timer.cpp +1 -0
- data/ext/reflex/view.cpp +1 -0
- data/ext/reflex/window.cpp +2 -0
- data/pod.rake +35 -0
- data/reflex.gemspec +3 -3
- data/src/body.cpp +93 -90
- data/src/body.h +7 -7
- data/src/fixture.cpp +301 -49
- data/src/fixture.h +55 -10
- data/src/osx/app_delegate.mm +6 -4
- data/src/shape.cpp +58 -51
- data/src/shape.h +0 -3
- data/src/timer.cpp +8 -10
- data/src/view.cpp +1 -0
- data/src/world.cpp +301 -128
- data/src/world.h +12 -21
- metadata +10 -8
data/src/world.cpp
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
#include <assert.h>
|
|
5
5
|
#include <memory>
|
|
6
|
-
#include <
|
|
7
|
-
#include <
|
|
8
|
-
#include <
|
|
6
|
+
#include <vector>
|
|
7
|
+
#include <map>
|
|
8
|
+
#include <utility>
|
|
9
|
+
#include <box2d/box2d.h>
|
|
9
10
|
#include "reflex/event.h"
|
|
10
11
|
#include "reflex/exception.h"
|
|
11
12
|
#include "shape.h"
|
|
@@ -21,20 +22,28 @@ namespace Reflex
|
|
|
21
22
|
static constexpr double DELTA_TIME = 1. / 60.;
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
class DebugDraw
|
|
25
|
+
class DebugDraw
|
|
25
26
|
{
|
|
26
27
|
|
|
27
28
|
public:
|
|
28
29
|
|
|
29
30
|
DebugDraw (float ppm)
|
|
30
|
-
: ppm(ppm)
|
|
31
|
+
: ppm(ppm)
|
|
31
32
|
{
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
b2draw = b2DefaultDebugDraw();
|
|
34
|
+
b2draw.DrawPolygonFcn = DrawPolygon;
|
|
35
|
+
b2draw.DrawSolidPolygonFcn = DrawSolidPolygon;
|
|
36
|
+
b2draw.DrawCircleFcn = DrawCircle;
|
|
37
|
+
b2draw.DrawSolidCircleFcn = DrawSolidCircle;
|
|
38
|
+
b2draw.DrawSolidCapsuleFcn = DrawSolidCapsule;
|
|
39
|
+
b2draw.DrawSegmentFcn = DrawSegment;
|
|
40
|
+
b2draw.DrawTransformFcn = DrawTransform;
|
|
41
|
+
b2draw.DrawPointFcn = DrawPoint;
|
|
42
|
+
b2draw.DrawStringFcn = DrawString;
|
|
43
|
+
b2draw.drawShapes = true;
|
|
44
|
+
b2draw.drawJoints = true;
|
|
45
|
+
b2draw.drawMass = true;
|
|
46
|
+
b2draw.context = this;
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
void begin (Painter* painter)
|
|
@@ -49,101 +58,284 @@ namespace Reflex
|
|
|
49
58
|
painter = NULL;
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
|
|
61
|
+
b2DebugDraw* b2ptr ()
|
|
54
62
|
{
|
|
55
|
-
|
|
63
|
+
return &b2draw;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private:
|
|
56
67
|
|
|
57
|
-
|
|
58
|
-
|
|
68
|
+
b2DebugDraw b2draw;
|
|
69
|
+
|
|
70
|
+
float ppm;
|
|
71
|
+
|
|
72
|
+
Painter* painter = NULL;
|
|
73
|
+
|
|
74
|
+
static void set_fill (DebugDraw* draw, b2HexColor color)
|
|
75
|
+
{
|
|
76
|
+
draw->painter->set_fill(
|
|
77
|
+
((color >> 16) & 0xff) / 255.f,
|
|
78
|
+
((color >> 8) & 0xff) / 255.f,
|
|
79
|
+
( color & 0xff) / 255.f,
|
|
80
|
+
0.5f);
|
|
81
|
+
draw->painter->no_stroke();
|
|
82
|
+
}
|
|
59
83
|
|
|
84
|
+
static void set_stroke (DebugDraw* draw, b2HexColor color)
|
|
85
|
+
{
|
|
86
|
+
draw->painter->no_fill();
|
|
87
|
+
draw->painter->set_stroke(
|
|
88
|
+
((color >> 16) & 0xff) / 255.f,
|
|
89
|
+
((color >> 8) & 0xff) / 255.f,
|
|
90
|
+
( color & 0xff) / 255.f,
|
|
91
|
+
0.5f);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static void draw_polygon (
|
|
95
|
+
DebugDraw* draw, const b2Vec2* vertices, int vertexCount)
|
|
96
|
+
{
|
|
60
97
|
std::unique_ptr<Point[]> points(new Point[vertexCount]);
|
|
61
98
|
for (int i = 0; i < vertexCount; ++i)
|
|
62
|
-
points[i] = to_point(vertices[i], ppm);
|
|
99
|
+
points[i] = to_point(vertices[i], draw->ppm);
|
|
63
100
|
|
|
64
|
-
painter->line(&points[0], vertexCount, true);
|
|
101
|
+
draw->painter->line(&points[0], vertexCount, true);
|
|
65
102
|
}
|
|
66
103
|
|
|
67
|
-
void
|
|
68
|
-
const b2Vec2* vertices,
|
|
104
|
+
static void DrawPolygon (
|
|
105
|
+
const b2Vec2* vertices, int vertexCount, b2HexColor color,
|
|
106
|
+
void* context)
|
|
69
107
|
{
|
|
70
|
-
|
|
108
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
109
|
+
assert(draw && draw->painter);
|
|
71
110
|
|
|
72
|
-
|
|
73
|
-
|
|
111
|
+
set_stroke(draw, color);
|
|
112
|
+
draw_polygon(draw, vertices, vertexCount);
|
|
113
|
+
}
|
|
74
114
|
|
|
75
|
-
|
|
115
|
+
static void DrawSolidPolygon (
|
|
116
|
+
b2Transform transform, const b2Vec2* vertices, int vertexCount,
|
|
117
|
+
float radius, b2HexColor color, void* context)
|
|
118
|
+
{
|
|
119
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
120
|
+
assert(draw && draw->painter);
|
|
121
|
+
|
|
122
|
+
std::vector<b2Vec2> points;
|
|
123
|
+
points.reserve(vertexCount);
|
|
76
124
|
for (int i = 0; i < vertexCount; ++i)
|
|
77
|
-
points
|
|
125
|
+
points.emplace_back(b2TransformPoint(transform, vertices[i]));
|
|
78
126
|
|
|
79
|
-
|
|
127
|
+
set_fill(draw, color);
|
|
128
|
+
draw_polygon(draw, &points[0], vertexCount);
|
|
80
129
|
}
|
|
81
130
|
|
|
82
|
-
void DrawCircle (
|
|
83
|
-
|
|
131
|
+
static void DrawCircle (
|
|
132
|
+
b2Vec2 center, float radius, b2HexColor color, void* context)
|
|
84
133
|
{
|
|
85
|
-
|
|
134
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
135
|
+
assert(draw && draw->painter);
|
|
86
136
|
|
|
87
|
-
|
|
88
|
-
painter->
|
|
89
|
-
|
|
137
|
+
set_stroke(draw, color);
|
|
138
|
+
draw->painter->ellipse(
|
|
139
|
+
to_point(center, draw->ppm), to_coord(radius, draw->ppm));
|
|
90
140
|
}
|
|
91
141
|
|
|
92
|
-
void DrawSolidCircle (
|
|
93
|
-
|
|
142
|
+
static void DrawSolidCircle (
|
|
143
|
+
b2Transform transform, float radius, b2HexColor color, void* context)
|
|
94
144
|
{
|
|
95
|
-
|
|
145
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
146
|
+
assert(draw && draw->painter);
|
|
96
147
|
|
|
97
|
-
|
|
98
|
-
painter->
|
|
99
|
-
|
|
148
|
+
set_fill(draw, color);
|
|
149
|
+
draw->painter->ellipse(
|
|
150
|
+
to_point(transform.p, draw->ppm), to_coord(radius, draw->ppm));
|
|
100
151
|
}
|
|
101
152
|
|
|
102
|
-
void
|
|
103
|
-
|
|
153
|
+
static void DrawSolidCapsule (
|
|
154
|
+
b2Vec2 p1, b2Vec2 p2, float radius, b2HexColor color, void* context)
|
|
104
155
|
{
|
|
105
|
-
|
|
156
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
157
|
+
assert(draw && draw->painter);
|
|
158
|
+
|
|
159
|
+
set_fill(draw, color);
|
|
160
|
+
draw->painter->ellipse(
|
|
161
|
+
to_point(p1, draw->ppm), to_coord(radius, draw->ppm));
|
|
162
|
+
draw->painter->ellipse(
|
|
163
|
+
to_point(p2, draw->ppm), to_coord(radius, draw->ppm));
|
|
164
|
+
draw->painter->line(
|
|
165
|
+
to_point(p1, draw->ppm), to_point(p2, draw->ppm));
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static void DrawSegment (
|
|
169
|
+
b2Vec2 p1, b2Vec2 p2, b2HexColor color, void* context)
|
|
170
|
+
{
|
|
171
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
172
|
+
assert(draw && draw->painter);
|
|
106
173
|
|
|
107
|
-
|
|
108
|
-
painter->
|
|
109
|
-
|
|
174
|
+
set_stroke(draw, color);
|
|
175
|
+
draw->painter->line(
|
|
176
|
+
to_point(p1, draw->ppm), to_point(p2, draw->ppm));
|
|
110
177
|
}
|
|
111
178
|
|
|
112
|
-
void DrawPoint (
|
|
179
|
+
static void DrawPoint (
|
|
180
|
+
b2Vec2 p, float size, b2HexColor color, void* context)
|
|
113
181
|
{
|
|
114
|
-
|
|
182
|
+
DebugDraw* draw = (DebugDraw*) context;
|
|
183
|
+
assert(draw && draw->painter);
|
|
115
184
|
|
|
116
|
-
|
|
117
|
-
painter->
|
|
118
|
-
|
|
185
|
+
set_fill(draw, color);
|
|
186
|
+
draw->painter->ellipse(
|
|
187
|
+
to_point(p, draw->ppm), to_coord(size / 2, draw->ppm));
|
|
119
188
|
}
|
|
120
189
|
|
|
121
|
-
void DrawTransform (
|
|
190
|
+
static void DrawTransform (b2Transform transform, void* context)
|
|
122
191
|
{
|
|
123
|
-
assert(painter);
|
|
124
192
|
}
|
|
125
193
|
|
|
126
|
-
|
|
194
|
+
static void DrawString (
|
|
195
|
+
b2Vec2 p, const char* s, b2HexColor color, void* context)
|
|
196
|
+
{
|
|
197
|
+
}
|
|
127
198
|
|
|
128
|
-
|
|
199
|
+
};// DebugDraw
|
|
129
200
|
|
|
130
|
-
Painter* painter;
|
|
131
201
|
|
|
132
|
-
|
|
202
|
+
typedef std::pair<uint64_t, uint64_t> ShapePairKey;
|
|
203
|
+
|
|
204
|
+
typedef std::pair<Shape*, Shape*> ShapePair;
|
|
205
|
+
|
|
206
|
+
typedef std::map<ShapePairKey, ShapePair> ShapePairMap;
|
|
207
|
+
|
|
208
|
+
static ShapePairKey
|
|
209
|
+
make_pair_key (b2ShapeId b2shape1, b2ShapeId b2shape2)
|
|
210
|
+
{
|
|
211
|
+
uint64_t key1 = b2StoreShapeId(b2shape1);
|
|
212
|
+
uint64_t key2 = b2StoreShapeId(b2shape2);
|
|
213
|
+
return key1 < key2
|
|
214
|
+
? std::make_pair(key1, key2)
|
|
215
|
+
: std::make_pair(key2, key1);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
static Shape*
|
|
219
|
+
get_shape (b2ShapeId b2shape)
|
|
220
|
+
{
|
|
221
|
+
if (B2_IS_NULL(b2shape)) return NULL;
|
|
222
|
+
return (Shape*) b2Shape_GetUserData(b2shape);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static bool
|
|
226
|
+
should_collide (Shape* s1, Shape* s2)
|
|
227
|
+
{
|
|
228
|
+
if (!s1 || !s2)
|
|
229
|
+
return false;
|
|
230
|
+
|
|
231
|
+
View* v1 = s1->owner();
|
|
232
|
+
View* v2 = s2->owner();
|
|
233
|
+
if (!v1 || !v2 || !View_is_active(*v1) || !View_is_active(*v2))
|
|
234
|
+
return false;
|
|
235
|
+
|
|
236
|
+
return
|
|
237
|
+
s1->will_contact(s2) &&
|
|
238
|
+
s2->will_contact(s1) &&
|
|
239
|
+
v1->will_contact(v2) &&
|
|
240
|
+
v2->will_contact(v1);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
static bool
|
|
244
|
+
custom_filter_callback (b2ShapeId b2shape1, b2ShapeId b2shape2, void* context)
|
|
245
|
+
{
|
|
246
|
+
return should_collide(get_shape(b2shape1), get_shape(b2shape2));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
static void
|
|
250
|
+
call_contact_events (Shape* s1, Shape* s2, ContactEvent::Action action)
|
|
251
|
+
{
|
|
252
|
+
if (!s1 || !s2)
|
|
253
|
+
return;
|
|
254
|
+
|
|
255
|
+
View* v1 = s1->owner();
|
|
256
|
+
View* v2 = s2->owner();
|
|
257
|
+
if (!v1 || !v2 || !View_is_active(*v1) || !View_is_active(*v2))
|
|
258
|
+
return;
|
|
259
|
+
|
|
260
|
+
ContactEvent e1(action, s2), e2(action, s1);
|
|
261
|
+
Shape_call_contact_event(s1, &e1);
|
|
262
|
+
Shape_call_contact_event(s2, &e2);
|
|
263
|
+
}
|
|
133
264
|
|
|
134
265
|
|
|
135
266
|
struct World::Data
|
|
136
267
|
{
|
|
137
268
|
|
|
138
|
-
|
|
269
|
+
b2WorldId b2world = b2_nullWorldId;
|
|
270
|
+
|
|
271
|
+
float ppm = 0;
|
|
272
|
+
|
|
273
|
+
float time_scale = 1;
|
|
139
274
|
|
|
140
|
-
|
|
275
|
+
bool stepping = false;
|
|
141
276
|
|
|
142
277
|
std::unique_ptr<DebugDraw> debug_draw;
|
|
143
278
|
|
|
144
|
-
|
|
145
|
-
|
|
279
|
+
// tracked to deliver contact-end events for shapes that Box2D has already
|
|
280
|
+
// forgotten on destruction
|
|
281
|
+
ShapePairMap touching_pairs;
|
|
282
|
+
|
|
283
|
+
void begin_contact (b2ShapeId b2shape1, b2ShapeId b2shape2, bool is_sensor_event)
|
|
146
284
|
{
|
|
285
|
+
Shape* s1 = get_shape(b2shape1);
|
|
286
|
+
Shape* s2 = get_shape(b2shape2);
|
|
287
|
+
if (!s1 || !s2)
|
|
288
|
+
return;
|
|
289
|
+
|
|
290
|
+
// Box2D 3.x does not call the custom filter for sensor overlaps,
|
|
291
|
+
// so respect will_contact() here
|
|
292
|
+
if (is_sensor_event && !should_collide(s1, s2))
|
|
293
|
+
return;
|
|
294
|
+
|
|
295
|
+
ShapePairKey key = make_pair_key(b2shape1, b2shape2);
|
|
296
|
+
if (!touching_pairs.emplace(key, ShapePair(s1, s2)).second)
|
|
297
|
+
return;// already touching
|
|
298
|
+
|
|
299
|
+
call_contact_events(s1, s2, ContactEvent::BEGIN);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
void end_contact (b2ShapeId id1, b2ShapeId id2)
|
|
303
|
+
{
|
|
304
|
+
auto it = touching_pairs.find(make_pair_key(id1, id2));
|
|
305
|
+
if (it == touching_pairs.end())
|
|
306
|
+
return;
|
|
307
|
+
|
|
308
|
+
ShapePair pair = it->second;
|
|
309
|
+
touching_pairs.erase(it);
|
|
310
|
+
|
|
311
|
+
call_contact_events(pair.first, pair.second, ContactEvent::END);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
void handle_contact_events ()
|
|
315
|
+
{
|
|
316
|
+
b2ContactEvents contacts = b2World_GetContactEvents(b2world);
|
|
317
|
+
for (int i = 0; i < contacts.beginCount; ++i)
|
|
318
|
+
{
|
|
319
|
+
const auto& e = contacts.beginEvents[i];
|
|
320
|
+
begin_contact(e.shapeIdA, e.shapeIdB, false);
|
|
321
|
+
}
|
|
322
|
+
for (int i = 0; i < contacts.endCount; ++i)
|
|
323
|
+
{
|
|
324
|
+
const auto& e = contacts.endEvents[i];
|
|
325
|
+
end_contact(e.shapeIdA, e.shapeIdB);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
b2SensorEvents sensors = b2World_GetSensorEvents(b2world);
|
|
329
|
+
for (int i = 0; i < sensors.beginCount; ++i)
|
|
330
|
+
{
|
|
331
|
+
const auto& e = sensors.beginEvents[i];
|
|
332
|
+
begin_contact(e.sensorShapeId, e.visitorShapeId, true);
|
|
333
|
+
}
|
|
334
|
+
for (int i = 0; i < sensors.endCount; ++i)
|
|
335
|
+
{
|
|
336
|
+
const auto& e = sensors.endEvents[i];
|
|
337
|
+
end_contact(e.sensorShapeId, e.visitorShapeId);
|
|
338
|
+
}
|
|
147
339
|
}
|
|
148
340
|
|
|
149
341
|
};// World::Data
|
|
@@ -155,14 +347,23 @@ namespace Reflex
|
|
|
155
347
|
|
|
156
348
|
self->ppm = pixels_per_meter;
|
|
157
349
|
|
|
158
|
-
|
|
159
|
-
|
|
350
|
+
b2WorldDef def = b2DefaultWorldDef();
|
|
351
|
+
def.gravity = b2Vec2{0, 0};
|
|
352
|
+
def.userData = this;
|
|
353
|
+
|
|
354
|
+
self->b2world = b2CreateWorld(&def);
|
|
355
|
+
if (!b2World_IsValid(self->b2world))
|
|
356
|
+
physics_error(__FILE__, __LINE__);
|
|
357
|
+
|
|
358
|
+
b2World_SetCustomFilterCallback(self->b2world, custom_filter_callback, this);
|
|
160
359
|
}
|
|
161
360
|
|
|
162
361
|
World::~World ()
|
|
163
362
|
{
|
|
164
|
-
self->
|
|
165
|
-
|
|
363
|
+
self->touching_pairs.clear();
|
|
364
|
+
|
|
365
|
+
b2DestroyWorld(self->b2world);
|
|
366
|
+
self->b2world = b2_nullWorldId;
|
|
166
367
|
}
|
|
167
368
|
|
|
168
369
|
void
|
|
@@ -175,7 +376,13 @@ namespace Reflex
|
|
|
175
376
|
if (count < 1) count = 1;
|
|
176
377
|
|
|
177
378
|
for (int i = 0; i < count; ++i)
|
|
178
|
-
|
|
379
|
+
{
|
|
380
|
+
self->stepping = true;
|
|
381
|
+
b2World_Step(self->b2world, dt, 4);
|
|
382
|
+
self->stepping = false;
|
|
383
|
+
|
|
384
|
+
self->handle_contact_events();
|
|
385
|
+
}
|
|
179
386
|
}
|
|
180
387
|
|
|
181
388
|
float
|
|
@@ -187,17 +394,18 @@ namespace Reflex
|
|
|
187
394
|
void
|
|
188
395
|
World::set_gravity (const Point& gravity)
|
|
189
396
|
{
|
|
190
|
-
b2Vec2
|
|
191
|
-
|
|
397
|
+
b2Vec2 b2vec = to_b2vec2(gravity, self->ppm);
|
|
398
|
+
b2Vec2 current = b2World_GetGravity(self->b2world);
|
|
399
|
+
if (b2vec.x == current.x && b2vec.y == current.y)
|
|
192
400
|
return;
|
|
193
401
|
|
|
194
|
-
self->b2world
|
|
402
|
+
b2World_SetGravity(self->b2world, b2vec);
|
|
195
403
|
}
|
|
196
404
|
|
|
197
405
|
Point
|
|
198
406
|
World::gravity () const
|
|
199
407
|
{
|
|
200
|
-
return to_point(self->b2world
|
|
408
|
+
return to_point(b2World_GetGravity(self->b2world), self->ppm);
|
|
201
409
|
}
|
|
202
410
|
|
|
203
411
|
void
|
|
@@ -218,14 +426,9 @@ namespace Reflex
|
|
|
218
426
|
if (state == debug()) return;
|
|
219
427
|
|
|
220
428
|
if (state)
|
|
221
|
-
{
|
|
222
|
-
assert(!self->debug_draw);
|
|
223
429
|
self->debug_draw.reset(new DebugDraw(self->ppm));
|
|
224
|
-
}
|
|
225
430
|
else
|
|
226
431
|
self->debug_draw.reset();
|
|
227
|
-
|
|
228
|
-
self->b2world.SetDebugDraw(self->debug_draw.get());
|
|
229
432
|
}
|
|
230
433
|
|
|
231
434
|
bool
|
|
@@ -246,65 +449,47 @@ namespace Reflex
|
|
|
246
449
|
if (!self->debug_draw) return;
|
|
247
450
|
|
|
248
451
|
self->debug_draw->begin(painter);
|
|
249
|
-
self->b2world
|
|
452
|
+
b2World_Draw(self->b2world, self->debug_draw->b2ptr());
|
|
250
453
|
self->debug_draw->end();
|
|
251
454
|
}
|
|
252
455
|
|
|
253
|
-
bool
|
|
254
|
-
World::ShouldCollide (b2Fixture* f1, b2Fixture* f2)
|
|
255
|
-
{
|
|
256
|
-
Shape* s1 = (Shape*) f1->GetUserData().pointer;
|
|
257
|
-
Shape* s2 = (Shape*) f2->GetUserData().pointer;
|
|
258
|
-
if (!s1 || !s2)
|
|
259
|
-
return false;
|
|
260
456
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
return
|
|
267
|
-
s1->will_contact(s2) &&
|
|
268
|
-
s2->will_contact(s1) &&
|
|
269
|
-
v1->will_contact(v2) &&
|
|
270
|
-
v2->will_contact(v1);
|
|
457
|
+
b2WorldId
|
|
458
|
+
World_get_id (const World* world)
|
|
459
|
+
{
|
|
460
|
+
return world ? world->self->b2world : b2_nullWorldId;
|
|
271
461
|
}
|
|
272
462
|
|
|
273
|
-
|
|
274
|
-
|
|
463
|
+
bool
|
|
464
|
+
World_is_stepping (const World* world)
|
|
275
465
|
{
|
|
276
|
-
|
|
277
|
-
if (!s1) return;
|
|
278
|
-
|
|
279
|
-
Shape* s2 = (Shape*) contact->GetFixtureB()->GetUserData().pointer;
|
|
280
|
-
if (!s2) return;
|
|
281
|
-
|
|
282
|
-
if (!View_is_active(*s1->owner()) || !View_is_active(*s2->owner()))
|
|
283
|
-
return;
|
|
284
|
-
|
|
285
|
-
ContactEvent e1(ContactEvent::BEGIN, s2), e2(ContactEvent::BEGIN, s1);
|
|
286
|
-
Shape_call_contact_event(s1, &e1);
|
|
287
|
-
Shape_call_contact_event(s2, &e2);
|
|
466
|
+
return world ? world->self->stepping : false;
|
|
288
467
|
}
|
|
289
468
|
|
|
290
469
|
void
|
|
291
|
-
|
|
470
|
+
World_end_contacts_for (World* world, b2ShapeId b2shape)
|
|
292
471
|
{
|
|
293
|
-
|
|
294
|
-
if (!s1) return;
|
|
472
|
+
if (!world) return;
|
|
295
473
|
|
|
296
|
-
|
|
297
|
-
if (!s2) return;
|
|
474
|
+
uint64_t key = b2StoreShapeId(b2shape);
|
|
298
475
|
|
|
299
|
-
|
|
300
|
-
|
|
476
|
+
std::vector<ShapePair> ended;
|
|
477
|
+
auto& pairs = world->self->touching_pairs;
|
|
478
|
+
for (auto it = pairs.begin(); it != pairs.end();)
|
|
479
|
+
{
|
|
480
|
+
if (it->first.first == key || it->first.second == key)
|
|
481
|
+
{
|
|
482
|
+
ended.emplace_back(it->second);
|
|
483
|
+
it = pairs.erase(it);
|
|
484
|
+
}
|
|
485
|
+
else
|
|
486
|
+
++it;
|
|
487
|
+
}
|
|
301
488
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
Shape_call_contact_event(s2, &e2);
|
|
489
|
+
for (auto& pair : ended)
|
|
490
|
+
call_contact_events(pair.first, pair.second, ContactEvent::END);
|
|
305
491
|
}
|
|
306
492
|
|
|
307
|
-
|
|
308
493
|
World*
|
|
309
494
|
World_get_temporary ()
|
|
310
495
|
{
|
|
@@ -312,17 +497,5 @@ namespace Reflex
|
|
|
312
497
|
return &world;
|
|
313
498
|
}
|
|
314
499
|
|
|
315
|
-
b2World*
|
|
316
|
-
World_get_b2ptr (World* world)
|
|
317
|
-
{
|
|
318
|
-
return world ? &world->self->b2world : NULL;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const b2World*
|
|
322
|
-
World_get_b2ptr (const World* world)
|
|
323
|
-
{
|
|
324
|
-
return World_get_b2ptr(const_cast<World*>(world));
|
|
325
|
-
}
|
|
326
|
-
|
|
327
500
|
|
|
328
501
|
}// Reflex
|
data/src/world.h
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
#define __REFLEX_SRC_WORLD_H__
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
#include <box2d/
|
|
8
|
-
#include <box2d/
|
|
7
|
+
#include <box2d/id.h>
|
|
8
|
+
#include <box2d/math_functions.h>
|
|
9
9
|
#include <xot/noncopyable.h>
|
|
10
10
|
#include <xot/pimpl.h>
|
|
11
11
|
#include <rays/point.h>
|
|
@@ -13,9 +13,6 @@
|
|
|
13
13
|
#include "reflex/defs.h"
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class b2World;
|
|
17
|
-
|
|
18
|
-
|
|
19
16
|
namespace Reflex
|
|
20
17
|
{
|
|
21
18
|
|
|
@@ -24,7 +21,7 @@ namespace Reflex
|
|
|
24
21
|
class Body;
|
|
25
22
|
|
|
26
23
|
|
|
27
|
-
class World : public Xot::NonCopyable
|
|
24
|
+
class World : public Xot::NonCopyable
|
|
28
25
|
{
|
|
29
26
|
|
|
30
27
|
public:
|
|
@@ -62,14 +59,6 @@ namespace Reflex
|
|
|
62
59
|
|
|
63
60
|
Xot::PImpl<Data> self;
|
|
64
61
|
|
|
65
|
-
protected:
|
|
66
|
-
|
|
67
|
-
virtual bool ShouldCollide (b2Fixture* f1, b2Fixture* f2) override;
|
|
68
|
-
|
|
69
|
-
virtual void BeginContact (b2Contact* contact) override;
|
|
70
|
-
|
|
71
|
-
virtual void EndContact (b2Contact* contact) override;
|
|
72
|
-
|
|
73
62
|
};// World
|
|
74
63
|
|
|
75
64
|
|
|
@@ -84,18 +73,18 @@ namespace Reflex
|
|
|
84
73
|
inline b2Vec2
|
|
85
74
|
to_b2vec2 (T x, T y, float scale)
|
|
86
75
|
{
|
|
87
|
-
return b2Vec2
|
|
76
|
+
return b2Vec2{
|
|
88
77
|
to_b2coord(x, scale),
|
|
89
|
-
to_b2coord(y, scale)
|
|
78
|
+
to_b2coord(y, scale)};
|
|
90
79
|
}
|
|
91
80
|
|
|
92
81
|
template <typename VEC>
|
|
93
82
|
inline b2Vec2
|
|
94
83
|
to_b2vec2 (const VEC& v, float scale)
|
|
95
84
|
{
|
|
96
|
-
return b2Vec2
|
|
85
|
+
return b2Vec2{
|
|
97
86
|
to_b2coord(v.x, scale),
|
|
98
|
-
to_b2coord(v.y, scale)
|
|
87
|
+
to_b2coord(v.y, scale)};
|
|
99
88
|
}
|
|
100
89
|
|
|
101
90
|
inline coord
|
|
@@ -113,11 +102,13 @@ namespace Reflex
|
|
|
113
102
|
}
|
|
114
103
|
|
|
115
104
|
|
|
116
|
-
World*
|
|
105
|
+
b2WorldId World_get_id (const World* world);
|
|
117
106
|
|
|
118
|
-
|
|
107
|
+
bool World_is_stepping (const World* world);
|
|
119
108
|
|
|
120
|
-
|
|
109
|
+
void World_end_contacts_for (World* world, b2ShapeId b2shape);
|
|
110
|
+
|
|
111
|
+
World* World_get_temporary ();
|
|
121
112
|
|
|
122
113
|
|
|
123
114
|
}// Reflex
|