chipmunk 4.1.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/LICENSE +20 -0
  2. data/README +60 -0
  3. data/Rakefile +47 -40
  4. data/ext/chipmunk/chipmunk.c +39 -3
  5. data/ext/chipmunk/cpArbiter.c +91 -80
  6. data/ext/chipmunk/cpArray.c +24 -10
  7. data/ext/chipmunk/cpBB.c +5 -4
  8. data/ext/chipmunk/cpBody.c +30 -22
  9. data/ext/chipmunk/cpCollision.c +54 -53
  10. data/ext/chipmunk/cpConstraint.c +54 -0
  11. data/ext/chipmunk/cpDampedRotarySpring.c +106 -0
  12. data/ext/chipmunk/cpDampedSpring.c +117 -0
  13. data/ext/chipmunk/cpGearJoint.c +114 -0
  14. data/ext/chipmunk/cpGrooveJoint.c +138 -0
  15. data/ext/chipmunk/cpHashSet.c +74 -40
  16. data/ext/chipmunk/cpPinJoint.c +117 -0
  17. data/ext/chipmunk/cpPivotJoint.c +114 -0
  18. data/ext/chipmunk/cpPolyShape.c +117 -15
  19. data/ext/chipmunk/cpRatchetJoint.c +128 -0
  20. data/ext/chipmunk/cpRotaryLimitJoint.c +122 -0
  21. data/ext/chipmunk/cpShape.c +174 -18
  22. data/ext/chipmunk/cpSimpleMotor.c +99 -0
  23. data/ext/chipmunk/cpSlideJoint.c +131 -0
  24. data/ext/chipmunk/cpSpace.c +584 -215
  25. data/ext/chipmunk/cpSpaceHash.c +191 -105
  26. data/ext/chipmunk/cpVect.c +18 -10
  27. data/ext/chipmunk/extconf.rb +34 -4
  28. data/ext/chipmunk/{chipmunk.h → include/chipmunk/chipmunk.h} +63 -6
  29. data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +42 -0
  30. data/ext/chipmunk/include/chipmunk/chipmunk_types.h +80 -0
  31. data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +54 -0
  32. data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +92 -0
  33. data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
  34. data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +53 -0
  35. data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +41 -0
  36. data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +44 -0
  37. data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +43 -0
  38. data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +42 -0
  39. data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
  40. data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
  41. data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
  42. data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +44 -0
  43. data/ext/chipmunk/include/chipmunk/constraints/util.h +116 -0
  44. data/ext/chipmunk/{cpArbiter.h → include/chipmunk/cpArbiter.h} +66 -15
  45. data/ext/chipmunk/{cpArray.h → include/chipmunk/cpArray.h} +2 -1
  46. data/ext/chipmunk/{cpBB.h → include/chipmunk/cpBB.h} +21 -0
  47. data/ext/chipmunk/{cpBody.h → include/chipmunk/cpBody.h} +37 -9
  48. data/ext/chipmunk/{cpCollision.h → include/chipmunk/cpCollision.h} +1 -1
  49. data/ext/chipmunk/{cpHashSet.h → include/chipmunk/cpHashSet.h} +12 -9
  50. data/ext/chipmunk/{cpPolyShape.h → include/chipmunk/cpPolyShape.h} +13 -2
  51. data/ext/chipmunk/{cpShape.h → include/chipmunk/cpShape.h} +51 -18
  52. data/ext/chipmunk/include/chipmunk/cpSpace.h +180 -0
  53. data/ext/chipmunk/{cpSpaceHash.h → include/chipmunk/cpSpaceHash.h} +18 -9
  54. data/ext/chipmunk/{cpVect.h → include/chipmunk/cpVect.h} +61 -10
  55. data/ext/chipmunk/prime.h +32 -32
  56. data/ext/chipmunk/rb_chipmunk.c +125 -109
  57. data/ext/chipmunk/rb_chipmunk.h +96 -77
  58. data/ext/chipmunk/rb_cpArbiter.c +225 -0
  59. data/ext/chipmunk/rb_cpBB.c +174 -154
  60. data/ext/chipmunk/rb_cpBody.c +347 -239
  61. data/ext/chipmunk/rb_cpConstraint.c +346 -0
  62. data/ext/chipmunk/rb_cpShape.c +455 -292
  63. data/ext/chipmunk/rb_cpSpace.c +544 -330
  64. data/ext/chipmunk/rb_cpVect.c +321 -250
  65. data/lib/chipmunk.rb +28 -15
  66. data/lib/chipmunk/version.rb +3 -0
  67. metadata +74 -34
  68. data/ext/chipmunk/cpJoint.c +0 -553
  69. data/ext/chipmunk/cpJoint.h +0 -122
  70. data/ext/chipmunk/cpSpace.h +0 -120
  71. data/ext/chipmunk/rb_cpJoint.c +0 -136
