chipmunk 5.3.4.0-x86-mingw32 → 5.3.4.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/README +33 -13
  2. data/Rakefile +20 -7
  3. data/ext/chipmunk/extconf.rb +55 -12
  4. data/ext/chipmunk/rb_chipmunk.c +92 -98
  5. data/ext/chipmunk/rb_chipmunk.h +44 -34
  6. data/ext/chipmunk/rb_cpArbiter.c +135 -98
  7. data/ext/chipmunk/rb_cpBB.c +84 -101
  8. data/ext/chipmunk/rb_cpBody.c +219 -241
  9. data/ext/chipmunk/rb_cpConstraint.c +173 -185
  10. data/ext/chipmunk/rb_cpShape.c +347 -251
  11. data/ext/chipmunk/rb_cpSpace.c +376 -408
  12. data/ext/chipmunk/rb_cpVect.c +132 -170
  13. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk.h +163 -0
  14. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_ffi.h +59 -0
  15. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_private.h +49 -0
  16. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_types.h +151 -0
  17. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/chipmunk_unsafe.h +54 -0
  18. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpConstraint.h +105 -0
  19. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
  20. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpDampedSpring.h +53 -0
  21. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpGearJoint.h +41 -0
  22. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpGrooveJoint.h +48 -0
  23. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpPinJoint.h +43 -0
  24. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpPivotJoint.h +42 -0
  25. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
  26. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
  27. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
  28. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/cpSlideJoint.h +44 -0
  29. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/constraints/util.h +134 -0
  30. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpArbiter.h +188 -0
  31. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpArray.h +49 -0
  32. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpBB.h +74 -0
  33. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpBody.h +219 -0
  34. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpCollision.h +28 -0
  35. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpHashSet.h +82 -0
  36. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpPolyShape.h +103 -0
  37. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpShape.h +177 -0
  38. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpSpace.h +206 -0
  39. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpSpaceHash.h +110 -0
  40. data/ext/chipmunk/vendor/chipmunk-5.3.4/include/chipmunk/cpVect.h +207 -0
  41. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/chipmunk.c +151 -0
  42. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpConstraint.c +54 -0
  43. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpDampedRotarySpring.c +105 -0
  44. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpDampedSpring.c +115 -0
  45. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpGearJoint.c +113 -0
  46. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpGrooveJoint.c +161 -0
  47. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpPinJoint.c +116 -0
  48. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpPivotJoint.c +114 -0
  49. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpRatchetJoint.c +126 -0
  50. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpRotaryLimitJoint.c +120 -0
  51. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpSimpleMotor.c +97 -0
  52. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/constraints/cpSlideJoint.c +129 -0
  53. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpArbiter.c +280 -0
  54. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpArray.c +143 -0
  55. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpBB.c +47 -0
  56. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpBody.c +192 -0
  57. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpCollision.c +411 -0
  58. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpHashSet.c +253 -0
  59. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpPolyShape.c +240 -0
  60. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpShape.c +405 -0
  61. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpace.c +499 -0
  62. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceComponent.c +279 -0
  63. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceHash.c +534 -0
  64. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceQuery.c +246 -0
  65. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpSpaceStep.c +398 -0
  66. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/cpVect.c +71 -0
  67. data/ext/chipmunk/vendor/chipmunk-5.3.4/src/prime.h +68 -0
  68. data/lib/1.9/chipmunk.so +0 -0
  69. data/lib/chipmunk.rb +19 -8
  70. metadata +84 -42
  71. data/lib/1.8/chipmunk.so +0 -0
