chipmunk 4.1.0-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,141 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ // For determinism, you can reset the shape id counter.
23
+ void cpResetShapeIdCounter(void);
24
+
25
+ // Enumeration of shape types.
26
+ typedef enum cpShapeType{
27
+ CP_CIRCLE_SHAPE,
28
+ CP_SEGMENT_SHAPE,
29
+ CP_POLY_SHAPE,
30
+ CP_NUM_SHAPES
31
+ } cpShapeType;
32
+
33
+ // Forward declarations required for defining the cpShape and cpShapeClass structs.
34
+ struct cpShape;
35
+ struct cpShapeClass;
36
+
37
+ // Shape class. Holds function pointers and type data.
38
+ typedef struct cpShapeClass {
39
+ cpShapeType type;
40
+
41
+ // Called by cpShapeCacheBB().
42
+ cpBB (*cacheData)(struct cpShape *shape, cpVect p, cpVect rot);
43
+ // Called to by cpShapeDestroy().
44
+ void (*destroy)(struct cpShape *shape);
45
+
46
+ // called by cpShapeQueryPointQuery().
47
+ int (*pointQuery)(struct cpShape *shape, cpVect p);
48
+ } cpShapeClass;
49
+
50
+ // Basic shape struct that the others inherit from.
51
+ typedef struct cpShape{
52
+ // The "class" of a shape as defined above
53
+ const cpShapeClass *klass;
54
+
55
+ // cpBody that the shape is attached to.
56
+ cpBody *body;
57
+
58
+ // Cached BBox for the shape.
59
+ cpBB bb;
60
+
61
+ // *** Surface properties.
62
+
63
+ // Coefficient of restitution. (elasticity)
64
+ cpFloat e;
65
+ // Coefficient of friction.
66
+ cpFloat u;
67
+ // Surface velocity used when solving for friction.
68
+ cpVect surface_v;
69
+
70
+ // *** User Definable Fields
71
+
72
+ // User defined data pointer for the shape.
73
+ void *data;
74
+
75
+ // User defined collision type for the shape.
76
+ unsigned int collision_type;
77
+ // User defined collision group for the shape.
78
+ unsigned int group;
79
+ // User defined layer bitmask for the shape.
80
+ unsigned int layers;
81
+
82
+ // *** Internally Used Fields
83
+
84
+ // Unique id used as the hash value.
85
+ unsigned int id;
86
+ } cpShape;
87
+
88
+ // Low level shape initialization func.
89
+ cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);
90
+
91
+ // Basic destructor functions. (allocation functions are not shared)
92
+ void cpShapeDestroy(cpShape *shape);
93
+ void cpShapeFree(cpShape *shape);
94
+
95
+ // Cache the BBox of the shape.
96
+ cpBB cpShapeCacheBB(cpShape *shape);
97
+
98
+ // Test if a point lies within a shape.
99
+ int cpShapePointQuery(cpShape *shape, cpVect p);
100
+
101
+ // Test if a segment collides with a shape.
102
+ // Returns [0-1] if the segment collides and -1 otherwise.
103
+ // 0 would be a collision at point a, 1 would be a collision at point b.
104
+ //cpFloat cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b);
105
+
106
+
107
+ // Circle shape structure.
108
+ typedef struct cpCircleShape{
109
+ cpShape shape;
110
+
111
+ // Center. (body space coordinates)
112
+ cpVect c;
113
+ // Radius.
114
+ cpFloat r;
115
+
116
+ // Transformed center. (world space coordinates)
117
+ cpVect tc;
118
+ } cpCircleShape;
119
+
120
+ // Basic allocation functions for cpCircleShape.
121
+ cpCircleShape *cpCircleShapeAlloc(void);
122
+ cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
123
+ cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
124
+
125
+ // Segment shape structure.
126
+ typedef struct cpSegmentShape{
127
+ cpShape shape;
128
+
129
+ // Endpoints and normal of the segment. (body space coordinates)
130
+ cpVect a, b, n;
131
+ // Radius of the segment. (Thickness)
132
+ cpFloat r;
133
+
134
+ // Transformed endpoints and normal. (world space coordinates)
135
+ cpVect ta, tb, tn;
136
+ } cpSegmentShape;
137
+
138
+ // Basic allocation functions for cpSegmentShape.
139
+ cpSegmentShape* cpSegmentShapeAlloc(void);
140
+ cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
141
+ cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
@@ -0,0 +1,530 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ #include <stdlib.h>
23
+ #include <stdio.h>
24
+ #include <math.h>
25
+ #include <assert.h>
26
+
27
+ #include "chipmunk.h"
28
+
29
+ int cp_contact_persistence = 3;
30
+
31
+ // Equal function for contactSet.
32
+ static int
33
+ contactSetEql(void *ptr, void *elt)
34
+ {
35
+ cpShape **shapes = (cpShape **)ptr;
36
+ cpShape *a = shapes[0];
37
+ cpShape *b = shapes[1];
38
+
39
+ cpArbiter *arb = (cpArbiter *)elt;
40
+
41
+ return ((a == arb->a && b == arb->b) || (b == arb->a && a == arb->b));
42
+ }
43
+
44
+ // Transformation function for contactSet.
45
+ static void *
46
+ contactSetTrans(void *ptr, void *data)
47
+ {
48
+ cpShape **shapes = (cpShape **)ptr;
49
+ cpShape *a = shapes[0];
50
+ cpShape *b = shapes[1];
51
+
52
+ cpSpace *space = (cpSpace *)data;
53
+
54
+ return cpArbiterNew(a, b, space->stamp);
55
+ }
56
+
57
+ // Collision pair function wrapper struct.
58
+ typedef struct collFuncData {
59
+ cpCollFunc func;
60
+ void *data;
61
+ } collFuncData;
62
+
63
+ // Equals function for collFuncSet.
64
+ static int
65
+ collFuncSetEql(void *ptr, void *elt)
66
+ {
67
+ unsigned int *ids = (unsigned int *)ptr;
68
+ unsigned int a = ids[0];
69
+ unsigned int b = ids[1];
70
+
71
+ cpCollPairFunc *pair = (cpCollPairFunc *)elt;
72
+
73
+ return ((a == pair->a && b == pair->b) || (b == pair->a && a == pair->b));
74
+ }
75
+
76
+ // Transformation function for collFuncSet.
77
+ static void *
78
+ collFuncSetTrans(void *ptr, void *data)
79
+ {
80
+ unsigned int *ids = (unsigned int *)ptr;
81
+ collFuncData *funcData = (collFuncData *)data;
82
+
83
+ cpCollPairFunc *pair = (cpCollPairFunc *)malloc(sizeof(cpCollPairFunc));
84
+ pair->a = ids[0];
85
+ pair->b = ids[1];
86
+ pair->func = funcData->func;
87
+ pair->data = funcData->data;
88
+
89
+ return pair;
90
+ }
91
+
92
+ // Default collision pair function.
93
+ static int
94
+ alwaysCollide(cpShape *a, cpShape *b, cpContact *arr, int numCon, cpFloat normal_coef, void *data)
95
+ {
96
+ return 1;
97
+ }
98
+
99
+ // BBfunc callback for the spatial hash.
100
+ static cpBB
101
+ bbfunc(void *ptr)
102
+ {
103
+ cpShape *shape = (cpShape *)ptr;
104
+ return shape->bb;
105
+ }
106
+
107
+ // Iterator functions for destructors.
108
+ static void freeWrap(void *ptr, void *unused){ free( ptr);}
109
+ static void shapeFreeWrap(void *ptr, void *unused){ cpShapeFree((cpShape *) ptr);}
110
+ static void arbiterFreeWrap(void *ptr, void *unused){ cpArbiterFree((cpArbiter *)ptr);}
111
+ static void bodyFreeWrap(void *ptr, void *unused){ cpBodyFree((cpBody *) ptr);}
112
+ static void jointFreeWrap(void *ptr, void *unused){ cpJointFree((cpJoint *) ptr);}
113
+
114
+ cpSpace*
115
+ cpSpaceAlloc(void)
116
+ {
117
+ return (cpSpace *)calloc(1, sizeof(cpSpace));
118
+ }
119
+
120
+ #define DEFAULT_DIM_SIZE 100.0f
121
+ #define DEFAULT_COUNT 1000
122
+ #define DEFAULT_ITERATIONS 10
123
+ #define DEFAULT_ELASTIC_ITERATIONS 0
124
+
125
+ cpSpace*
126
+ cpSpaceInit(cpSpace *space)
127
+ {
128
+ space->iterations = DEFAULT_ITERATIONS;
129
+ space->elasticIterations = DEFAULT_ELASTIC_ITERATIONS;
130
+ // space->sleepTicks = 300;
131
+
132
+ space->gravity = cpvzero;
133
+ space->damping = 1.0f;
134
+
135
+ space->stamp = 0;
136
+
137
+ space->staticShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, &bbfunc);
138
+ space->activeShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, &bbfunc);
139
+
140
+ space->bodies = cpArrayNew(0);
141
+ space->arbiters = cpArrayNew(0);
142
+ space->contactSet = cpHashSetNew(0, contactSetEql, contactSetTrans);
143
+
144
+ space->joints = cpArrayNew(0);
145
+
146
+ cpCollPairFunc pairFunc = {0, 0, alwaysCollide, NULL};
147
+ space->defaultPairFunc = pairFunc;
148
+ space->collFuncSet = cpHashSetNew(0, collFuncSetEql, collFuncSetTrans);
149
+ space->collFuncSet->default_value = &space->defaultPairFunc;
150
+
151
+ return space;
152
+ }
153
+
154
+ cpSpace*
155
+ cpSpaceNew(void)
156
+ {
157
+ return cpSpaceInit(cpSpaceAlloc());
158
+ }
159
+
160
+ void
161
+ cpSpaceDestroy(cpSpace *space)
162
+ {
163
+ cpSpaceHashFree(space->staticShapes);
164
+ cpSpaceHashFree(space->activeShapes);
165
+
166
+ cpArrayFree(space->bodies);
167
+
168
+ cpArrayFree(space->joints);
169
+
170
+ if(space->contactSet)
171
+ cpHashSetEach(space->contactSet, &arbiterFreeWrap, NULL);
172
+ cpHashSetFree(space->contactSet);
173
+ cpArrayFree(space->arbiters);
174
+
175
+ if(space->collFuncSet)
176
+ cpHashSetEach(space->collFuncSet, &freeWrap, NULL);
177
+ cpHashSetFree(space->collFuncSet);
178
+ }
179
+
180
+ void
181
+ cpSpaceFree(cpSpace *space)
182
+ {
183
+ if(space) cpSpaceDestroy(space);
184
+ free(space);
185
+ }
186
+
187
+ void
188
+ cpSpaceFreeChildren(cpSpace *space)
189
+ {
190
+ cpSpaceHashEach(space->staticShapes, &shapeFreeWrap, NULL);
191
+ cpSpaceHashEach(space->activeShapes, &shapeFreeWrap, NULL);
192
+ cpArrayEach(space->bodies, &bodyFreeWrap, NULL);
193
+ cpArrayEach(space->joints, &jointFreeWrap, NULL);
194
+ }
195
+
196
+ void
197
+ cpSpaceAddCollisionPairFunc(cpSpace *space, unsigned int a, unsigned int b,
198
+ cpCollFunc func, void *data)
199
+ {
200
+ unsigned int ids[] = {a, b};
201
+ unsigned int hash = CP_HASH_PAIR(a, b);
202
+ // Remove any old function so the new one will get added.
203
+ cpSpaceRemoveCollisionPairFunc(space, a, b);
204
+
205
+ collFuncData funcData = {func, data};
206
+ cpHashSetInsert(space->collFuncSet, hash, ids, &funcData);
207
+ }
208
+
209
+ void
210
+ cpSpaceRemoveCollisionPairFunc(cpSpace *space, unsigned int a, unsigned int b)
211
+ {
212
+ unsigned int ids[] = {a, b};
213
+ unsigned int hash = CP_HASH_PAIR(a, b);
214
+ cpCollPairFunc *old_pair = (cpCollPairFunc *)cpHashSetRemove(space->collFuncSet, hash, ids);
215
+ free(old_pair);
216
+ }
217
+
218
+ void
219
+ cpSpaceSetDefaultCollisionPairFunc(cpSpace *space, cpCollFunc func, void *data)
220
+ {
221
+ cpCollPairFunc pairFunc = {0, 0, (func ? func : alwaysCollide), (func ? data : NULL)};
222
+ space->defaultPairFunc = pairFunc;
223
+ }
224
+
225
+ void
226
+ cpSpaceAddShape(cpSpace *space, cpShape *shape)
227
+ {
228
+ cpSpaceHashInsert(space->activeShapes, shape, shape->id, shape->bb);
229
+ }
230
+
231
+ void
232
+ cpSpaceAddStaticShape(cpSpace *space, cpShape *shape)
233
+ {
234
+ cpShapeCacheBB(shape);
235
+ cpSpaceHashInsert(space->staticShapes, shape, shape->id, shape->bb);
236
+ }
237
+
238
+ void
239
+ cpSpaceAddBody(cpSpace *space, cpBody *body)
240
+ {
241
+ cpArrayPush(space->bodies, body);
242
+ }
243
+
244
+ void
245
+ cpSpaceAddJoint(cpSpace *space, cpJoint *joint)
246
+ {
247
+ cpArrayPush(space->joints, joint);
248
+ }
249
+
250
+ void
251
+ cpSpaceRemoveShape(cpSpace *space, cpShape *shape)
252
+ {
253
+ cpSpaceHashRemove(space->activeShapes, shape, shape->id);
254
+ }
255
+
256
+ void
257
+ cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape)
258
+ {
259
+ cpSpaceHashRemove(space->staticShapes, shape, shape->id);
260
+ }
261
+
262
+ void
263
+ cpSpaceRemoveBody(cpSpace *space, cpBody *body)
264
+ {
265
+ cpArrayDeleteObj(space->bodies, body);
266
+ }
267
+
268
+ void
269
+ cpSpaceRemoveJoint(cpSpace *space, cpJoint *joint)
270
+ {
271
+ cpArrayDeleteObj(space->joints, joint);
272
+ }
273
+
274
+ void
275
+ cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data)
276
+ {
277
+ cpArray *bodies = space->bodies;
278
+
279
+ for(int i=0; i<bodies->num; i++)
280
+ func((cpBody *)bodies->arr[i], data);
281
+ }
282
+
283
+ // Iterator function used for updating shape BBoxes.
284
+ static void
285
+ updateBBCache(void *ptr, void *unused)
286
+ {
287
+ cpShape *shape = (cpShape *)ptr;
288
+ cpShapeCacheBB(shape);
289
+ }
290
+
291
+ void
292
+ cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count)
293
+ {
294
+ cpSpaceHashResize(space->staticShapes, dim, count);
295
+ cpSpaceHashRehash(space->staticShapes);
296
+ }
297
+
298
+ void
299
+ cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count)
300
+ {
301
+ cpSpaceHashResize(space->activeShapes, dim, count);
302
+ }
303
+
304
+ void
305
+ cpSpaceRehashStatic(cpSpace *space)
306
+ {
307
+ cpSpaceHashEach(space->staticShapes, &updateBBCache, NULL);
308
+ cpSpaceHashRehash(space->staticShapes);
309
+ }
310
+
311
+ typedef struct pointQueryFuncPair {
312
+ cpSpacePointQueryFunc func;
313
+ void *data;
314
+ } pointQueryFuncPair;
315
+
316
+ static int
317
+ pointQueryHelper(void *point, void *obj, void *data)
318
+ {
319
+ cpShape *shape = (cpShape *)obj;
320
+ pointQueryFuncPair *pair = (pointQueryFuncPair *)data;
321
+
322
+ if(cpShapePointQuery(shape, *((cpVect *)point)))
323
+ pair->func(shape, pair->data);
324
+
325
+ return 1; // return value needed for historical reasons (value is ignored)
326
+ }
327
+
328
+ static void
329
+ pointQuery(cpSpaceHash *hash, cpVect point, cpSpacePointQueryFunc func, void *data)
330
+ {
331
+ pointQueryFuncPair pair = {func, data};
332
+ cpSpaceHashPointQuery(hash, point, pointQueryHelper, &pair);
333
+ }
334
+
335
+ void
336
+ cpSpaceShapePointQuery(cpSpace *space, cpVect point, cpSpacePointQueryFunc func, void *data)
337
+ {
338
+ pointQuery(space->activeShapes, point, func, data);
339
+ }
340
+
341
+ void
342
+ cpSpaceStaticShapePointQuery(cpSpace *space, cpVect point, cpSpacePointQueryFunc func, void *data)
343
+ {
344
+ pointQuery(space->staticShapes, point, func, data);
345
+ }
346
+
347
+ static inline int
348
+ queryReject(cpShape *a, cpShape *b)
349
+ {
350
+ return
351
+ // BBoxes must overlap
352
+ !cpBBintersects(a->bb, b->bb)
353
+ // Don't collide shapes attached to the same body.
354
+ || a->body == b->body
355
+ // Don't collide objects in the same non-zero group
356
+ || (a->group && b->group && a->group == b->group)
357
+ // Don't collide objects that don't share at least on layer.
358
+ || !(a->layers & b->layers);
359
+ }
360
+
361
+ // Callback from the spatial hash.
362
+ // TODO: Refactor this into separate functions?
363
+ static int
364
+ queryFunc(void *p1, void *p2, void *data)
365
+ {
366
+ // Cast the generic pointers from the spatial hash back to usefull types
367
+ cpShape *a = (cpShape *)p1;
368
+ cpShape *b = (cpShape *)p2;
369
+ cpSpace *space = (cpSpace *)data;
370
+
371
+ // Reject any of the simple cases
372
+ if(queryReject(a,b)) return 0;
373
+
374
+ // Shape 'a' should have the lower shape type. (required by cpCollideShapes() )
375
+ if(a->klass->type > b->klass->type){
376
+ cpShape *temp = a;
377
+ a = b;
378
+ b = temp;
379
+ }
380
+
381
+ // Find the collision pair function for the shapes.
382
+ unsigned int ids[] = {a->collision_type, b->collision_type};
383
+ unsigned int hash = CP_HASH_PAIR(a->collision_type, b->collision_type);
384
+ cpCollPairFunc *pairFunc = (cpCollPairFunc *)cpHashSetFind(space->collFuncSet, hash, ids);
385
+ if(!pairFunc->func) return 0; // A NULL pair function means don't collide at all.
386
+
387
+ // Narrow-phase collision detection.
388
+ cpContact *contacts = NULL;
389
+ int numContacts = cpCollideShapes(a, b, &contacts);
390
+ if(!numContacts) return 0; // Shapes are not colliding.
391
+
392
+ // The collision pair function requires objects to be ordered by their collision types.
393
+ cpShape *pair_a = a;
394
+ cpShape *pair_b = b;
395
+ cpFloat normal_coef = 1.0f;
396
+
397
+ // Swap them if necessary.
398
+ if(pair_a->collision_type != pairFunc->a){
399
+ cpShape *temp = pair_a;
400
+ pair_a = pair_b;
401
+ pair_b = temp;
402
+ normal_coef = -1.0f;
403
+ }
404
+
405
+ if(pairFunc->func(pair_a, pair_b, contacts, numContacts, normal_coef, pairFunc->data)){
406
+ // The collision pair function OKed the collision. Record the contact information.
407
+
408
+ // Get an arbiter from space->contactSet for the two shapes.
409
+ // This is where the persistant contact magic comes from.
410
+ cpShape *shape_pair[] = {a, b};
411
+ cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->contactSet, CP_HASH_PAIR(a, b), shape_pair, space);
412
+
413
+ // Timestamp the arbiter.
414
+ arb->stamp = space->stamp;
415
+ arb->a = a; arb->b = b; // TODO: Investigate why this is still necessary?
416
+ // Inject the new contact points into the arbiter.
417
+ cpArbiterInject(arb, contacts, numContacts);
418
+
419
+ // Add the arbiter to the list of active arbiters.
420
+ cpArrayPush(space->arbiters, arb);
421
+
422
+ return numContacts;
423
+ } else {
424
+ // The collision pair function rejected the collision.
425
+
426
+ free(contacts);
427
+ return 0;
428
+ }
429
+ }
430
+
431
+ // Iterator for active/static hash collisions.
432
+ static void
433
+ active2staticIter(void *ptr, void *data)
434
+ {
435
+ cpShape *shape = (cpShape *)ptr;
436
+ cpSpace *space = (cpSpace *)data;
437
+ cpSpaceHashQuery(space->staticShapes, shape, shape->bb, &queryFunc, space);
438
+ }
439
+
440
+ // Hashset reject func to throw away old arbiters.
441
+ static int
442
+ contactSetReject(void *ptr, void *data)
443
+ {
444
+ cpArbiter *arb = (cpArbiter *)ptr;
445
+ cpSpace *space = (cpSpace *)data;
446
+
447
+ if((space->stamp - arb->stamp) > cp_contact_persistence){
448
+ cpArbiterFree(arb);
449
+ return 0;
450
+ }
451
+
452
+ return 1;
453
+ }
454
+
455
+ void
456
+ cpSpaceStep(cpSpace *space, cpFloat dt)
457
+ {
458
+ if(!dt) return; // prevents div by zero.
459
+ cpFloat dt_inv = 1.0f/dt;
460
+
461
+ cpArray *bodies = space->bodies;
462
+ cpArray *arbiters = space->arbiters;
463
+ cpArray *joints = space->joints;
464
+
465
+ // Empty the arbiter list.
466
+ cpHashSetReject(space->contactSet, &contactSetReject, space);
467
+ space->arbiters->num = 0;
468
+
469
+ // Integrate positions.
470
+ for(int i=0; i<bodies->num; i++){
471
+ cpBody *body = (cpBody *)bodies->arr[i];
472
+ body->position_func(body, dt);
473
+ }
474
+
475
+ // Pre-cache BBoxes and shape data.
476
+ cpSpaceHashEach(space->activeShapes, &updateBBCache, NULL);
477
+
478
+ // Collide!
479
+ cpSpaceHashEach(space->activeShapes, &active2staticIter, space);
480
+ cpSpaceHashQueryRehash(space->activeShapes, &queryFunc, space);
481
+
482
+ // Prestep the arbiters.
483
+ for(int i=0; i<arbiters->num; i++)
484
+ cpArbiterPreStep((cpArbiter *)arbiters->arr[i], dt_inv);
485
+
486
+ // Prestep the joints.
487
+ for(int i=0; i<joints->num; i++){
488
+ cpJoint *joint = (cpJoint *)joints->arr[i];
489
+ joint->klass->preStep(joint, dt_inv);
490
+ }
491
+
492
+ for(int i=0; i<space->elasticIterations; i++){
493
+ for(int j=0; j<arbiters->num; j++)
494
+ cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], 1.0f);
495
+
496
+ for(int j=0; j<joints->num; j++){
497
+ cpJoint *joint = (cpJoint *)joints->arr[j];
498
+ joint->klass->applyImpulse(joint);
499
+ }
500
+ }
501
+
502
+ // Integrate velocities.
503
+ cpFloat damping = pow(1.0f/space->damping, -dt);
504
+ for(int i=0; i<bodies->num; i++){
505
+ cpBody *body = (cpBody *)bodies->arr[i];
506
+ body->velocity_func(body, space->gravity, damping, dt);
507
+ }
508
+
509
+ for(int i=0; i<arbiters->num; i++)
510
+ cpArbiterApplyCachedImpulse((cpArbiter *)arbiters->arr[i]);
511
+
512
+ // Run the impulse solver.
513
+ for(int i=0; i<space->iterations; i++){
514
+ for(int j=0; j<arbiters->num; j++)
515
+ cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], 0.0f);
516
+
517
+ for(int j=0; j<joints->num; j++){
518
+ cpJoint *joint = (cpJoint *)joints->arr[j];
519
+ joint->klass->applyImpulse(joint);
520
+ }
521
+ }
522
+
523
+ // cpFloat dvsq = cpvdot(space->gravity, space->gravity);
524
+ // dvsq *= dt*dt * space->damping*space->damping;
525
+ // for(int i=0; i<bodies->num; i++)
526
+ // cpBodyMarkLowEnergy(bodies->arr[i], dvsq, space->sleepTicks);
527
+
528
+ // Increment the stamp.
529
+ space->stamp++;
530
+ }