@@ -32,7 +32,7 @@
32
32
  cpArray*
33
33
  cpArrayAlloc(void)
34
34
  {
35
- return (cpArray *)calloc(1, sizeof(cpArray));
35
+ return (cpArray *)cpcalloc(1, sizeof(cpArray));
36
36
  }
37
37
 
38
38
  cpArray*
@@ -42,7 +42,7 @@ cpArrayInit(cpArray *arr, int size)
42
42
 
43
43
  size = (size ? size : 4);
44
44
  arr->max = size;
45
- arr->arr = (void **)malloc(size*sizeof(void**));
45
+ arr->arr = (void **)cpmalloc(size*sizeof(void**));
46
46
 
47
47
  return arr;
48
48
  }
@@ -56,15 +56,16 @@ cpArrayNew(int size)
56
56
  void
57
57
  cpArrayDestroy(cpArray *arr)
58
58
  {
59
- free(arr->arr);
59
+ cpfree(arr->arr);
60
60
  }
61
61
 
62
62
  void
63
63
  cpArrayFree(cpArray *arr)
64
64
  {
65
- if(!arr) return;
66
- cpArrayDestroy(arr);
67
- free(arr);
65
+ if(arr){
66
+ cpArrayDestroy(arr);
67
+ cpfree(arr);
68
+ }
68
69
  }
69
70
 
70
71
  void
@@ -72,18 +73,31 @@ cpArrayPush(cpArray *arr, void *object)
72
73
  {
73
74
  if(arr->num == arr->max){
74
75
  arr->max *= 2;
75
- arr->arr = (void **)realloc(arr->arr, arr->max*sizeof(void**));
76
+ arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void**));
76
77
  }
77
78
 
78
79
  arr->arr[arr->num] = object;
79
80
  arr->num++;
80
81
  }
81
82
 
83
+ void *
84
+ cpArrayPop(cpArray *arr)
85
+ {
86
+ arr->num--;
87
+
88
+ void *value = arr->arr[arr->num];
89
+ arr->arr[arr->num] = NULL;
90
+
91
+ return value;
92
+ }
93
+
82
94
  void
83
- cpArrayDeleteIndex(cpArray *arr, int index)
95
+ cpArrayDeleteIndex(cpArray *arr, int idx)
84
96
  {
85
- int last = --arr->num;
86
- arr->arr[index] = arr->arr[last];
97
+ arr->num--;
98
+
99
+ arr->arr[idx] = arr->arr[arr->num];
100
+ arr->arr[arr->num] = NULL;
87
101
  }
88
102
 
89
103
  void
data/ext/chipmunk/cpBB.c CHANGED
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  #include <math.h>
23
+ #include <stdlib.h>
23
24
 
24
25
  #include "chipmunk.h"
25
26
 
@@ -34,12 +35,12 @@ cpBBClampVect(const cpBB bb, const cpVect v)
34
35
  cpVect
35
36
  cpBBWrapVect(const cpBB bb, const cpVect v)
