chipmunk 4.1.0-x86-mswin32 → 5.3.4.0-x86-mswin32
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.
- data/{ext/chipmunk/cpCollision.h → LICENSE} +4 -5
- data/README +67 -0
- data/Rakefile +76 -29
- data/ext/chipmunk/extconf.rb +38 -0
- data/ext/chipmunk/rb_chipmunk.c +162 -21
- data/ext/chipmunk/rb_chipmunk.h +39 -11
- data/ext/chipmunk/rb_cpArbiter.c +253 -0
- data/ext/chipmunk/rb_cpBB.c +60 -4
- data/ext/chipmunk/rb_cpBody.c +282 -17
- data/ext/chipmunk/rb_cpConstraint.c +336 -0
- data/ext/chipmunk/rb_cpShape.c +145 -4
- data/ext/chipmunk/rb_cpSpace.c +438 -57
- data/ext/chipmunk/rb_cpVect.c +98 -2
- data/lib/1.8/chipmunk.so +0 -0
- data/lib/1.9/chipmunk.so +0 -0
- data/lib/chipmunk.rb +168 -0
- metadata +29 -41
- data/ext/chipmunk/chipmunk.c +0 -69
- data/ext/chipmunk/chipmunk.h +0 -91
- data/ext/chipmunk/cpArbiter.c +0 -263
- data/ext/chipmunk/cpArbiter.h +0 -85
- data/ext/chipmunk/cpArray.c +0 -114
- data/ext/chipmunk/cpArray.h +0 -45
- data/ext/chipmunk/cpBB.c +0 -46
- data/ext/chipmunk/cpBB.h +0 -53
- data/ext/chipmunk/cpBody.c +0 -180
- data/ext/chipmunk/cpBody.h +0 -132
- data/ext/chipmunk/cpCollision.c +0 -390
- data/ext/chipmunk/cpHashSet.c +0 -219
- data/ext/chipmunk/cpHashSet.h +0 -79
- data/ext/chipmunk/cpJoint.c +0 -553
- data/ext/chipmunk/cpJoint.h +0 -122
- data/ext/chipmunk/cpPolyShape.c +0 -139
- data/ext/chipmunk/cpPolyShape.h +0 -92
- data/ext/chipmunk/cpShape.c +0 -244
- data/ext/chipmunk/cpShape.h +0 -141
- data/ext/chipmunk/cpSpace.c +0 -530
- data/ext/chipmunk/cpSpace.h +0 -120
- data/ext/chipmunk/cpSpaceHash.c +0 -455
- data/ext/chipmunk/cpSpaceHash.h +0 -100
- data/ext/chipmunk/cpVect.c +0 -63
- data/ext/chipmunk/cpVect.h +0 -106
- data/ext/chipmunk/prime.h +0 -68
- data/ext/chipmunk/rb_cpJoint.c +0 -136
data/ext/chipmunk/cpShape.h
DELETED
@@ -1,141 +0,0 @@
|
|
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);
|
data/ext/chipmunk/cpSpace.c
DELETED
@@ -1,530 +0,0 @@
|
|
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
|
-
}
|