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,253 @@
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 <assert.h>
24
+
25
+ #include "chipmunk_private.h"
26
+ #include "prime.h"
27
+
28
+ static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
29
+
30
+ void
31
+ cpHashSetDestroy(cpHashSet *set)
32
+ {
33
+ // Free the table.
34
+ cpfree(set->table);
35
+
36
+ cpArrayEach(set->allocatedBuffers, freeWrap, NULL);
37
+ cpArrayFree(set->allocatedBuffers);
38
+ }
39
+
40
+ void
41
+ cpHashSetFree(cpHashSet *set)
42
+ {
43
+ if(set){
44
+ cpHashSetDestroy(set);
45
+ cpfree(set);
46
+ }
47
+ }
48
+
49
+ cpHashSet *
50
+ cpHashSetAlloc(void)
51
+ {
52
+ return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));
53
+ }
54
+
55
+ cpHashSet *
56
+ cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
57
+ {
58
+ set->size = next_prime(size);
59
+ set->entries = 0;
60
+
61
+ set->eql = eqlFunc;
62
+ set->trans = trans;
63
+
64
+ set->default_value = NULL;
65
+
66
+ set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));
67
+ set->pooledBins = NULL;
68
+
69
+ set->allocatedBuffers = cpArrayNew(0);
70
+
71
+ return set;
72
+ }
73
+
74
+ cpHashSet *
75
+ cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)
76
+ {
77
+ return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);
78
+ }
79
+
80
+ static int
81
+ setIsFull(cpHashSet *set)
82
+ {
83
+ return (set->entries >= set->size);
84
+ }
85
+
86
+ static void
87
+ cpHashSetResize(cpHashSet *set)
88
+ {
89
+ // Get the next approximate doubled prime.
90
+ int newSize = next_prime(set->size + 1);
91
+ // Allocate a new table.
92
+ cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));
93
+
94
+ // Iterate over the chains.
95
+ for(int i=0; i<set->size; i++){
96
+ // Rehash the bins into the new table.
97
+ cpHashSetBin *bin = set->table[i];
98
+ while(bin){
99
+ cpHashSetBin *next = bin->next;
100
+
101
+ int idx = bin->hash%newSize;
102
+ bin->next = newTable[idx];
103
+ newTable[idx] = bin;
104
+
105
+ bin = next;
106
+ }
107
+ }
108
+
109
+ cpfree(set->table);
110
+
111
+ set->table = newTable;
112
+ set->size = newSize;
113
+ }
114
+
115
+ static inline void
116
+ recycleBin(cpHashSet *set, cpHashSetBin *bin)
117
+ {
118
+ bin->next = set->pooledBins;
119
+ set->pooledBins = bin;
120
+ bin->elt = NULL;
121
+ }
122
+
123
+ static cpHashSetBin *
124
+ getUnusedBin(cpHashSet *set)
125
+ {
126
+ cpHashSetBin *bin = set->pooledBins;
127
+
128
+ if(bin){
129
+ set->pooledBins = bin->next;
130
+ return bin;
131
+ } else {
132
+ // Pool is exhausted, make more
133
+ int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);
134
+ cpAssert(count, "Buffer size is too small.");
135
+
136
+ cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
137
+ cpArrayPush(set->allocatedBuffers, buffer);
138
+
139
+ // push all but the first one, return the first instead
140
+ for(int i=1; i<count; i++) recycleBin(set, buffer + i);
141
+ return buffer;
142
+ }
143
+ }
144
+
145
+ void *
146
+ cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
147
+ {
148
+ int idx = hash%set->size;
149
+
150
+ // Find the bin with the matching element.
151
+ cpHashSetBin *bin = set->table[idx];
152
+ while(bin && !set->eql(ptr, bin->elt))
153
+ bin = bin->next;
154
+
155
+ // Create it necessary.
156
+ if(!bin){
157
+ bin = getUnusedBin(set);
158
+ bin->hash = hash;
159
+ bin->elt = set->trans(ptr, data); // Transform the pointer.
160
+
161
+ bin->next = set->table[idx];
162
+ set->table[idx] = bin;
163
+
164
+ set->entries++;
165
+
166
+ // Resize the set if it's full.
167
+ if(setIsFull(set))
168
+ cpHashSetResize(set);
169
+ }
170
+
171
+ return bin->elt;
172
+ }
173
+
174
+ void *
175
+ cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
176
+ {
177
+ int idx = hash%set->size;
178
+
179
+ // Pointer to the previous bin pointer.
180
+ cpHashSetBin **prev_ptr = &set->table[idx];
181
+ // Pointer the the current bin.
182
+ cpHashSetBin *bin = set->table[idx];
183
+
184
+ // Find the bin
185
+ while(bin && !set->eql(ptr, bin->elt)){
186
+ prev_ptr = &bin->next;
187
+ bin = bin->next;
188
+ }
189
+
190
+ // Remove it if it exists.
191
+ if(bin){
192
+ // Update the previous bin pointer to point to the next bin.
193
+ (*prev_ptr) = bin->next;
194
+ set->entries--;
195
+
196
+ void *return_value = bin->elt;
197
+
198
+ recycleBin(set, bin);
199
+
200
+ return return_value;
201
+ }
202
+
203
+ return NULL;
204
+ }
205
+
206
+ void *
207
+ cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
208
+ {
209
+ int idx = hash%set->size;
210
+ cpHashSetBin *bin = set->table[idx];
211
+ while(bin && !set->eql(ptr, bin->elt))
212
+ bin = bin->next;
213
+
214
+ return (bin ? bin->elt : set->default_value);
215
+ }
216
+
217
+ void
218
+ cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)
219
+ {
220
+ for(int i=0; i<set->size; i++){
221
+ cpHashSetBin *bin = set->table[i];
222
+ while(bin){
223
+ cpHashSetBin *next = bin->next;
224
+ func(bin->elt, data);
225
+ bin = next;
226
+ }
227
+ }
228
+ }
229
+
230
+ void
231
+ cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)
232
+ {
233
+ // Iterate over all the chains.
234
+ for(int i=0; i<set->size; i++){
235
+ // The rest works similarly to cpHashSetRemove() above.
236
+ cpHashSetBin **prev_ptr = &set->table[i];
237
+ cpHashSetBin *bin = set->table[i];
238
+ while(bin){
239
+ cpHashSetBin *next = bin->next;
240
+
241
+ if(func(bin->elt, data)){
242
+ prev_ptr = &bin->next;
243
+ } else {
244
+ (*prev_ptr) = next;
245
+
246
+ set->entries--;
247
+ recycleBin(set, bin);
248
+ }
249
+
250
+ bin = next;
251
+ }
252
+ }
253
+ }
@@ -0,0 +1,240 @@
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
+
24
+ #include "chipmunk_private.h"
25
+ #include "chipmunk_unsafe.h"
26
+
27
+ cpPolyShape *
28
+ cpPolyShapeAlloc(void)
29
+ {
30
+ return (cpPolyShape *)cpcalloc(1, sizeof(cpPolyShape));
31
+ }
32
+
33
+ static void
34
+ cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)
35
+ {
36
+ cpVect *src = poly->verts;
37
+ cpVect *dst = poly->tVerts;
38
+
39
+ for(int i=0; i<poly->numVerts; i++)
40
+ dst[i] = cpvadd(p, cpvrotate(src[i], rot));
41
+ }
42
+
43
+ static void
44
+ cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)
45
+ {
46
+ cpPolyShapeAxis *src = poly->axes;
47
+ cpPolyShapeAxis *dst = poly->tAxes;
48
+
49
+ for(int i=0; i<poly->numVerts; i++){
50
+ cpVect n = cpvrotate(src[i].n, rot);
51
+ dst[i].n = n;
52
+ dst[i].d = cpvdot(p, n) + src[i].d;
53
+ }
54
+ }
55
+
56
+ static cpBB
57
+ cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
58
+ {
59
+ cpPolyShape *poly = (cpPolyShape *)shape;
60
+
61
+ cpFloat l, b, r, t;
62
+
63
+ cpPolyShapeTransformAxes(poly, p, rot);
64
+ cpPolyShapeTransformVerts(poly, p, rot);
65
+
66
+ cpVect *verts = poly->tVerts;
67
+ l = r = verts[0].x;
68
+ b = t = verts[0].y;
69
+
70
+ // TODO do as part of cpPolyShapeTransformVerts?
71
+ for(int i=1; i<poly->numVerts; i++){
72
+ cpVect v = verts[i];
73
+
74
+ l = cpfmin(l, v.x);
75
+ r = cpfmax(r, v.x);
76
+
77
+ b = cpfmin(b, v.y);
78
+ t = cpfmax(t, v.y);
79
+ }
80
+
81
+ return cpBBNew(l, b, r, t);
82
+ }
83
+
84
+ static void
85
+ cpPolyShapeDestroy(cpShape *shape)
86
+ {
87
+ cpPolyShape *poly = (cpPolyShape *)shape;
88
+
89
+ cpfree(poly->verts);
90
+ cpfree(poly->tVerts);
91
+
92
+ cpfree(poly->axes);
93
+ cpfree(poly->tAxes);
94
+ }
95
+
96
+ static cpBool
97
+ cpPolyShapePointQuery(cpShape *shape, cpVect p){
98
+ return cpBBcontainsVect(shape->bb, p) && cpPolyShapeContainsVert((cpPolyShape *)shape, p);
99
+ }
100
+
101
+ static void
102
+ cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)
103
+ {
104
+ cpPolyShape *poly = (cpPolyShape *)shape;
105
+ cpPolyShapeAxis *axes = poly->tAxes;
106
+ cpVect *verts = poly->tVerts;
107
+ int numVerts = poly->numVerts;
108
+
109
+ for(int i=0; i<numVerts; i++){
110
+ cpVect n = axes[i].n;
111
+ cpFloat an = cpvdot(a, n);
112
+ if(axes[i].d > an) continue;
113
+
114
+ cpFloat bn = cpvdot(b, n);
115
+ cpFloat t = (axes[i].d - an)/(bn - an);
116
+ if(t < 0.0f || 1.0f < t) continue;
117
+
118
+ cpVect point = cpvlerp(a, b, t);
119
+ cpFloat dt = -cpvcross(n, point);
120
+ cpFloat dtMin = -cpvcross(n, verts[i]);
121
+ cpFloat dtMax = -cpvcross(n, verts[(i+1)%numVerts]);
122
+
123
+ if(dtMin <= dt && dt <= dtMax){
124
+ info->shape = shape;
125
+ info->t = t;
126
+ info->n = n;
127
+ }
128
+ }
129
+ }
130
+
131
+ static const cpShapeClass polyClass = {
132
+ CP_POLY_SHAPE,
133
+ cpPolyShapeCacheData,
134
+ cpPolyShapeDestroy,
135
+ cpPolyShapePointQuery,
136
+ cpPolyShapeSegmentQuery,
137
+ };
138
+
139
+ cpBool
140
+ cpPolyValidate(const cpVect *verts, const int numVerts)
141
+ {
142
+ for(int i=0; i<numVerts; i++){
143
+ cpVect a = verts[i];
144
+ cpVect b = verts[(i+1)%numVerts];
145
+ cpVect c = verts[(i+2)%numVerts];
146
+
147
+ if(cpvcross(cpvsub(b, a), cpvsub(c, b)) > 0.0f)
148
+ return cpFalse;
149
+ }
150
+
151
+ return cpTrue;
152
+ }
153
+
154
+ int
155
+ cpPolyShapeGetNumVerts(cpShape *shape)
156
+ {
157
+ cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
158
+ return ((cpPolyShape *)shape)->numVerts;
159
+ }
160
+
161
+ cpVect
162
+ cpPolyShapeGetVert(cpShape *shape, int idx)
163
+ {
164
+ cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
165
+ cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");
166
+
167
+ return ((cpPolyShape *)shape)->verts[idx];
168
+ }
169
+
170
+
171
+ static void
172
+ setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)
173
+ {
174
+ poly->numVerts = numVerts;
175
+
176
+ poly->verts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
177
+ poly->tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));
178
+ poly->axes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
179
+ poly->tAxes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));
180
+
181
+ for(int i=0; i<numVerts; i++){
182
+ cpVect a = cpvadd(offset, verts[i]);
183
+ cpVect b = cpvadd(offset, verts[(i+1)%numVerts]);
184
+ cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
185
+
186
+ poly->verts[i] = a;
187
+ poly->axes[i].n = n;
188
+ poly->axes[i].d = cpvdot(n, a);
189
+ }
190
+ }
191
+
192
+ cpPolyShape *
193
+ cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
194
+ {
195
+ // Fail if the user attempts to pass a concave poly, or a bad winding.
196
+ cpAssert(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding.");
197
+
198
+ setUpVerts(poly, numVerts, verts, offset);
199
+ cpShapeInit((cpShape *)poly, &polyClass, body);
200
+
201
+ return poly;
202
+ }
203
+
204
+ cpShape *
205
+ cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)
206
+ {
207
+ return (cpShape *)cpPolyShapeInit(cpPolyShapeAlloc(), body, numVerts, verts, offset);
208
+ }
209
+
210
+ cpPolyShape *
211
+ cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height)
212
+ {
213
+ cpFloat hw = width/2.0f;
214
+ cpFloat hh = height/2.0f;
215
+
216
+ cpVect verts[] = {
217
+ cpv(-hw,-hh),
218
+ cpv(-hw, hh),
219
+ cpv( hw, hh),
220
+ cpv( hw,-hh),
221
+ };
222
+
223
+ return cpPolyShapeInit(poly, body, 4, verts, cpvzero);
224
+ }
225
+
226
+ cpShape *
227
+ cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height)
228
+ {
229
+ return (cpShape *)cpBoxShapeInit(cpPolyShapeAlloc(), body, width, height);
230
+ }
231
+
232
+ // Unsafe API (chipmunk_unsafe.h)
233
+
234
+ void
235
+ cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset)
236
+ {
237
+ cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");
238
+ cpPolyShapeDestroy(shape);
239
+ setUpVerts((cpPolyShape *)shape, numVerts, verts, offset);
240
+ }