36
37
  {
37
- cpFloat ix = fabsf(bb.r - bb.l);
38
- cpFloat modx = fmodf(v.x - bb.l, ix);
38
+ cpFloat ix = cpfabs(bb.r - bb.l);
39
+ cpFloat modx = cpfmod(v.x - bb.l, ix);
39
40
  cpFloat x = (modx > 0.0f) ? modx : modx + ix;
40
41
 
41
- cpFloat iy = fabsf(bb.t - bb.b);
42
- cpFloat mody = fmodf(v.y - bb.b, iy);
42
+ cpFloat iy = cpfabs(bb.t - bb.b);
43
+ cpFloat mody = cpfmod(v.y - bb.b, iy);
43
44
  cpFloat y = (mody > 0.0f) ? mody : mody + iy;
44
45
 
45
46
  return cpv(x + bb.l, y + bb.b);
@@ -20,7 +20,6 @@
20
20
  */
21
21
 
22
22
  #include <stdlib.h>
23
- #include <math.h>
24
23
  #include <float.h>
25
24
 
26
25
  #include "chipmunk.h"
@@ -28,14 +27,17 @@
28
27
  cpBody*
29
28
  cpBodyAlloc(void)
30
29
  {
31
- return (cpBody *)malloc(sizeof(cpBody));
30
+ return (cpBody *)cpmalloc(sizeof(cpBody));
32
31
  }
33
32
 
33
+ cpBodyVelocityFunc cpBodyUpdateVelocityDefault = cpBodyUpdateVelocity;
34
+ cpBodyPositionFunc cpBodyUpdatePositionDefault = cpBodyUpdatePosition;
35
+
34
36
  cpBody*
35
37
  cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
36
38
  {
37
- body->velocity_func = cpBodyUpdateVelocity;
38
- body->position_func = cpBodyUpdatePosition;
39
+ body->velocity_func = cpBodyUpdateVelocityDefault;
40
+ body->position_func = cpBodyUpdatePositionDefault;
39
41
 
40
42
  cpBodySetMass(body, m);
41
43
  cpBodySetMoment(body, i);
@@ -52,6 +54,8 @@ cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
52
54
  body->w_bias = 0.0f;
53
55
 
54
56
  body->data = NULL;
57
+ body->v_limit = (cpFloat)INFINITY;
58
+ body->w_limit = (cpFloat)INFINITY;
55
59
  // body->active = 1;
56
60
 
57
61
  return body;
@@ -68,43 +72,47 @@ void cpBodyDestroy(cpBody *body){}
68
72
  void
69
73
  cpBodyFree(cpBody *body)
70
74
  {
71
- if(body) cpBodyDestroy(body);
72
- free(body);
75
+ if(body){
76
+ cpBodyDestroy(body);
77
+ cpfree(body);
78
+ }
73
79
  }
74
80
 
75
81
  void
76
- cpBodySetMass(cpBody *body, cpFloat m)
82
+ cpBodySetMass(cpBody *body, cpFloat mass)
77
83
  {
78
- body->m = m;
79
- body->m_inv = 1.0f/m;
84
+ body->m = mass;
85
+ body->m_inv = 1.0f/mass;
80
86
  }
81
87
 
82
88
  void
83
- cpBodySetMoment(cpBody *body, cpFloat i)
89
+ cpBodySetMoment(cpBody *body, cpFloat moment)
84
90
  {
85
- body->i = i;
86
- body->i_inv = 1.0f/i;
91
+ body->i = moment;
92
+ body->i_inv = 1.0f/moment;
87
93
  }
88
94
 
89
95
  void
90
- cpBodySetAngle(cpBody *body, cpFloat a)
96
+ cpBodySetAngle(cpBody *body, cpFloat angle)
91
97
  {
92
- body->a = fmod(a, (cpFloat)M_PI*2.0f);
93
- body->rot = cpvforangle(a);
98
+ body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
99
+ body->rot = cpvforangle(angle);
94
100
  }
95
101
 
96
102
  void
97
103
  cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)
98
104
  {
99
105
  cpVect delta = cpvsub(pos, body->p);
100
- body->v = cpvmult(delta, 1.0/dt);
106
+ body->v = cpvmult(delta, 1.0f/dt);
101
107
  }
102
108
 
103
109
  void
104
110
  cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
105
111
  {
106
- body->v = cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt));
107
- body->w = body->w*damping + body->t*body->i_inv*dt;
112
+ body->v = cpvclamp(cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt)), body->v_limit);
113
+
114
+ cpFloat w_limit = body->w_limit;
115
+ body->w = cpfclamp(body->w*damping + body->t*body->i_inv*dt, -w_limit, w_limit);
108
116
  }