@@ -0,0 +1,47 @@
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 <math.h>
23
+ #include <stdlib.h>
24
+
25
+ #include "chipmunk.h"
26
+
27
+ cpVect
28
+ cpBBClampVect(const cpBB bb, const cpVect v)
29
+ {
30
+ cpFloat x = cpfmin(cpfmax(bb.l, v.x), bb.r);
31
+ cpFloat y = cpfmin(cpfmax(bb.b, v.y), bb.t);
32
+ return cpv(x, y);
33
+ }
34
+
35
+ cpVect
36
+ cpBBWrapVect(const cpBB bb, const cpVect v)
37
+ {
38
+ cpFloat ix = cpfabs(bb.r - bb.l);
39
+ cpFloat modx = cpfmod(v.x - bb.l, ix);
40
+ cpFloat x = (modx > 0.0f) ? modx : modx + ix;
41
+
42
+ cpFloat iy = cpfabs(bb.t - bb.b);
43
+ cpFloat mody = cpfmod(v.y - bb.b, iy);
44
+ cpFloat y = (mody > 0.0f) ? mody : mody + iy;
45
+
46
+ return cpv(x + bb.l, y + bb.b);
47
+ }
@@ -0,0 +1,192 @@
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 <float.h>
24
+ #include <stdarg.h>
25
+
26
+ #include "chipmunk_private.h"
27
+
28
+ // initialized in cpInitChipmunk()
29
+ cpBody cpStaticBodySingleton;
30
+
31
+ cpBody*
32
+ cpBodyAlloc(void)
33
+ {
34
+ return (cpBody *)cpmalloc(sizeof(cpBody));
35
+ }
36
+
37
+ cpBodyVelocityFunc cpBodyUpdateVelocityDefault = cpBodyUpdateVelocity;
38
+ cpBodyPositionFunc cpBodyUpdatePositionDefault = cpBodyUpdatePosition;
39
+
40
+ cpBody*
41
+ cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
42
+ {
43
+ body->velocity_func = cpBodyUpdateVelocityDefault;
44
+ body->position_func = cpBodyUpdatePositionDefault;
45
+
46
+ cpBodySetMass(body, m);
47
+ cpBodySetMoment(body, i);
48
+
49
+ body->p = cpvzero;
50
+ body->v = cpvzero;
51
+ body->f = cpvzero;
52
+
53
+ cpBodySetAngle(body, 0.0f);
54
+ body->w = 0.0f;
55
+ body->t = 0.0f;
56
+
57
+ body->v_bias = cpvzero;
58
+ body->w_bias = 0.0f;
59
+
60
+ body->data = NULL;
61
+ body->v_limit = (cpFloat)INFINITY;
62
+ body->w_limit = (cpFloat)INFINITY;
63
+
64
+ body->space = NULL;
65
+ body->shapesList = NULL;
66
+
67
+ cpComponentNode node = {NULL, NULL, 0, 0.0f};
68
+ body->node = node;
69
+
70
+ return body;
71
+ }
72
+
73
+ cpBody*
74
+ cpBodyNew(cpFloat m, cpFloat i)
75
+ {
76
+ return cpBodyInit(cpBodyAlloc(), m, i);
77
+ }
78
+
79
+ cpBody *
80
+ cpBodyInitStatic(cpBody *body)
81
+ {
82
+ cpBodyInit(body, (cpFloat)INFINITY, (cpFloat)INFINITY);
83
+ body->node.idleTime = (cpFloat)INFINITY;
84
+
85
+ return body;
86
+ }
87
+
88
+ cpBody *
89
+ cpBodyNewStatic()
90
+ {
91
+ return cpBodyInitStatic(cpBodyAlloc());
92
+ }
93
+
94
+ void cpBodyDestroy(cpBody *body){}
95
+
96
+ void
97
+ cpBodyFree(cpBody *body)
98
+ {
99
+ if(body){
100
+ cpBodyDestroy(body);
101
+ cpfree(body);
102
+ }
103
+ }
104
+
105
+ void
106
+ cpBodySetMass(cpBody *body, cpFloat mass)
107
+ {
108
+ body->m = mass;
109
+ body->m_inv = 1.0f/mass;
110
+ }
111
+
112
+ void
113
+ cpBodySetMoment(cpBody *body, cpFloat moment)
114
+ {
115
+ body->i = moment;
116
+ body->i_inv = 1.0f/moment;
117
+ }
118
+
119
+ void
120
+ cpBodySetAngle(cpBody *body, cpFloat angle)
121
+ {
122
+ body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
123
+ body->rot = cpvforangle(angle);
124
+ }
125
+
126
+ void
127
+ cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)
128
+ {
129
+ cpVect delta = cpvsub(pos, body->p);
130
+ body->v = cpvmult(delta, 1.0f/dt);
131
+ }
132
+
133
+ void
134
+ cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
135
+ {
136
+ body->v = cpvclamp(cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt)), body->v_limit);
137
+
138
+ cpFloat w_limit = body->w_limit;
139
+ body->w = cpfclamp(body->w*damping + body->t*body->i_inv*dt, -w_limit, w_limit);
140
+ }
141
+
142
+ void
143
+ cpBodyUpdatePosition(cpBody *body, cpFloat dt)
144
+ {
145
+ body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));
146
+ cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt);
147
+
148
+ body->v_bias = cpvzero;
149
+ body->w_bias = 0.0f;
150
+ }
151
+
152
+ void
153
+ cpBodyResetForces(cpBody *body)
154
+ {
155
+ body->f = cpvzero;
156
+ body->t = 0.0f;
157
+ }
158
+
159
+ void
160
+ cpBodyApplyForce(cpBody *body, cpVect force, cpVect r)
161
+ {
162
+ body->f = cpvadd(body->f, force);
163
+ body->t += cpvcross(r, force);
164
+ }
165
+
166
+ void
167
+ cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)
168
+ {
169
+ // Calculate the world space anchor coordinates.
170
+ cpVect r1 = cpvrotate(anchr1, a->rot);
171
+ cpVect r2 = cpvrotate(anchr2, b->rot);
172
+
173
+ cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));
174
+ cpFloat dist = cpvlength(delta);
175
+ cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;
176
+
177
+ cpFloat f_spring = (dist - rlen)*k;
178
+
179
+ // Calculate the world relative velocities of the anchor points.
180
+ cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
181
+ cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
182
+
183
+ // Calculate the damping force.
184
+ // This really should be in the impulse solver and can produce problems when using large damping values.
185
+ cpFloat vrn = cpvdot(cpvsub(v2, v1), n);
186
+ cpFloat f_damp = vrn*cpfmin(dmp, 1.0f/(dt*(a->m_inv + b->m_inv)));
187
+
188
+ // Apply!
189
+ cpVect f = cpvmult(n, f_spring + f_damp);
190
+ cpBodyApplyForce(a, f, r1);
191
+ cpBodyApplyForce(b, cpvneg(f), r2);
192
+ }
@@ -0,0 +1,411 @@
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 <math.h>
24
+ //#include <stdio.h>
25
+
26
+ #include "chipmunk_private.h"
27
+
28
+ typedef int (*collisionFunc)(const cpShape *, const cpShape *, cpContact *);
29
+
30
+ // Add contact points for circle to circle collisions.
31
+ // Used by several collision tests.
32
+ static int
33
+ circle2circleQuery(const cpVect p1, const cpVect p2, const cpFloat r1, const cpFloat r2, cpContact *con)
34
+ {
35
+ cpFloat mindist = r1 + r2;
36
+ cpVect delta = cpvsub(p2, p1);
37
+ cpFloat distsq = cpvlengthsq(delta);
38
+ if(distsq >= mindist*mindist) return 0;
39
+
40
+ cpFloat dist = cpfsqrt(distsq);
41
+
42
+ // Allocate and initialize the contact.
43
+ cpContactInit(
44
+ con,
45
+ cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/(dist ? dist : INFINITY))),
46
+ (dist ? cpvmult(delta, 1.0f/dist) : cpv(1.0f, 0.0f)),
47
+ dist - mindist,
48
+ 0
49
+ );
50
+
51
+ return 1;
52
+ }
53
+
54
+ // Collide circle shapes.
55
+ static int
56
+ circle2circle(const cpShape *shape1, const cpShape *shape2, cpContact *arr)
57
+ {
58
+ cpCircleShape *circ1 = (cpCircleShape *)shape1;
59
+ cpCircleShape *circ2 = (cpCircleShape *)shape2;
60
+
61
+ return circle2circleQuery(circ1->tc, circ2->tc, circ1->r, circ2->r, arr);
62
+ }
63
+
64
+ // Collide circles to segment shapes.
65
+ static int
66
+ circle2segment(const cpShape *circleShape, const cpShape *segmentShape, cpContact *con)
67
+ {
68
+ cpCircleShape *circ = (cpCircleShape *)circleShape;
69
+ cpSegmentShape *seg = (cpSegmentShape *)segmentShape;
70
+
71
+ // Radius sum
72
+ cpFloat rsum = circ->r + seg->r;
73
+
74
+ // Calculate normal distance from segment.
75
+ cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);
76
+ cpFloat dist = cpfabs(dn) - rsum;
77
+ if(dist > 0.0f) return 0;
78
+
79
+ // Calculate tangential distance along segment.
80
+ cpFloat dt = -cpvcross(seg->tn, circ->tc);
81
+ cpFloat dtMin = -cpvcross(seg->tn, seg->ta);
82
+ cpFloat dtMax = -cpvcross(seg->tn, seg->tb);
83
+
84
+ // Decision tree to decide which feature of the segment to collide with.
85
+ if(dt < dtMin){
86
+ if(dt < (dtMin - rsum)){
87
+ return 0;
88
+ } else {
89
+ return circle2circleQuery(circ->tc, seg->ta, circ->r, seg->r, con);
90
+ }
91
+ } else {
92
+ if(dt < dtMax){
93
+ cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);
94
+ cpContactInit(
95
+ con,
96
+ cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),
97
+ n,
98
+ dist,
99
+ 0
100
+ );
101
+ return 1;
102
+ } else {
103
+ if(dt < (dtMax + rsum)) {
104
+ return circle2circleQuery(circ->tc, seg->tb, circ->r, seg->r, con);
105
+ } else {
106
+ return 0;
107
+ }
108
+ }
109
+ }
110
+
111
+ return 1;
112
+ }
113
+
114
+ // Helper function for working with contact buffers
115
+ // This used to malloc/realloc memory on the fly but was repurposed.
116
+ static cpContact *
117
+ nextContactPoint(cpContact *arr, int *numPtr)
118
+ {
119
+ int index = *numPtr;
120
+
121
+ if(index < CP_MAX_CONTACTS_PER_ARBITER){
122
+ (*numPtr) = index + 1;
123
+ return &arr[index];
124
+ } else {
125
+ return &arr[CP_MAX_CONTACTS_PER_ARBITER - 1];
126
+ }
127
+ }
128
+
129
+ // Find the minimum separating axis for the give poly and axis list.
130
+ static inline int
131
+ findMSA(const cpPolyShape *poly, const cpPolyShapeAxis *axes, const int num, cpFloat *min_out)
132
+ {
133
+ int min_index = 0;
134
+ cpFloat min = cpPolyShapeValueOnAxis(poly, axes->n, axes->d);
135
+ if(min > 0.0f) return -1;
136
+
137
+ for(int i=1; i<num; i++){
138
+ cpFloat dist = cpPolyShapeValueOnAxis(poly, axes[i].n, axes[i].d);
139
+ if(dist > 0.0f) {
140
+ return -1;
141
+ } else if(dist > min){
142
+ min = dist;
143
+ min_index = i;
144
+ }
145
+ }
146
+
147
+ (*min_out) = min;
148
+ return min_index;
149
+ }
150
+
151
+ // Add contacts for probably penetrating vertexes.
152
+ // This handles the degenerate case where an overlap was detected, but no vertexes fall inside
153
+ // the opposing polygon. (like a star of david)
154
+ static inline int
155
+ findVertsFallback(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)
156
+ {
157
+ int num = 0;
158
+
159
+ for(int i=0; i<poly1->numVerts; i++){
160
+ cpVect v = poly1->tVerts[i];
161
+ if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))
162
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));
163
+ }
164
+
165
+ for(int i=0; i<poly2->numVerts; i++){
166
+ cpVect v = poly2->tVerts[i];
167
+ if(cpPolyShapeContainsVertPartial(poly1, v, n))
168
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));
169
+ }
170
+
171
+ return num;
172
+ }
173
+
174
+ // Add contacts for penetrating vertexes.
175
+ static inline int
176
+ findVerts(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)
177
+ {
178
+ int num = 0;
179
+
180
+ for(int i=0; i<poly1->numVerts; i++){
181
+ cpVect v = poly1->tVerts[i];
182
+ if(cpPolyShapeContainsVert(poly2, v))
183
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));
184
+ }
185
+
186
+ for(int i=0; i<poly2->numVerts; i++){
187
+ cpVect v = poly2->tVerts[i];
188
+ if(cpPolyShapeContainsVert(poly1, v))
189
+ cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));
190
+ }
191
+
192
+ return (num ? num : findVertsFallback(arr, poly1, poly2, n, dist));
193
+ }
194
+
195
+ // Collide poly shapes together.
196
+ static int
197
+ poly2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)
198
+ {
199
+ cpPolyShape *poly1 = (cpPolyShape *)shape1;
200
+ cpPolyShape *poly2 = (cpPolyShape *)shape2;
201
+
202
+ cpFloat min1;
203
+ int mini1 = findMSA(poly2, poly1->tAxes, poly1->numVerts, &min1);
204
+ if(mini1 == -1) return 0;
205
+
206
+ cpFloat min2;
207
+ int mini2 = findMSA(poly1, poly2->tAxes, poly2->numVerts, &min2);
208
+ if(mini2 == -1) return 0;
209
+
210
+ // There is overlap, find the penetrating verts
211
+ if(min1 > min2)
212
+ return findVerts(arr, poly1, poly2, poly1->tAxes[mini1].n, min1);
213
+ else
214
+ return findVerts(arr, poly1, poly2, cpvneg(poly2->tAxes[mini2].n), min2);
215
+ }
216
+
217
+ // Like cpPolyValueOnAxis(), but for segments.
218
+ static inline cpFloat
219
+ segValueOnAxis(const cpSegmentShape *seg, const cpVect n, const cpFloat d)
220
+ {
221
+ cpFloat a = cpvdot(n, seg->ta) - seg->r;
222
+ cpFloat b = cpvdot(n, seg->tb) - seg->r;
223
+ return cpfmin(a, b) - d;
224
+ }
225
+
226
+ // Identify vertexes that have penetrated the segment.
227
+ static inline void
228
+ findPointsBehindSeg(cpContact *arr, int *num, const cpSegmentShape *seg, const cpPolyShape *poly, const cpFloat pDist, const cpFloat coef)
229
+ {
230
+ cpFloat dta = cpvcross(seg->tn, seg->ta);
231
+ cpFloat dtb = cpvcross(seg->tn, seg->tb);
232
+ cpVect n = cpvmult(seg->tn, coef);
233
+
234
+ for(int i=0; i<poly->numVerts; i++){
235
+ cpVect v = poly->tVerts[i];
236
+ if(cpvdot(v, n) < cpvdot(seg->tn, seg->ta)*coef + seg->r){
237
+ cpFloat dt = cpvcross(seg->tn, v);
238
+ if(dta >= dt && dt >= dtb){
239
+ cpContactInit(nextContactPoint(arr, num), v, n, pDist, CP_HASH_PAIR(poly->shape.hashid, i));
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ // This one is complicated and gross. Just don't go there...
246
+ // TODO: Comment me!
247
+ static int
248
+ seg2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)
249
+ {
250
+ cpSegmentShape *seg = (cpSegmentShape *)shape1;
251
+ cpPolyShape *poly = (cpPolyShape *)shape2;
252
+ cpPolyShapeAxis *axes = poly->tAxes;
253
+
254
+ cpFloat segD = cpvdot(seg->tn, seg->ta);
255
+ cpFloat minNorm = cpPolyShapeValueOnAxis(poly, seg->tn, segD) - seg->r;
256
+ cpFloat minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg->tn), -segD) - seg->r;
257
+ if(minNeg > 0.0f || minNorm > 0.0f) return 0;
258
+
259
+ int mini = 0;
260
+ cpFloat poly_min = segValueOnAxis(seg, axes->n, axes->d);
261
+ if(poly_min > 0.0f) return 0;
262
+ for(int i=0; i<poly->numVerts; i++){
263
+ cpFloat dist = segValueOnAxis(seg, axes[i].n, axes[i].d);
264
+ if(dist > 0.0f){
265
+ return 0;
266
+ } else if(dist > poly_min){
267
+ poly_min = dist;
268
+ mini = i;
269
+ }
270
+ }
271
+
272
+ int num = 0;
273
+
274
+ cpVect poly_n = cpvneg(axes[mini].n);
275
+
276
+ cpVect va = cpvadd(seg->ta, cpvmult(poly_n, seg->r));
277
+ cpVect vb = cpvadd(seg->tb, cpvmult(poly_n, seg->r));
278
+ if(cpPolyShapeContainsVert(poly, va))
279
+ cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 0));
280
+ if(cpPolyShapeContainsVert(poly, vb))
281
+ cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 1));
282
+
283
+ // Floating point precision problems here.
284
+ // This will have to do for now.
285
+ poly_min -= cp_collision_slop;
286
+ if(minNorm >= poly_min || minNeg >= poly_min) {
287
+ if(minNorm > minNeg)
288
+ findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f);
289
+ else
290
+ findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f);
291
+ }
292
+
293
+ // If no other collision points are found, try colliding endpoints.
294
+ if(num == 0){
295
+ cpVect poly_a = poly->tVerts[mini];
296
+ cpVect poly_b = poly->tVerts[(mini + 1)%poly->numVerts];
297
+
298
+ if(circle2circleQuery(seg->ta, poly_a, seg->r, 0.0f, arr))
299
+ return 1;
300
+
301
+ if(circle2circleQuery(seg->tb, poly_a, seg->r, 0.0f, arr))
302
+ return 1;
303
+
304
+ if(circle2circleQuery(seg->ta, poly_b, seg->r, 0.0f, arr))
305
+ return 1;
306
+
307
+ if(circle2circleQuery(seg->tb, poly_b, seg->r, 0.0f, arr))
308
+ return 1;
309
+ }
310
+
311
+ return num;
312
+ }
313
+
314
+ // This one is less gross, but still gross.
315
+ // TODO: Comment me!
316
+ static int
317
+ circle2poly(const cpShape *shape1, const cpShape *shape2, cpContact *con)
318
+ {
319
+ cpCircleShape *circ = (cpCircleShape *)shape1;
320
+ cpPolyShape *poly = (cpPolyShape *)shape2;
321
+ cpPolyShapeAxis *axes = poly->tAxes;
322
+
323
+ int mini = 0;
324
+ cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;
325
+ for(int i=0; i<poly->numVerts; i++){
326
+ cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;
327
+ if(dist > 0.0f){
328
+ return 0;
329
+ } else if(dist > min) {
330
+ min = dist;
331
+ mini = i;
332
+ }
333
+ }
334
+
335
+ cpVect n = axes[mini].n;
336
+ cpVect a = poly->tVerts[mini];
337
+ cpVect b = poly->tVerts[(mini + 1)%poly->numVerts];
338
+ cpFloat dta = cpvcross(n, a);
339
+ cpFloat dtb = cpvcross(n, b);
340
+ cpFloat dt = cpvcross(n, circ->tc);
341
+
342
+ if(dt < dtb){
343
+ return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);
344
+ } else if(dt < dta) {
345
+ cpContactInit(
346
+ con,
347
+ cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),
348
+ cpvneg(n),
349
+ min,
350
+ 0
351
+ );
352
+
353
+ return 1;
354
+ } else {
355
+ return circle2circleQuery(circ->tc, a, circ->r, 0.0f, con);
356
+ }
357
+ }
358
+
359
+ //static const collisionFunc builtinCollisionFuncs[9] = {
360
+ // circle2circle,
361
+ // NULL,
362
+ // NULL,
363
+ // circle2segment,
364
+ // NULL,
365
+ // NULL,
366
+ // circle2poly,
367
+ // seg2poly,
368
+ // poly2poly,
369
+ //};
370
+ //static const collisionFunc *colfuncs = builtinCollisionFuncs;
371
+
372
+ static collisionFunc *colfuncs = NULL;
373
+
374
+ static void
375
+ addColFunc(const cpShapeType a, const cpShapeType b, const collisionFunc func)
376
+ {
377
+ colfuncs[a + b*CP_NUM_SHAPES] = func;
378
+ }
379
+
380
+ #ifdef __cplusplus
381
+ extern "C" {
382
+ #endif
383
+ void cpInitCollisionFuncs(void);
384
+
385
+ // Initializes the array of collision functions.
386
+ // Called by cpInitChipmunk().
387
+ void
388
+ cpInitCollisionFuncs(void)
389
+ {
390
+ if(!colfuncs)
391
+ colfuncs = (collisionFunc *)cpcalloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));
392
+
393
+ addColFunc(CP_CIRCLE_SHAPE, CP_CIRCLE_SHAPE, circle2circle);
394
+ addColFunc(CP_CIRCLE_SHAPE, CP_SEGMENT_SHAPE, circle2segment);
395
+ addColFunc(CP_SEGMENT_SHAPE, CP_POLY_SHAPE, seg2poly);
396
+ addColFunc(CP_CIRCLE_SHAPE, CP_POLY_SHAPE, circle2poly);
397
+ addColFunc(CP_POLY_SHAPE, CP_POLY_SHAPE, poly2poly);
398
+ }
399
+ #ifdef __cplusplus
400
+ }
401
+ #endif
402
+
403
+ int
404
+ cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr)
405
+ {
406
+ // Their shape types must be in order.
407
+ cpAssert(a->klass->type <= b->klass->type, "Collision shapes passed to cpCollideShapes() are not sorted.");
408
+
409
+ collisionFunc cfunc = colfuncs[a->klass->type + b->klass->type*CP_NUM_SHAPES];
410
+ return (cfunc) ? cfunc(a, b, arr) : 0;
411
+ }