box2d-ruby 1.0.0
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +336 -0
- data/examples/contact_events.rb +22 -0
- data/examples/debug_draw.rb +15 -0
- data/examples/falling_ball.rb +19 -0
- data/examples/rugl_debug_draw.rb +68 -0
- data/examples/stagecraft_debug_draw.rb +64 -0
- data/examples/support/box2d_debug_lines.rb +125 -0
- data/ext/box2d/CMakeLists.txt +35 -0
- data/ext/box2d/extconf.rb +42 -0
- data/ext/box2d/native.c +9 -0
- data/ext/box2d/vendor/box2d/LICENSE +21 -0
- data/ext/box2d/vendor/box2d/VERSION +1 -0
- data/ext/box2d/vendor/box2d/include/box2d/base.h +131 -0
- data/ext/box2d/vendor/box2d/include/box2d/box2d.h +1222 -0
- data/ext/box2d/vendor/box2d/include/box2d/collision.h +830 -0
- data/ext/box2d/vendor/box2d/include/box2d/id.h +144 -0
- data/ext/box2d/vendor/box2d/include/box2d/math_functions.h +761 -0
- data/ext/box2d/vendor/box2d/include/box2d/types.h +1457 -0
- data/ext/box2d/vendor/box2d/src/CMakeLists.txt +223 -0
- data/ext/box2d/vendor/box2d/src/aabb.c +132 -0
- data/ext/box2d/vendor/box2d/src/aabb.h +56 -0
- data/ext/box2d/vendor/box2d/src/arena_allocator.c +112 -0
- data/ext/box2d/vendor/box2d/src/arena_allocator.h +48 -0
- data/ext/box2d/vendor/box2d/src/array.c +8 -0
- data/ext/box2d/vendor/box2d/src/array.h +179 -0
- data/ext/box2d/vendor/box2d/src/atomic.h +79 -0
- data/ext/box2d/vendor/box2d/src/bitset.c +67 -0
- data/ext/box2d/vendor/box2d/src/bitset.h +65 -0
- data/ext/box2d/vendor/box2d/src/body.c +1884 -0
- data/ext/box2d/vendor/box2d/src/body.h +194 -0
- data/ext/box2d/vendor/box2d/src/box2d.natvis +41 -0
- data/ext/box2d/vendor/box2d/src/broad_phase.c +524 -0
- data/ext/box2d/vendor/box2d/src/broad_phase.h +83 -0
- data/ext/box2d/vendor/box2d/src/constants.h +54 -0
- data/ext/box2d/vendor/box2d/src/constraint_graph.c +322 -0
- data/ext/box2d/vendor/box2d/src/constraint_graph.h +58 -0
- data/ext/box2d/vendor/box2d/src/contact.c +650 -0
- data/ext/box2d/vendor/box2d/src/contact.h +148 -0
- data/ext/box2d/vendor/box2d/src/contact_solver.c +2120 -0
- data/ext/box2d/vendor/box2d/src/contact_solver.h +54 -0
- data/ext/box2d/vendor/box2d/src/core.c +178 -0
- data/ext/box2d/vendor/box2d/src/core.h +149 -0
- data/ext/box2d/vendor/box2d/src/ctz.h +112 -0
- data/ext/box2d/vendor/box2d/src/distance.c +1415 -0
- data/ext/box2d/vendor/box2d/src/distance_joint.c +556 -0
- data/ext/box2d/vendor/box2d/src/dynamic_tree.c +1989 -0
- data/ext/box2d/vendor/box2d/src/geometry.c +1028 -0
- data/ext/box2d/vendor/box2d/src/hull.c +328 -0
- data/ext/box2d/vendor/box2d/src/id_pool.c +79 -0
- data/ext/box2d/vendor/box2d/src/id_pool.h +35 -0
- data/ext/box2d/vendor/box2d/src/island.c +977 -0
- data/ext/box2d/vendor/box2d/src/island.h +89 -0
- data/ext/box2d/vendor/box2d/src/joint.c +1272 -0
- data/ext/box2d/vendor/box2d/src/joint.h +335 -0
- data/ext/box2d/vendor/box2d/src/manifold.c +1726 -0
- data/ext/box2d/vendor/box2d/src/math_functions.c +159 -0
- data/ext/box2d/vendor/box2d/src/motor_joint.c +283 -0
- data/ext/box2d/vendor/box2d/src/mouse_joint.c +214 -0
- data/ext/box2d/vendor/box2d/src/mover.c +73 -0
- data/ext/box2d/vendor/box2d/src/prismatic_joint.c +656 -0
- data/ext/box2d/vendor/box2d/src/revolute_joint.c +534 -0
- data/ext/box2d/vendor/box2d/src/sensor.c +389 -0
- data/ext/box2d/vendor/box2d/src/sensor.h +36 -0
- data/ext/box2d/vendor/box2d/src/shape.c +1714 -0
- data/ext/box2d/vendor/box2d/src/shape.h +123 -0
- data/ext/box2d/vendor/box2d/src/solver.c +2038 -0
- data/ext/box2d/vendor/box2d/src/solver.h +155 -0
- data/ext/box2d/vendor/box2d/src/solver_set.c +613 -0
- data/ext/box2d/vendor/box2d/src/solver_set.h +57 -0
- data/ext/box2d/vendor/box2d/src/table.c +238 -0
- data/ext/box2d/vendor/box2d/src/table.h +37 -0
- data/ext/box2d/vendor/box2d/src/timer.c +185 -0
- data/ext/box2d/vendor/box2d/src/types.c +151 -0
- data/ext/box2d/vendor/box2d/src/weld_joint.c +310 -0
- data/ext/box2d/vendor/box2d/src/wheel_joint.c +551 -0
- data/ext/box2d/vendor/box2d/src/world.c +3301 -0
- data/ext/box2d/vendor/box2d/src/world.h +192 -0
- data/generator/generate.rb +316 -0
- data/generator/layout_probe.c +507 -0
- data/generator/verify_layouts.rb +32 -0
- data/lib/box2d/body.rb +172 -0
- data/lib/box2d/body_definition.rb +38 -0
- data/lib/box2d/body_shapes.rb +135 -0
- data/lib/box2d/chain.rb +61 -0
- data/lib/box2d/debug_draw.rb +118 -0
- data/lib/box2d/events.rb +103 -0
- data/lib/box2d/fixed_stepper.rb +39 -0
- data/lib/box2d/handle.rb +46 -0
- data/lib/box2d/hit.rb +5 -0
- data/lib/box2d/joint.rb +197 -0
- data/lib/box2d/native.rb +1462 -0
- data/lib/box2d/native_loader.rb +45 -0
- data/lib/box2d/pixel_scale.rb +29 -0
- data/lib/box2d/shape.rb +109 -0
- data/lib/box2d/shape_definition.rb +44 -0
- data/lib/box2d/value_conversion.rb +80 -0
- data/lib/box2d/version.rb +7 -0
- data/lib/box2d/world.rb +135 -0
- data/lib/box2d/world_joints.rb +156 -0
- data/lib/box2d/world_queries.rb +122 -0
- data/lib/box2d/world_registry.rb +95 -0
- data/lib/box2d.rb +31 -0
- data/script/build_platform_gem.rb +24 -0
- data/script/deterministic_scene.rb +56 -0
- data/script/update_deterministic_snapshot.rb +11 -0
- data/script/verify_platform_gem.rb +24 -0
- metadata +164 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2023 Erin Catto
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
#include "constants.h"
|
|
5
|
+
#include "core.h"
|
|
6
|
+
|
|
7
|
+
#include "box2d/collision.h"
|
|
8
|
+
#include "box2d/math_functions.h"
|
|
9
|
+
|
|
10
|
+
#include <float.h>
|
|
11
|
+
|
|
12
|
+
// quickhull recursion
|
|
13
|
+
static b2Hull b2RecurseHull( b2Vec2 p1, b2Vec2 p2, b2Vec2* ps, int count )
|
|
14
|
+
{
|
|
15
|
+
b2Hull hull;
|
|
16
|
+
hull.count = 0;
|
|
17
|
+
|
|
18
|
+
if ( count == 0 )
|
|
19
|
+
{
|
|
20
|
+
return hull;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// create an edge vector pointing from p1 to p2
|
|
24
|
+
b2Vec2 e = b2Normalize( b2Sub( p2, p1 ) );
|
|
25
|
+
|
|
26
|
+
// discard points left of e and find point furthest to the right of e
|
|
27
|
+
b2Vec2 rightPoints[B2_MAX_POLYGON_VERTICES];
|
|
28
|
+
int rightCount = 0;
|
|
29
|
+
|
|
30
|
+
int bestIndex = 0;
|
|
31
|
+
float bestDistance = b2Cross( b2Sub( ps[bestIndex], p1 ), e );
|
|
32
|
+
if ( bestDistance > 0.0f )
|
|
33
|
+
{
|
|
34
|
+
rightPoints[rightCount++] = ps[bestIndex];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for ( int i = 1; i < count; ++i )
|
|
38
|
+
{
|
|
39
|
+
float distance = b2Cross( b2Sub( ps[i], p1 ), e );
|
|
40
|
+
if ( distance > bestDistance )
|
|
41
|
+
{
|
|
42
|
+
bestIndex = i;
|
|
43
|
+
bestDistance = distance;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if ( distance > 0.0f )
|
|
47
|
+
{
|
|
48
|
+
rightPoints[rightCount++] = ps[i];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if ( bestDistance < 2.0f * B2_LINEAR_SLOP )
|
|
53
|
+
{
|
|
54
|
+
return hull;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
b2Vec2 bestPoint = ps[bestIndex];
|
|
58
|
+
|
|
59
|
+
// compute hull to the right of p1-bestPoint
|
|
60
|
+
b2Hull hull1 = b2RecurseHull( p1, bestPoint, rightPoints, rightCount );
|
|
61
|
+
|
|
62
|
+
// compute hull to the right of bestPoint-p2
|
|
63
|
+
b2Hull hull2 = b2RecurseHull( bestPoint, p2, rightPoints, rightCount );
|
|
64
|
+
|
|
65
|
+
// stitch together hulls
|
|
66
|
+
for ( int i = 0; i < hull1.count; ++i )
|
|
67
|
+
{
|
|
68
|
+
hull.points[hull.count++] = hull1.points[i];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
hull.points[hull.count++] = bestPoint;
|
|
72
|
+
|
|
73
|
+
for ( int i = 0; i < hull2.count; ++i )
|
|
74
|
+
{
|
|
75
|
+
hull.points[hull.count++] = hull2.points[i];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
B2_ASSERT( hull.count < B2_MAX_POLYGON_VERTICES );
|
|
79
|
+
|
|
80
|
+
return hull;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// quickhull algorithm
|
|
84
|
+
// - merges vertices based on B2_LINEAR_SLOP
|
|
85
|
+
// - removes collinear points using B2_LINEAR_SLOP
|
|
86
|
+
// - returns an empty hull if it fails
|
|
87
|
+
b2Hull b2ComputeHull( const b2Vec2* points, int count )
|
|
88
|
+
{
|
|
89
|
+
b2Hull hull;
|
|
90
|
+
hull.count = 0;
|
|
91
|
+
|
|
92
|
+
if ( count < 3 || count > B2_MAX_POLYGON_VERTICES )
|
|
93
|
+
{
|
|
94
|
+
// check your data
|
|
95
|
+
return hull;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
count = b2MinInt( count, B2_MAX_POLYGON_VERTICES );
|
|
99
|
+
|
|
100
|
+
b2AABB aabb = { { FLT_MAX, FLT_MAX }, { -FLT_MAX, -FLT_MAX } };
|
|
101
|
+
|
|
102
|
+
// Perform aggressive point welding. First point always remains.
|
|
103
|
+
// Also compute the bounding box for later.
|
|
104
|
+
b2Vec2 ps[B2_MAX_POLYGON_VERTICES];
|
|
105
|
+
int n = 0;
|
|
106
|
+
const float linearSlop = B2_LINEAR_SLOP;
|
|
107
|
+
const float tolSqr = 16.0f * linearSlop * linearSlop;
|
|
108
|
+
for ( int i = 0; i < count; ++i )
|
|
109
|
+
{
|
|
110
|
+
aabb.lowerBound = b2Min( aabb.lowerBound, points[i] );
|
|
111
|
+
aabb.upperBound = b2Max( aabb.upperBound, points[i] );
|
|
112
|
+
|
|
113
|
+
b2Vec2 vi = points[i];
|
|
114
|
+
|
|
115
|
+
bool unique = true;
|
|
116
|
+
for ( int j = 0; j < i; ++j )
|
|
117
|
+
{
|
|
118
|
+
b2Vec2 vj = points[j];
|
|
119
|
+
|
|
120
|
+
float distSqr = b2DistanceSquared( vi, vj );
|
|
121
|
+
if ( distSqr < tolSqr )
|
|
122
|
+
{
|
|
123
|
+
unique = false;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if ( unique )
|
|
129
|
+
{
|
|
130
|
+
ps[n++] = vi;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if ( n < 3 )
|
|
135
|
+
{
|
|
136
|
+
// all points very close together, check your data and check your scale
|
|
137
|
+
return hull;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Find an extreme point as the first point on the hull
|
|
141
|
+
b2Vec2 c = b2AABB_Center( aabb );
|
|
142
|
+
int f1 = 0;
|
|
143
|
+
float dsq1 = b2DistanceSquared( c, ps[f1] );
|
|
144
|
+
for ( int i = 1; i < n; ++i )
|
|
145
|
+
{
|
|
146
|
+
float dsq = b2DistanceSquared( c, ps[i] );
|
|
147
|
+
if ( dsq > dsq1 )
|
|
148
|
+
{
|
|
149
|
+
f1 = i;
|
|
150
|
+
dsq1 = dsq;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// remove p1 from working set
|
|
155
|
+
b2Vec2 p1 = ps[f1];
|
|
156
|
+
ps[f1] = ps[n - 1];
|
|
157
|
+
n = n - 1;
|
|
158
|
+
|
|
159
|
+
int f2 = 0;
|
|
160
|
+
float dsq2 = b2DistanceSquared( p1, ps[f2] );
|
|
161
|
+
for ( int i = 1; i < n; ++i )
|
|
162
|
+
{
|
|
163
|
+
float dsq = b2DistanceSquared( p1, ps[i] );
|
|
164
|
+
if ( dsq > dsq2 )
|
|
165
|
+
{
|
|
166
|
+
f2 = i;
|
|
167
|
+
dsq2 = dsq;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// remove p2 from working set
|
|
172
|
+
b2Vec2 p2 = ps[f2];
|
|
173
|
+
ps[f2] = ps[n - 1];
|
|
174
|
+
n = n - 1;
|
|
175
|
+
|
|
176
|
+
// split the points into points that are left and right of the line p1-p2.
|
|
177
|
+
b2Vec2 rightPoints[B2_MAX_POLYGON_VERTICES - 2];
|
|
178
|
+
int rightCount = 0;
|
|
179
|
+
|
|
180
|
+
b2Vec2 leftPoints[B2_MAX_POLYGON_VERTICES - 2];
|
|
181
|
+
int leftCount = 0;
|
|
182
|
+
|
|
183
|
+
b2Vec2 e = b2Normalize( b2Sub( p2, p1 ) );
|
|
184
|
+
|
|
185
|
+
for ( int i = 0; i < n; ++i )
|
|
186
|
+
{
|
|
187
|
+
float d = b2Cross( b2Sub( ps[i], p1 ), e );
|
|
188
|
+
|
|
189
|
+
// slop used here to skip points that are very close to the line p1-p2
|
|
190
|
+
if ( d >= 2.0f * linearSlop )
|
|
191
|
+
{
|
|
192
|
+
rightPoints[rightCount++] = ps[i];
|
|
193
|
+
}
|
|
194
|
+
else if ( d <= -2.0f * linearSlop )
|
|
195
|
+
{
|
|
196
|
+
leftPoints[leftCount++] = ps[i];
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// compute hulls on right and left
|
|
201
|
+
b2Hull hull1 = b2RecurseHull( p1, p2, rightPoints, rightCount );
|
|
202
|
+
b2Hull hull2 = b2RecurseHull( p2, p1, leftPoints, leftCount );
|
|
203
|
+
|
|
204
|
+
if ( hull1.count == 0 && hull2.count == 0 )
|
|
205
|
+
{
|
|
206
|
+
// all points collinear
|
|
207
|
+
return hull;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// stitch hulls together, preserving CCW winding order
|
|
211
|
+
hull.points[hull.count++] = p1;
|
|
212
|
+
|
|
213
|
+
for ( int i = 0; i < hull1.count; ++i )
|
|
214
|
+
{
|
|
215
|
+
hull.points[hull.count++] = hull1.points[i];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
hull.points[hull.count++] = p2;
|
|
219
|
+
|
|
220
|
+
for ( int i = 0; i < hull2.count; ++i )
|
|
221
|
+
{
|
|
222
|
+
hull.points[hull.count++] = hull2.points[i];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
B2_ASSERT( hull.count <= B2_MAX_POLYGON_VERTICES );
|
|
226
|
+
|
|
227
|
+
// merge collinear
|
|
228
|
+
bool searching = true;
|
|
229
|
+
while ( searching && hull.count > 2 )
|
|
230
|
+
{
|
|
231
|
+
searching = false;
|
|
232
|
+
|
|
233
|
+
for ( int i = 0; i < hull.count; ++i )
|
|
234
|
+
{
|
|
235
|
+
int i1 = i;
|
|
236
|
+
int i2 = ( i + 1 ) % hull.count;
|
|
237
|
+
int i3 = ( i + 2 ) % hull.count;
|
|
238
|
+
|
|
239
|
+
b2Vec2 s1 = hull.points[i1];
|
|
240
|
+
b2Vec2 s2 = hull.points[i2];
|
|
241
|
+
b2Vec2 s3 = hull.points[i3];
|
|
242
|
+
|
|
243
|
+
// unit edge vector for s1-s3
|
|
244
|
+
b2Vec2 r = b2Normalize( b2Sub( s3, s1 ) );
|
|
245
|
+
|
|
246
|
+
float distance = b2Cross( b2Sub( s2, s1 ), r );
|
|
247
|
+
if ( distance <= 2.0f * linearSlop )
|
|
248
|
+
{
|
|
249
|
+
// remove midpoint from hull
|
|
250
|
+
for ( int j = i2; j < hull.count - 1; ++j )
|
|
251
|
+
{
|
|
252
|
+
hull.points[j] = hull.points[j + 1];
|
|
253
|
+
}
|
|
254
|
+
hull.count -= 1;
|
|
255
|
+
|
|
256
|
+
// continue searching for collinear points
|
|
257
|
+
searching = true;
|
|
258
|
+
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if ( hull.count < 3 )
|
|
265
|
+
{
|
|
266
|
+
// all points collinear, shouldn't be reached since this was validated above
|
|
267
|
+
hull.count = 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return hull;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
bool b2ValidateHull( const b2Hull* hull )
|
|
274
|
+
{
|
|
275
|
+
if ( hull->count < 3 || B2_MAX_POLYGON_VERTICES < hull->count )
|
|
276
|
+
{
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// test that every point is behind every edge
|
|
281
|
+
for ( int i = 0; i < hull->count; ++i )
|
|
282
|
+
{
|
|
283
|
+
// create an edge vector
|
|
284
|
+
int i1 = i;
|
|
285
|
+
int i2 = i < hull->count - 1 ? i1 + 1 : 0;
|
|
286
|
+
b2Vec2 p = hull->points[i1];
|
|
287
|
+
b2Vec2 e = b2Normalize( b2Sub( hull->points[i2], p ) );
|
|
288
|
+
|
|
289
|
+
for ( int j = 0; j < hull->count; ++j )
|
|
290
|
+
{
|
|
291
|
+
// skip points that subtend the current edge
|
|
292
|
+
if ( j == i1 || j == i2 )
|
|
293
|
+
{
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
float distance = b2Cross( b2Sub( hull->points[j], p ), e );
|
|
298
|
+
if ( distance >= 0.0f )
|
|
299
|
+
{
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// test for collinear points
|
|
306
|
+
const float linearSlop = B2_LINEAR_SLOP;
|
|
307
|
+
for ( int i = 0; i < hull->count; ++i )
|
|
308
|
+
{
|
|
309
|
+
int i1 = i;
|
|
310
|
+
int i2 = ( i + 1 ) % hull->count;
|
|
311
|
+
int i3 = ( i + 2 ) % hull->count;
|
|
312
|
+
|
|
313
|
+
b2Vec2 p1 = hull->points[i1];
|
|
314
|
+
b2Vec2 p2 = hull->points[i2];
|
|
315
|
+
b2Vec2 p3 = hull->points[i3];
|
|
316
|
+
|
|
317
|
+
b2Vec2 e = b2Normalize( b2Sub( p3, p1 ) );
|
|
318
|
+
|
|
319
|
+
float distance = b2Cross( b2Sub( p2, p1 ), e );
|
|
320
|
+
if ( distance <= linearSlop )
|
|
321
|
+
{
|
|
322
|
+
// p1-p2-p3 are collinear
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return true;
|
|
328
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2023 Erin Catto
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
#include "id_pool.h"
|
|
5
|
+
|
|
6
|
+
b2IdPool b2CreateIdPool( void )
|
|
7
|
+
{
|
|
8
|
+
b2IdPool pool = { 0 };
|
|
9
|
+
pool.freeArray = b2IntArray_Create( 32 );
|
|
10
|
+
return pool;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
void b2DestroyIdPool( b2IdPool* pool )
|
|
14
|
+
{
|
|
15
|
+
b2IntArray_Destroy( &pool->freeArray );
|
|
16
|
+
*pool = ( b2IdPool ){ 0 };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
int b2AllocId( b2IdPool* pool )
|
|
20
|
+
{
|
|
21
|
+
int count = pool->freeArray.count;
|
|
22
|
+
if ( count > 0 )
|
|
23
|
+
{
|
|
24
|
+
int id = b2IntArray_Pop( &pool->freeArray );
|
|
25
|
+
return id;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
int id = pool->nextIndex;
|
|
29
|
+
pool->nextIndex += 1;
|
|
30
|
+
return id;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
void b2FreeId( b2IdPool* pool, int id )
|
|
34
|
+
{
|
|
35
|
+
B2_ASSERT( pool->nextIndex > 0 );
|
|
36
|
+
B2_ASSERT( 0 <= id && id < pool->nextIndex );
|
|
37
|
+
b2IntArray_Push( &pool->freeArray, id );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#if B2_VALIDATE
|
|
41
|
+
|
|
42
|
+
void b2ValidateFreeId( b2IdPool* pool, int id )
|
|
43
|
+
{
|
|
44
|
+
int freeCount = pool->freeArray.count;
|
|
45
|
+
for ( int i = 0; i < freeCount; ++i )
|
|
46
|
+
{
|
|
47
|
+
if ( pool->freeArray.data[i] == id )
|
|
48
|
+
{
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
B2_ASSERT( 0 );
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void b2ValidateUsedId( b2IdPool* pool, int id )
|
|
57
|
+
{
|
|
58
|
+
int freeCount = pool->freeArray.count;
|
|
59
|
+
for ( int i = 0; i < freeCount; ++i )
|
|
60
|
+
{
|
|
61
|
+
if ( pool->freeArray.data[i] == id )
|
|
62
|
+
{
|
|
63
|
+
B2_ASSERT( 0 );
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#else
|
|
69
|
+
|
|
70
|
+
void b2ValidateFreeId( b2IdPool* pool, int id )
|
|
71
|
+
{
|
|
72
|
+
B2_UNUSED( pool, id );
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
void b2ValidateUsedId( b2IdPool* pool, int id )
|
|
76
|
+
{
|
|
77
|
+
B2_UNUSED( pool, id );
|
|
78
|
+
}
|
|
79
|
+
#endif
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2023 Erin Catto
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
#pragma once
|
|
5
|
+
|
|
6
|
+
#include "array.h"
|
|
7
|
+
|
|
8
|
+
typedef struct b2IdPool
|
|
9
|
+
{
|
|
10
|
+
b2IntArray freeArray;
|
|
11
|
+
int nextIndex;
|
|
12
|
+
} b2IdPool;
|
|
13
|
+
|
|
14
|
+
b2IdPool b2CreateIdPool( void );
|
|
15
|
+
void b2DestroyIdPool( b2IdPool* pool );
|
|
16
|
+
|
|
17
|
+
int b2AllocId( b2IdPool* pool );
|
|
18
|
+
void b2FreeId( b2IdPool* pool, int id );
|
|
19
|
+
void b2ValidateFreeId( b2IdPool* pool, int id );
|
|
20
|
+
void b2ValidateUsedId( b2IdPool* pool, int id );
|
|
21
|
+
|
|
22
|
+
static inline int b2GetIdCount( b2IdPool* pool )
|
|
23
|
+
{
|
|
24
|
+
return pool->nextIndex - pool->freeArray.count;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static inline int b2GetIdCapacity( b2IdPool* pool )
|
|
28
|
+
{
|
|
29
|
+
return pool->nextIndex;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
static inline int b2GetIdBytes( b2IdPool* pool )
|
|
33
|
+
{
|
|
34
|
+
return b2IntArray_ByteCount(&pool->freeArray);
|
|
35
|
+
}
|