109
117
 
110
118
  void
@@ -125,14 +133,14 @@ cpBodyResetForces(cpBody *body)
125
133
  }
126
134
 
127
135
  void
128
- cpBodyApplyForce(cpBody *body, cpVect f, cpVect r)
136
+ cpBodyApplyForce(cpBody *body, cpVect force, cpVect r)
129
137
  {
130
- body->f = cpvadd(body->f, f);
131
- body->t += cpvcross(r, f);
138
+ body->f = cpvadd(body->f, force);
139
+ body->t += cpvcross(r, force);
132
140
  }
133
141
 
134
142
  void
135
- cpDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)
143
+ cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)
136
144
  {
137
145
  // Calculate the world space anchor coordinates.
138
146
  cpVect r1 = cpvrotate(anchr1, a->rot);
@@ -22,34 +22,30 @@
22
22
  #include <stdlib.h>
23
23
  #include <math.h>
24
24
  #include <stdio.h>
25
- #include <assert.h>
26
25
 
27
26
  #include "chipmunk.h"
28
27
 
29
- typedef int (*collisionFunc)(cpShape*, cpShape*, cpContact**);
30
-
31
- static collisionFunc *colfuncs = NULL;
28
+ typedef int (*collisionFunc)(cpShape *, cpShape *, cpContact *);
32
29
 
33
30
  // Add contact points for circle to circle collisions.
34
31
  // Used by several collision tests.
35
32
  static int
36
- circle2circleQuery(cpVect p1, cpVect p2, cpFloat r1, cpFloat r2, cpContact **con)
33
+ circle2circleQuery(cpVect p1, cpVect p2, cpFloat r1, cpFloat r2, cpContact *con)
37
34
  {
38
35
  cpFloat mindist = r1 + r2;
39
36
  cpVect delta = cpvsub(p2, p1);
40
37
  cpFloat distsq = cpvlengthsq(delta);
41
38
  if(distsq >= mindist*mindist) return 0;
42
39
 
43
- cpFloat dist = sqrtf(distsq);
40
+ cpFloat dist = cpfsqrt(distsq);
44
41
  // To avoid singularities, do nothing in the case of dist = 0.
45
42
  cpFloat non_zero_dist = (dist ? dist : INFINITY);
46
43
 
47
44
  // Allocate and initialize the contact.
48
- (*con) = (cpContact *)malloc(sizeof(cpContact));
49
45
  cpContactInit(
50
- (*con),
51
- cpvadd(p1, cpvmult(delta, 0.5 + (r1 - 0.5*mindist)/non_zero_dist)),
52
- cpvmult(delta, 1.0/non_zero_dist),
46
+ con,
47
+ cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/non_zero_dist)),
48
+ cpvmult(delta, 1.0f/non_zero_dist),
53
49
  dist - mindist,
54
50
  0
55
51
  );
@@ -59,7 +55,7 @@ circle2circleQuery(cpVect p1, cpVect p2, cpFloat r1, cpFloat r2, cpContact **con
59
55
 
60
56
  // Collide circle shapes.
61
57
  static int
62
- circle2circle(cpShape *shape1, cpShape *shape2, cpContact **arr)
58
+ circle2circle(cpShape *shape1, cpShape *shape2, cpContact *arr)
63
59
  {
64
60
  cpCircleShape *circ1 = (cpCircleShape *)shape1;
65
61
  cpCircleShape *circ2 = (cpCircleShape *)shape2;
@@ -69,7 +65,7 @@ circle2circle(cpShape *shape1, cpShape *shape2, cpContact **arr)
69
65
 
70
66
  // Collide circles to segment shapes.
71
67
  static int
72
- circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con)
68
+ circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact *con)
73
69
  {
74
70
  cpCircleShape *circ = (cpCircleShape *)circleShape;
75
71
  cpSegmentShape *seg = (cpSegmentShape *)segmentShape;
@@ -79,7 +75,7 @@ circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con)
79
75
 
