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