chipmunk 4.1.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.
@@ -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
+ }
@@ -0,0 +1,120 @@
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
+ // Number of frames that contact information should persist.
23
+ extern int cp_contact_persistence;
24
+
25
+ // User collision pair function.
26
+ typedef int (*cpCollFunc)(cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data);
27
+
28
+ // Structure for holding collision pair function information.
29
+ // Used internally.
30
+ typedef struct cpCollPairFunc {
31
+ unsigned int a;
32
+ unsigned int b;
33
+ cpCollFunc func;
34
+ void *data;
35
+ } cpCollPairFunc;
36
+
37
+ typedef struct cpSpace{
38
+ // *** User definable fields
39
+
40
+ // Number of iterations to use in the impulse solver to solve contacts.
41
+ int iterations;
42
+
43
+ // Number of iterations to use in the impulse solver to solve elastic collisions.
44
+ int elasticIterations;
45
+
46
+ // Default gravity to supply when integrating rigid body motions.
47
+ cpVect gravity;
48
+
49
+ // Default damping to supply when integrating rigid body motions.
50
+ cpFloat damping;
51
+
52
+ // *** Internally Used Fields
53
+
54
+ // Time stamp. Is incremented on every call to cpSpaceStep().
55
+ int stamp;
56
+
57
+ // The static and active shape spatial hashes.
58
+ cpSpaceHash *staticShapes;
59
+ cpSpaceHash *activeShapes;
60
+
61
+ // List of bodies in the system.
62
+ cpArray *bodies;
63
+ // List of active arbiters for the impulse solver.
64
+ cpArray *arbiters;
65
+ // Persistant contact set.
66
+ cpHashSet *contactSet;
67
+
68
+ // List of joints in the system.
69
+ cpArray *joints;
70
+
71
+ // Set of collisionpair functions.
72
+ cpHashSet *collFuncSet;
73
+ // Default collision pair function.
74
+ cpCollPairFunc defaultPairFunc;
75
+ } cpSpace;
76
+
77
+ // Basic allocation/destruction functions.
78
+ cpSpace* cpSpaceAlloc(void);
79
+ cpSpace* cpSpaceInit(cpSpace *space);
80
+ cpSpace* cpSpaceNew(void);
81
+
82
+ void cpSpaceDestroy(cpSpace *space);
83
+ void cpSpaceFree(cpSpace *space);
84
+
85
+ // Convenience function. Frees all referenced entities. (bodies, shapes and joints)
86
+ void cpSpaceFreeChildren(cpSpace *space);
87
+
88
+ // Collision pair function management functions.
89
+ void cpSpaceAddCollisionPairFunc(cpSpace *space, unsigned int a, unsigned int b,
90
+ cpCollFunc func, void *data);
91
+ void cpSpaceRemoveCollisionPairFunc(cpSpace *space, unsigned int a, unsigned int b);
92
+ void cpSpaceSetDefaultCollisionPairFunc(cpSpace *space, cpCollFunc func, void *data);
93
+
94
+ // Add and remove entities from the system.
95
+ void cpSpaceAddShape(cpSpace *space, cpShape *shape);
96
+ void cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);
97
+ void cpSpaceAddBody(cpSpace *space, cpBody *body);
98
+ void cpSpaceAddJoint(cpSpace *space, cpJoint *joint);
99
+
100
+ void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
101
+ void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);
102
+ void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
103
+ void cpSpaceRemoveJoint(cpSpace *space, cpJoint *joint);
104
+
105
+ // Point query callback function
106
+ typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);
107
+ void cpSpaceShapePointQuery(cpSpace *space, cpVect point, cpSpacePointQueryFunc func, void *data);
108
+ void cpSpaceStaticShapePointQuery(cpSpace *space, cpVect point, cpSpacePointQueryFunc func, void *data);
109
+
110
+ // Iterator function for iterating the bodies in a space.
111
+ typedef void (*cpSpaceBodyIterator)(cpBody *body, void *data);
112
+ void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data);
113
+
114
+ // Spatial hash management functions.
115
+ void cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count);
116
+ void cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count);
117
+ void cpSpaceRehashStatic(cpSpace *space);
118
+
119
+ // Update the space.
120
+ void cpSpaceStep(cpSpace *space, cpFloat dt);