80
76
  // Calculate normal distance from segment.
81
77
  cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);
82
- cpFloat dist = fabs(dn) - rsum;
78
+ cpFloat dist = cpfabs(dn) - rsum;
83
79
  if(dist > 0.0f) return 0;
84
80
 
85
81
  // Calculate tangential distance along segment.
@@ -97,9 +93,8 @@ circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con)
97
93
  } else {
98
94
  if(dt < dtMax){
99
95
  cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);
100
- (*con) = (cpContact *)malloc(sizeof(cpContact));
101
96
  cpContactInit(
102
- (*con),
97
+ con,
103
98
  cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),
104
99
  n,
105
100
  dist,
@@ -118,25 +113,17 @@ circle2segment(cpShape *circleShape, cpShape *segmentShape, cpContact **con)
118
113
  return 1;
119
114
  }
120
115
 
121
- // Helper function for allocating contact point lists.
116
+ // Helper function for working with contact buffers
117
+ // This used to malloc/realloc memory on the fly but was repurposed.
122
118
  static cpContact *
123
- addContactPoint(cpContact **arr, int *max, int *num)
119
+ nextContactPoint(cpContact *arr, int *numPtr)
124
120
  {
125
- if(*arr == NULL){
126
- // Allocate the array if it hasn't been done.
127
- (*max) = 2;
128
- (*num) = 0;
129
- (*arr) = (cpContact *)malloc((*max)*sizeof(cpContact));
130
- } else if(*num == *max){
131
- // Extend it if necessary.
132
- (*max) *= 2;
133
- (*arr) = (cpContact *)realloc(*arr, (*max)*sizeof(cpContact));
134
- }
121
+ int num = *numPtr;
135
122
 
136
- cpContact *con = &(*arr)[*num];
137
- (*num)++;
123
+ if(num <= CP_MAX_CONTACTS_PER_ARBITER)
124
+ (*numPtr) = num + 1;
138
125
 
139
- return con;
126
+ return &arr[num];
140
127
  }
141
128
 
142
129
  // Find the minimum separating axis for the give poly and axis list.
@@ -145,11 +132,11 @@ findMSA(cpPolyShape *poly, cpPolyShapeAxis *axes, int num, cpFloat *min_out)
145
132
  {
146
133
  int min_index = 0;
147
134
  cpFloat min = cpPolyShapeValueOnAxis(poly, axes->n, axes->d);
148
- if(min > 0.0) return -1;
135
+ if(min > 0.0f) return -1;
149
136
 
150
137
  for(int i=1; i<num; i++){
151
138
  cpFloat dist = cpPolyShapeValueOnAxis(poly, axes[i].n, axes[i].d);
152
- if(dist > 0.0) {
139
+ if(dist > 0.0f) {
153
140
  return -1;
154
141
  } else if(dist > min){
155
142
  min = dist;
@@ -163,21 +150,20 @@ findMSA(cpPolyShape *poly, cpPolyShapeAxis *axes, int num, cpFloat *min_out)
163
150
 
164
151
  // Add contacts for penetrating vertexes.
165
152
  static inline int
166
- findVerts(cpContact **arr, cpPolyShape *poly1, cpPolyShape *poly2, cpVect n, cpFloat dist)
153
+ findVerts(cpContact *arr, cpPolyShape *poly1, cpPolyShape *poly2, cpVect n, cpFloat dist)
167
154
  {
168
- int max = 0;
169
155
  int num = 0;
170
156
 
171
157
  for(int i=0; i<poly1->numVerts; i++){
172
158
  cpVect v = poly1->tVerts[i];
173
159
  if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))
174
- cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly1, i));
160
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));
175
161
  }
176
162
 
177
163
  for(int i=0; i<poly2->numVerts; i++){
178
164
  cpVect v = poly2->tVerts[i];
179
165
  if(cpPolyShapeContainsVertPartial(poly1, v, n))
180
- cpContactInit(addContactPoint(arr, &max, &num), v, n, dist, CP_HASH_PAIR(poly2, i));
166
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));
181
167
  }
182
168
 
183
169
  // if(!num)
@@ -188,7 +174,7 @@ findVerts(cpContact **arr, cpPolyShape *poly1, cpPolyShape *poly2, cpVect n, cpF
188
174
 
189
175
  // Collide poly shapes together.
190
176
  static int
191
- poly2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
177
+ poly2poly(cpShape *shape1, cpShape *shape2, cpContact *arr)
192
178
  {
193
179
  cpPolyShape *poly1 = (cpPolyShape *)shape1;
194
180
  cpPolyShape *poly2 = (cpPolyShape *)shape2;
@@ -209,7 +195,7 @@ poly2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
209
195
  }
210
196
 
211
197
  // Like cpPolyValueOnAxis(), but for segments.
212
- static inline float
198
+ static inline cpFloat
213
199
  segValueOnAxis(cpSegmentShape *seg, cpVect n, cpFloat d)
214
200
  {
215
201
  cpFloat a = cpvdot(n, seg->ta) - seg->r;
@@ -219,7 +205,7 @@ segValueOnAxis(cpSegmentShape *seg, cpVect n, cpFloat d)
219
205
 
220
206
  // Identify vertexes that have penetrated the segment.
221
207
  static inline void
222
- findPointsBehindSeg(cpContact **arr, int *max, int *num, cpSegmentShape *seg, cpPolyShape *poly, cpFloat pDist, cpFloat coef)
208
+ findPointsBehindSeg(cpContact *arr, int *num, cpSegmentShape *seg, cpPolyShape *poly, cpFloat pDist, cpFloat coef)
223
209
  {
224
210
  cpFloat dta = cpvcross(seg->tn, seg->ta);
225
211
  cpFloat dtb = cpvcross(seg->tn, seg->tb);
@@ -230,7 +216,7 @@ findPointsBehindSeg(cpContact **arr, int *max, int *num, cpSegmentShape *seg, cp
230
216
  if(cpvdot(v, n) < cpvdot(seg->tn, seg->ta)*coef + seg->r){
231
217
  cpFloat dt = cpvcross(seg->tn, v);
232
218
  if(dta >= dt && dt >= dtb){
233
- cpContactInit(addContactPoint(arr, max, num), v, n, pDist, CP_HASH_PAIR(poly, i));
219
+ cpContactInit(nextContactPoint(arr, num), v, n, pDist, CP_HASH_PAIR(poly->shape.hashid, i));
234
220
  }
235
221
  }
236
222
  }
@@ -239,7 +225,7 @@ findPointsBehindSeg(cpContact **arr, int *max, int *num, cpSegmentShape *seg, cp
239
225
  // This one is complicated and gross. Just don't go there...
240
226
  // TODO: Comment me!
241
227
  static int
242
- seg2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
228
+ seg2poly(cpShape *shape1, cpShape *shape2, cpContact *arr)
243
229
  {
244
230
  cpSegmentShape *seg = (cpSegmentShape *)shape1;
245
231
  cpPolyShape *poly = (cpPolyShape *)shape2;
@@ -263,7 +249,6 @@ seg2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
263
249
  }
264
250
  }
265
251
 
266
- int max = 0;
267
252
  int num = 0;
268
253
 
269
254
  cpVect poly_n = cpvneg(axes[mini].n);
@@ -271,18 +256,18 @@ seg2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
271
256
  cpVect va = cpvadd(seg->ta, cpvmult(poly_n, seg->r));
272
257
  cpVect vb = cpvadd(seg->tb, cpvmult(poly_n, seg->r));
273
258
  if(cpPolyShapeContainsVert(poly, va))
274
- cpContactInit(addContactPoint(arr, &max, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg, 0));
259
+ cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 0));
275
260
  if(cpPolyShapeContainsVert(poly, vb))
276
- cpContactInit(addContactPoint(arr, &max, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg, 1));
261
+ cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 1));
277
262
 
278
263
  // Floating point precision problems here.
279
264
  // This will have to do for now.
280
265
  poly_min -= cp_collision_slop;
281
266
  if(minNorm >= poly_min || minNeg >= poly_min) {
282
267
  if(minNorm > minNeg)
283
- findPointsBehindSeg(arr, &max, &num, seg, poly, minNorm, 1.0f);
268
+ findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f);
284
269
  else
285
- findPointsBehindSeg(arr, &max, &num, seg, poly, minNeg, -1.0f);
270
+ findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f);
286
271
  }
287
272
 
288
273
  // If no other collision points are found, try colliding endpoints.
@@ -309,7 +294,7 @@ seg2poly(cpShape *shape1, cpShape *shape2, cpContact **arr)
309
294
  // This one is less gross, but still gross.
310
295
  // TODO: Comment me!
311
296
  static int
312
- circle2poly(cpShape *shape1, cpShape *shape2, cpContact **con)
297
+ circle2poly(cpShape *shape1, cpShape *shape2, cpContact *con)
313
298
  {
314
299
  cpCircleShape *circ = (cpCircleShape *)shape1;
315
300
  cpPolyShape *poly = (cpPolyShape *)shape2;
@@ -319,7 +304,7 @@ circle2poly(cpShape *shape1, cpShape *shape2, cpContact **con)
319
304
  cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;
320
305
  for(int i=0; i<poly->numVerts; i++){
321
306
  cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;
322
- if(dist > 0.0){
307
+ if(dist > 0.0f){
323
308
  return 0;
324
309
  } else if(dist > min) {
325
310
  min = dist;
@@ -337,9 +322,8 @@ circle2poly(cpShape *shape1, cpShape *shape2, cpContact **con)
337
322
  if(dt < dtb){
338
323
  return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);
339
324
  } else if(dt < dta) {
340
- (*con) = (cpContact *)malloc(sizeof(cpContact));
341
325
  cpContactInit(
342
- (*con),
326
+ con,
343
327
  cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),
344
328
  cpvneg(n),
345
329
  min,
@@ -352,6 +336,21 @@ circle2poly(cpShape *shape1, cpShape *shape2, cpContact **con)
352
336
  }
353
337
  }
354
338
 
339
+ //static const collisionFunc builtinCollisionFuncs[9] = {
340
+ // circle2circle,
341
+ // NULL,
342
+ // NULL,
343
+ // circle2segment,
344
+ // NULL,
345
+ // NULL,
346
+ // circle2poly,
347
+ // seg2poly,
348
+ // poly2poly,
349
+ //};
350
+ //static const collisionFunc *colfuncs = builtinCollisionFuncs;
351
+
352
+ static collisionFunc *colfuncs = NULL;
353
+
355
354
  static void
356
355
  addColFunc(cpShapeType a, cpShapeType b, collisionFunc func)
357
356
  {
@@ -361,13 +360,15 @@ addColFunc(cpShapeType a, cpShapeType b, collisionFunc func)
361
360
  #ifdef __cplusplus
362
361
  extern "C" {
363
362
  #endif
363
+ void cpInitCollisionFuncs(void);
364
+
364
365
  // Initializes the array of collision functions.
365
366
  // Called by cpInitChipmunk().
366
367
  void
367
368
  cpInitCollisionFuncs(void)
368
369
  {
369
370
  if(!colfuncs)
370
- colfuncs = (collisionFunc *)calloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));
371
+ colfuncs = (collisionFunc *)cpcalloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));
371
372
 
372
373
  addColFunc(CP_CIRCLE_SHAPE, CP_CIRCLE_SHAPE, circle2circle);
373
374
  addColFunc(CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, circle2segment);
@@ -380,10 +381,10 @@ extern "C" {
380
381
  #endif
381
382
 
382
383
  int
383
- cpCollideShapes(cpShape *a, cpShape *b, cpContact **arr)
384
+ cpCollideShapes(cpShape *a, cpShape *b, cpContact *arr)
384
385
  {
385
386
  // Their shape types must be in order.
386
- assert(a->klass->type <= b->klass->type);
387
+ cpAssert(a->klass->type <= b->klass->type, "Collision shapes passed to cpCollideShapes() are not sorted.");
387
388
 
388
389
  collisionFunc cfunc = colfuncs[a->klass->type + b->klass->type*CP_NUM_SHAPES];
389
390
  return (cfunc) ? cfunc(a, b, arr) : 0;