chipmunk 5.3.4.0 → 5.3.4.2

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 (69) hide show
  1. data/README +36 -13
  2. data/Rakefile +23 -9
  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 +221 -243
  9. data/ext/chipmunk/rb_cpConstraint.c +173 -185
  10. data/ext/chipmunk/rb_cpShape.c +353 -240
  11. data/ext/chipmunk/rb_cpSpace.c +376 -408
  12. data/ext/chipmunk/rb_cpVect.c +135 -173
  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/chipmunk.rb +19 -8
  69. metadata +85 -38
@@ -1,15 +1,15 @@
1
1
  /* Copyright (c) 2007 Scott Lembcke
2
- *
2
+ *
3
3
  * Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  * of this software and associated documentation files (the "Software"), to deal
5
5
  * in the Software without restriction, including without limitation the rights
6
6
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
7
  * copies of the Software, and to permit persons to whom the Software is
8
8
  * furnished to do so, subject to the following conditions:
9
- *
9
+ *
10
10
  * The above copyright notice and this permission notice shall be included in
11
11
  * all copies or substantial portions of the Software.
12
- *
12
+ *
13
13
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
14
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
15
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@@ -18,9 +18,10 @@
18
18
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  * SOFTWARE.
20
20
  */
21
-
21
+
22
22
  #include <stdlib.h>
23
23
  #include "chipmunk.h"
24
+ #include "chipmunk_unsafe.h"
24
25
 
25
26
  #include "ruby.h"
26
27
  #include "rb_chipmunk.h"
@@ -43,175 +44,155 @@ rb_cpSegmentQueryInfoNew(VALUE shape, VALUE t, VALUE n) {
43
44
 
44
45
 
45
46
  static VALUE
46
- rb_cpShapeGetBody(VALUE self)
47
- {
48
- return rb_ivar_get(self, id_body);
47
+ rb_cpShapeGetBody(VALUE self) {
48
+ return rb_ivar_get(self, id_body);
49
49
  }
50
50
 
51
51
  static VALUE
52
- rb_cpShapeSensorP(VALUE self)
53
- {
54
- return SHAPE(self)->sensor ? Qtrue : Qfalse;
52
+ rb_cpShapeSensorP(VALUE self) {
53
+ return SHAPE(self)->sensor ? Qtrue : Qfalse;
55
54
  }
56
55
 
57
56
  static VALUE
58
- rb_cpShapeSetSensor(VALUE self, VALUE sensor)
59
- {
60
- int sens = (NIL_P(sensor) || (!sensor)) ? 0 : 1;
61
- SHAPE(self)->sensor = sens;
57
+ rb_cpShapeSetSensor(VALUE self, VALUE sensor) {
58
+ int sens = (NIL_P(sensor) || (!sensor)) ? 0 : 1;
59
+ SHAPE(self)->sensor = sens;
62
60
  return sensor;
63
61
  }
64
62
 
65
63
  static VALUE
66
- rb_cpShapeSetBody(VALUE self, VALUE body)
67
- {
68
- SHAPE(self)->body = BODY(body);
69
- rb_ivar_set(self, id_body, body);
70
-
71
- return body;
64
+ rb_cpShapeSetBody(VALUE self, VALUE body) {
65
+ SHAPE(self)->body = BODY(body);
66
+ rb_ivar_set(self, id_body, body);
67
+
68
+ return body;
72
69
  }
73
70
 
74
71
  static VALUE
75
- rb_cpShapeGetCollType(VALUE self)
76
- {
77
- return rb_iv_get(self, "collType");
72
+ rb_cpShapeGetCollType(VALUE self) {
73
+ return rb_iv_get(self, "collType");
78
74
  }
79
75
 
80
76
  static VALUE
81
- rb_cpShapeSetCollType(VALUE self, VALUE val)
82
- {
83
- VALUE col_type = rb_obj_id(val);
84
- rb_iv_set(self, "collType", val);
85
- SHAPE(self)->collision_type = NUM2UINT(col_type);
86
-
87
- return val;
77
+ rb_cpShapeSetCollType(VALUE self, VALUE val) {
78
+ VALUE col_type = rb_obj_id(val);
79
+ rb_iv_set(self, "collType", val);
80
+ SHAPE(self)->collision_type = NUM2UINT(col_type);
81
+
82
+ return val;
88
83
  }
89
84
 
90
85
  static VALUE
91
- rb_cpShapeGetData(VALUE self)
92
- {
86
+ rb_cpShapeGetData(VALUE self) {
93
87
  return rb_iv_get(self, "data");
94
88
  }
95
89
 
96
90
  static VALUE
97
- rb_cpShapeSetData(VALUE self, VALUE val)
98
- {
91
+ rb_cpShapeSetData(VALUE self, VALUE val) {
99
92
  rb_iv_set(self, "data", val);
100
93
  return val;
101
94
  }
102
95
 
103
96
  static VALUE
104
- rb_cpShapeGetSelf(VALUE self)
105
- {
97
+ rb_cpShapeGetSelf(VALUE self) {
106
98
  return self;
107
99
  }
108
100
 
109
101
 
110
102
  static VALUE
111
- rb_cpShapeGetGroup(VALUE self)
112
- {
113
- return rb_iv_get(self, "group");
103
+ rb_cpShapeGetGroup(VALUE self) {
104
+ return rb_iv_get(self, "group");
114
105
  }
115
106
 
116
107
  static VALUE
117
- rb_cpShapeSetGroup(VALUE self, VALUE val)
118
- {
119
- VALUE col_type = rb_obj_id(val);
120
- rb_iv_set(self, "group", val);
121
- SHAPE(self)->group = NUM2UINT(col_type);
122
-
123
- return val;
108
+ rb_cpShapeSetGroup(VALUE self, VALUE val) {
109
+ VALUE col_type = rb_obj_id(val);
110
+ rb_iv_set(self, "group", val);
111
+ SHAPE(self)->group = NUM2UINT(col_type);
112
+
113
+ return val;
124
114
  }
125
115
 
126
116
  static VALUE
127
- rb_cpShapeGetLayers(VALUE self)
128
- {
129
- return UINT2NUM(SHAPE(self)->layers);
117
+ rb_cpShapeGetLayers(VALUE self) {
118
+ return UINT2NUM(SHAPE(self)->layers);
130
119
  }
131
120
 
132
121
  static VALUE
133
- rb_cpShapeSetLayers(VALUE self, VALUE layers)
134
- {
135
- SHAPE(self)->layers = NUM2UINT(layers);
136
-
137
- return layers;
122
+ rb_cpShapeSetLayers(VALUE self, VALUE layers) {
123
+ SHAPE(self)->layers = NUM2UINT(layers);
124
+
125
+ return layers;
138
126
  }
139
127
 
140
128
  static VALUE
141
- rb_cpShapeGetBB(VALUE self)
142
- {
143
- cpBB *bb = malloc(sizeof(cpBB));
144
- *bb = SHAPE(self)->bb;
145
- return Data_Wrap_Struct(c_cpBB, NULL, free, bb);
129
+ rb_cpShapeGetBB(VALUE self) {
130
+ cpBB *bb = malloc(sizeof(cpBB));
131
+ *bb = SHAPE(self)->bb;
132
+ return Data_Wrap_Struct(c_cpBB, NULL, free, bb);
146
133
  }
147
134
 
148
135
  static VALUE
149
- rb_cpShapeCacheBB(VALUE self)
150
- {
151
- cpShape *shape = SHAPE(self);
152
- cpShapeCacheBB(shape);
153
-
154
- return rb_cpShapeGetBB(self);
136
+ rb_cpShapeCacheBB(VALUE self) {
137
+ cpShape *shape = SHAPE(self);
138
+ cpShapeCacheBB(shape);
139
+
140
+ return rb_cpShapeGetBB(self);
155
141
  }
156
142
 
157
143
  static VALUE
158
- rb_cpShapeGetElasticity(VALUE self)
159
- {
160
- return rb_float_new(SHAPE(self)->e);
144
+ rb_cpShapeGetElasticity(VALUE self) {
145
+ return rb_float_new(SHAPE(self)->e);
161
146
  }
162
147
 
163
148
  static VALUE
164
- rb_cpShapeGetFriction(VALUE self)
165
- {
166
- return rb_float_new(SHAPE(self)->u);
149
+ rb_cpShapeGetFriction(VALUE self) {
150
+ return rb_float_new(SHAPE(self)->u);
167
151
  }
168
152
 
169
153
  static VALUE
170
- rb_cpShapeSetElasticity(VALUE self, VALUE val)
171
- {
172
- SHAPE(self)->e = NUM2DBL(val);
173
- return val;
154
+ rb_cpShapeSetElasticity(VALUE self, VALUE val) {
155
+ SHAPE(self)->e = NUM2DBL(val);
156
+ return val;
174
157
  }
175
158
 
176
159
  static VALUE
177
- rb_cpShapeSetFriction(VALUE self, VALUE val)
178
- {
179
- SHAPE(self)->u = NUM2DBL(val);
180
- return val;
160
+ rb_cpShapeSetFriction(VALUE self, VALUE val) {
161
+ SHAPE(self)->u = NUM2DBL(val);
162
+ return val;
181
163
  }
182
164
 
183
165
  static VALUE
184
- rb_cpShapeGetSurfaceV(VALUE self)
185
- {
186
- return VWRAP(self, &SHAPE(self)->surface_v);
166
+ rb_cpShapeGetSurfaceV(VALUE self) {
167
+ return VWRAP(self, &SHAPE(self)->surface_v);
187
168
  }
188
169
 
189
170
  static VALUE
190
- rb_cpShapeSetSurfaceV(VALUE self, VALUE val)
191
- {
192
- SHAPE(self)->surface_v = *VGET(val);
193
- return val;
171
+ rb_cpShapeSetSurfaceV(VALUE self, VALUE val) {
172
+ SHAPE(self)->surface_v = *VGET(val);
173
+ return val;
194
174
  }
195
175
 
196
176
  static VALUE
197
- rb_cpShapeResetIdCounter(VALUE self)
198
- {
199
- cpResetShapeIdCounter();
200
- return Qnil;
177
+ rb_cpShapeResetIdCounter(VALUE self) {
178
+ cpResetShapeIdCounter();
179
+ return Qnil;
201
180
  }
202
181
 
203
182
  // Test if a point lies within a shape.
204
- static VALUE rb_cpShapePointQuery(VALUE self, VALUE point) {
205
- cpBool res = cpShapePointQuery(SHAPE(self), *VGET(point));
206
- return res ? Qtrue : Qfalse;
207
- }
183
+ static VALUE
184
+ rb_cpShapePointQuery(VALUE self, VALUE point) {
185
+ cpBool res = cpShapePointQuery(SHAPE(self), *VGET(point));
186
+ return res ? Qtrue : Qfalse;
187
+ }
208
188
 
209
189
 
210
- static VALUE rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
190
+ static VALUE
191
+ rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
211
192
  cpSegmentQueryInfo info;
212
193
  cpShapeSegmentQuery(SHAPE(self), *VGET(a), *VGET(b), &info);
213
- if(info.shape) {
214
- return rb_cpSegmentQueryInfoNew((VALUE)info.shape->data, rb_float_new(info.t), VNEW(info.n));
194
+ if(info.shape) {
195
+ return rb_cpSegmentQueryInfoNew((VALUE)info.shape->data, rb_float_new(info.t), VNEW(info.n));
215
196
  }
216
197
  return Qnil;
217
198
  }
@@ -219,215 +200,347 @@ static VALUE rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
219
200
 
220
201
 
221
202
  //cpCircle
203
+ static void
204
+ rb_cpCircleMark(void * data) {
205
+ cpCircleShape *circle = (cpCircleShape *) data;
206
+ }
207
+
222
208
  static VALUE
223
- rb_cpCircleAlloc(VALUE klass)
224
- {
225
- cpCircleShape *circle = cpCircleShapeAlloc();
226
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, circle);
209
+ rb_cpCircleAlloc(VALUE klass) {
210
+ cpCircleShape *circle = cpCircleShapeAlloc();
211
+ // note: in chipmunk 5.3.4, there is a bug wich will cause
212
+ // cpShapeFree to segfault if cpXXXShapeInit has not been called.
213
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, circle);
227
214
  }
228
215
 
216
+
217
+
229
218
  static VALUE
230
- rb_cpCircleInitialize(VALUE self, VALUE body, VALUE radius, VALUE offset)
231
- {
232
- cpCircleShape *circle = (cpCircleShape *)SHAPE(self);
233
-
234
- cpCircleShapeInit(circle, BODY(body), NUM2DBL(radius), *VGET(offset));
235
- circle->shape.data = (void *)self;
236
- circle->shape.collision_type = Qnil;
219
+ rb_cpCircleInitialize(int argc, VALUE * argv, VALUE self) {
220
+ VALUE body, radius, offset;
221
+ cpCircleShape *circle = NULL;
222
+ rb_scan_args(argc, argv, "21", &body, &radius, &offset);
223
+ circle = (cpCircleShape *)SHAPE(self);
237
224
 
238
- rb_ivar_set(self, id_body, body);
239
-
240
- return self;
241
- }
225
+ cpCircleShapeInit(circle, BODY(body), NUM2DBL(radius), VGET_ZERO(offset));
226
+ circle->shape.data = (void *)self;
227
+ circle->shape.collision_type = Qnil;
228
+ rb_ivar_set(self, id_body, body);
242
229
 
230
+ return self;
231
+ }
243
232
 
244
233
 
245
234
 
246
235
 
247
236
  //cpSegment
248
237
  static VALUE
249
- rb_cpSegmentAlloc(VALUE klass)
250
- {
251
- cpSegmentShape *seg = cpSegmentShapeAlloc();
252
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, seg);
238
+ rb_cpSegmentAlloc(VALUE klass) {
239
+ cpSegmentShape *seg = cpSegmentShapeAlloc();
240
+
241
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, seg);
253
242
  }
254
243
 
255
244
  static VALUE
256
- rb_cpSegmentInitialize(VALUE self, VALUE body, VALUE a, VALUE b, VALUE r)
257
- {
258
- cpSegmentShape *seg = (cpSegmentShape *)SHAPE(self);
259
-
260
- cpSegmentShapeInit(seg, BODY(body), *VGET(a), *VGET(b), NUM2DBL(r));
261
- seg->shape.data = (void *)self;
262
- seg->shape.collision_type = Qnil;
245
+ rb_cpSegmentInitialize(VALUE self, VALUE body, VALUE a, VALUE b, VALUE r) {
246
+ cpSegmentShape *seg = (cpSegmentShape *)SHAPE(self);
247
+
248
+ cpSegmentShapeInit(seg, BODY(body), *VGET(a), *VGET(b), NUM2DBL(r));
249
+ seg->shape.data = (void *)self;
250
+ seg->shape.collision_type = Qnil;
263
251
 
264
- rb_ivar_set(self, id_body, body);
265
-
266
- return self;
252
+ rb_ivar_set(self, id_body, body);
253
+
254
+ return self;
267
255
  }
268
256
 
269
257
 
270
258
 
271
259
  //cpPoly
260
+
261
+ // Syntactic macro to handle fetching the vertices from a ruby array
262
+ // to a C array.
263
+ #define RBCP_ARRAY_POINTS(ARR, NUM, VERTS) \
264
+ Check_Type(ARR, T_ARRAY); \
265
+ VALUE *__rbcp_ptr = RARRAY_PTR(ARR); \
266
+ long NUM = RARRAY_LEN(ARR); \
267
+ cpVect VERTS[NUM]; \
268
+ for(long i = 0; i < NUM; i++) \
269
+ VERTS[i] = *VGET(__rbcp_ptr[i]);
270
+
271
+
272
+ static VALUE
273
+ rb_cpPolyValidate(VALUE self, VALUE arr) {
274
+ RBCP_ARRAY_POINTS(arr, num, verts);
275
+
276
+ return CP_INT_BOOL(cpPolyValidate(verts, num));
277
+ }
278
+
279
+
272
280
  static VALUE
273
- rb_cpPolyAlloc(VALUE klass)
274
- {
275
- cpPolyShape *poly = cpPolyShapeAlloc();
276
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
281
+ rb_cpPolyAlloc(VALUE klass) {
282
+ cpPolyShape *poly = cpPolyShapeAlloc();
283
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
277
284
  }
278
285
 
279
286
  static VALUE
280
- rb_cpPolyInitialize(VALUE self, VALUE body, VALUE arr, VALUE offset)
281
- {
282
- cpPolyShape *poly = (cpPolyShape *)SHAPE(self);
283
-
284
- Check_Type(arr, T_ARRAY);
285
- int numVerts = RARRAY_LEN(arr);
286
- VALUE *ary_ptr = RARRAY_PTR(arr);
287
- cpVect verts[numVerts];
288
-
289
- for(int i=0; i<numVerts; i++)
290
- verts[i] = *VGET(ary_ptr[i]);
291
-
292
- cpPolyShapeInit(poly, BODY(body), numVerts, verts, *VGET(offset));
293
- poly->shape.data = (void *)self;
294
- poly->shape.collision_type = Qnil;
287
+ rb_cpPolyInitialize(int argc, VALUE * argv, VALUE self) {
288
+ VALUE body, arr, offset;
289
+ cpPolyShape *poly = (cpPolyShape *)SHAPE(self);
290
+
291
+ rb_scan_args(argc, argv, "21", &body, &arr, &offset);
292
+
293
+ RBCP_ARRAY_POINTS(arr, num, verts);
294
+
295
+ if(!cpPolyValidate(verts, num)) {
296
+ rb_raise(rb_eArgError, "The verts array does not from a valid polygon!");
297
+ }
298
+
299
+ cpPolyShapeInit(poly, BODY(body), num, verts, VGET_ZERO(offset));
300
+ poly->shape.data = (void *)self;
301
+ poly->shape.collision_type = Qnil;
295
302
 
296
- rb_ivar_set(self, id_body, body);
297
-
298
- return self;
303
+ rb_ivar_set(self, id_body, body);
304
+
305
+ return self;
299
306
  }
300
307
 
301
308
  // some getters
302
- static VALUE rb_cpCircleShapeGetOffset(VALUE self) {
309
+ static VALUE
310
+ rb_cpCircleShapeGetOffset(VALUE self) {
303
311
  return VNEW(cpCircleShapeGetOffset(SHAPE(self)));
304
312
  }
305
313
 
306
- static VALUE rb_cpCircleShapeGetRadius(VALUE self) {
314
+ static VALUE
315
+ rb_cpCircleShapeGetRadius(VALUE self) {
307
316
  return rb_float_new(cpCircleShapeGetRadius(SHAPE(self)));
308
317
  }
309
318
 
310
- static VALUE rb_cpSegmentShapeGetA(VALUE self) {
319
+ static VALUE
320
+ rb_cpSegmentShapeGetA(VALUE self) {
311
321
  return VNEW(cpSegmentShapeGetA(SHAPE(self)));
312
322
  }
313
323
 
314
- static VALUE rb_cpSegmentShapeGetB(VALUE self) {
324
+ static VALUE
325
+ rb_cpSegmentShapeGetB(VALUE self) {
315
326
  return VNEW(cpSegmentShapeGetB(SHAPE(self)));
316
327
  }
317
328
 
318
- static VALUE rb_cpSegmentShapeGetRadius(VALUE self) {
329
+ static VALUE
330
+ rb_cpSegmentShapeGetRadius(VALUE self) {
319
331
  return rb_float_new(cpSegmentShapeGetRadius(SHAPE(self)));
320
332
  }
321
333
 
322
- static VALUE rb_cpSegmentShapeGetNormal(VALUE self) {
334
+ static VALUE
335
+ rb_cpSegmentShapeGetNormal(VALUE self) {
323
336
  return VNEW(cpSegmentShapeGetNormal(SHAPE(self)));
324
337
  }
325
338
 
326
- static VALUE rb_cpPolyShapeGetNumVerts(VALUE self) {
339
+ static VALUE
340
+ rb_cpPolyShapeGetNumVerts(VALUE self) {
327
341
  return INT2NUM(cpPolyShapeGetNumVerts(SHAPE(self)));
328
342
  }
329
343
 
330
- static VALUE rb_cpPolyShapeGetVert(VALUE self, VALUE vindex) {
331
- cpShape *shape = SHAPE(self);
332
- int index = NUM2INT(vindex);
333
- if ((index < 0) || (index >= cpPolyShapeGetNumVerts(shape))) {
344
+ static VALUE
345
+ rb_cpPolyShapeGetVert(VALUE self, VALUE vindex) {
346
+ cpShape *shape = SHAPE(self);
347
+ int index = NUM2INT(vindex);
348
+ if ((index < 0) || (index >= cpPolyShapeGetNumVerts(shape))) {
334
349
  return Qnil;
335
- }
350
+ }
336
351
  return VNEW(cpPolyShapeGetVert(shape, index));
337
352
  }
338
353
 
354
+ /* "unsafe" API. */
355
+
356
+ static VALUE
357
+ rb_cpCircleShapeSetRadius(VALUE self, VALUE radius) {
358
+ cpCircleShapeSetRadius(SHAPE(self), NUM2DBL(radius));
359
+ return self;
360
+ }
361
+
362
+ static VALUE
363
+ rb_cpCircleShapeSetOffset(VALUE self, VALUE offset) {
364
+ cpCircleShapeSetOffset(SHAPE(self), *VGET(offset));
365
+ return self;
366
+ }
367
+
368
+ static VALUE
369
+ rb_cpSegmentShapeSetEndpoints(VALUE self, VALUE a, VALUE b) {
370
+ cpSegmentShapeSetEndpoints(SHAPE(self), *VGET(a), *VGET(b));
371
+ return self;
372
+ }
373
+
374
+ static VALUE
375
+ rb_cpSegmentShapeSetRadius(VALUE self, VALUE radius) {
376
+ cpSegmentShapeSetRadius(SHAPE(self), NUM2DBL(radius));
377
+ return self;
378
+ }
379
+
380
+
381
+ static VALUE
382
+ rb_cpPolyShapeSetVerts(VALUE self, VALUE arr, VALUE offset) {
383
+ cpShape *poly = SHAPE(self);
384
+
385
+ RBCP_ARRAY_POINTS(arr, num, verts);
386
+
387
+ if(!cpPolyValidate(verts, num)) {
388
+ rb_raise(rb_eArgError, "The verts array does not from a valid polygon!");
389
+ }
390
+
391
+ cpPolyShapeSetVerts(poly, num, verts, *VGET(offset));
392
+ return self;
393
+ }
394
+
395
+ /* extra inline functions from the headers */
396
+ // Returns the minimum distance of the polygon to the axis.
397
+ static VALUE
398
+ rb_cpPolyShapeValueOnAxis(VALUE self, VALUE n, VALUE d) {
399
+ cpPolyShape * poly = (cpPolyShape *) SHAPE(self);
400
+ return DBL2NUM(cpPolyShapeValueOnAxis(poly, *VGET(n), NUM2DBL(d)));
401
+ }
402
+
403
+ // Returns true if the polygon contains the vertex.
404
+ static VALUE
405
+ rb_cpPolyShapeContainsVert(VALUE self, VALUE v) {
406
+ cpPolyShape * poly = (cpPolyShape *) SHAPE(self);
407
+ return CP_INT_BOOL(cpPolyShapeContainsVert(poly, *VGET(v)));
408
+ }
409
+
410
+ // Same as cpPolyShapeContainsVert() but ignores faces pointing away from the normal.
411
+ static VALUE
412
+ rb_cpPolyShapeContainsVertPartial(VALUE self, VALUE v, VALUE n) {
413
+ cpPolyShape * poly = (cpPolyShape *) SHAPE(self);
414
+ return CP_INT_BOOL(cpPolyShapeContainsVertPartial(poly, *VGET(v), *VGET(n)));
415
+ }
416
+
417
+
418
+ /* collision.h */
419
+ static VALUE
420
+ rb_cpCollideShapes(VALUE self, VALUE other) {
421
+ cpContact points[CP_MAX_CONTACTS_PER_ARBITER];
422
+ int size = cpCollideShapes(SHAPE(self), SHAPE(other), points);
423
+ VALUE result = rb_ary_new();
424
+ for(int index = 0; index < size; index++) {
425
+ VALUE point = VNEW(points[index].p);
426
+ VALUE normal = VNEW(points[index].n);
427
+ VALUE dist = DBL2NUM(points[index].dist);
428
+ VALUE contact = rb_cpContactPointNew(point, normal, dist);
429
+ rb_ary_push(result, contact);
430
+ }
431
+ return result;
432
+ }
433
+
434
+
435
+
436
+
437
+
438
+
339
439
 
340
440
  void
341
- Init_cpShape(void)
342
- {
343
- id_body = rb_intern("body");
344
-
345
- m_cpShape = rb_define_module_under(m_Chipmunk, "Shape");
346
- rb_define_attr(m_cpShape, "obj", 1, 1);
347
-
348
- rb_define_method(m_cpShape, "body", rb_cpShapeGetBody, 0);
349
- rb_define_method(m_cpShape, "body=", rb_cpShapeSetBody, 1);
350
-
441
+ Init_cpShape(void) {
442
+ id_body = rb_intern("body");
443
+
444
+ m_cpShape = rb_define_module_under(m_Chipmunk, "Shape");
445
+ rb_define_attr(m_cpShape, "obj", 1, 1);
446
+
447
+ rb_define_method(m_cpShape, "body", rb_cpShapeGetBody, 0);
448
+ rb_define_method(m_cpShape, "body=", rb_cpShapeSetBody, 1);
449
+
351
450
  rb_define_method(m_cpShape, "sensor?", rb_cpShapeSensorP, 0);
352
451
  rb_define_method(m_cpShape, "sensor=", rb_cpShapeSetSensor, 1);
353
-
354
-
355
- rb_define_method(m_cpShape, "collision_type", rb_cpShapeGetCollType, 0);
356
- rb_define_method(m_cpShape, "collision_type=", rb_cpShapeSetCollType, 1);
357
-
358
- // this method only exists for Chipmunk-FFI compatibility as it seems useless
359
- // to me.
452
+
453
+
454
+ rb_define_method(m_cpShape, "collision_type", rb_cpShapeGetCollType, 0);
455
+ rb_define_method(m_cpShape, "collision_type=", rb_cpShapeSetCollType, 1);
456
+
457
+ // this method only exists for Chipmunk-FFI compatibility as it seems useless
458
+ // to me.
360
459
  rb_define_method(m_cpShape, "data", rb_cpShapeGetSelf, 0);
361
460
  // So we use this as the object setter
362
- rb_define_method(m_cpShape, "object" , rb_cpShapeGetData, 0);
461
+ rb_define_method(m_cpShape, "object", rb_cpShapeGetData, 0);
363
462
  rb_define_method(m_cpShape, "object=", rb_cpShapeSetData, 1);
364
-
365
- rb_define_method(m_cpShape, "group", rb_cpShapeGetGroup, 0);
366
- rb_define_method(m_cpShape, "group=", rb_cpShapeSetGroup, 1);
367
-
368
- rb_define_method(m_cpShape, "layers", rb_cpShapeGetLayers, 0);
369
- rb_define_method(m_cpShape, "layers=", rb_cpShapeSetLayers, 1);
370
-
371
- rb_define_method(m_cpShape, "bb" , rb_cpShapeCacheBB, 0);
372
- rb_define_method(m_cpShape, "cache_bb" , rb_cpShapeCacheBB, 0);
373
- rb_define_method(m_cpShape, "raw_bb" , rb_cpShapeGetBB, 0);
374
-
375
- rb_define_method(m_cpShape, "e", rb_cpShapeGetElasticity, 0);
376
- rb_define_method(m_cpShape, "u", rb_cpShapeGetFriction, 0);
377
-
378
- rb_define_method(m_cpShape, "e=", rb_cpShapeSetElasticity, 1);
379
- rb_define_method(m_cpShape, "u=", rb_cpShapeSetFriction, 1);
380
-
381
- rb_define_method(m_cpShape, "surface_v", rb_cpShapeGetSurfaceV, 0);
382
- rb_define_method(m_cpShape, "surface_v=", rb_cpShapeSetSurfaceV, 1);
383
-
463
+
464
+ rb_define_method(m_cpShape, "group", rb_cpShapeGetGroup, 0);
465
+ rb_define_method(m_cpShape, "group=", rb_cpShapeSetGroup, 1);
466
+
467
+ rb_define_method(m_cpShape, "layers", rb_cpShapeGetLayers, 0);
468
+ rb_define_method(m_cpShape, "layers=", rb_cpShapeSetLayers, 1);
469
+
470
+ rb_define_method(m_cpShape, "bb", rb_cpShapeCacheBB, 0);
471
+ rb_define_method(m_cpShape, "cache_bb", rb_cpShapeCacheBB, 0);
472
+ rb_define_method(m_cpShape, "raw_bb", rb_cpShapeGetBB, 0);
473
+
474
+ rb_define_method(m_cpShape, "e", rb_cpShapeGetElasticity, 0);
475
+ rb_define_method(m_cpShape, "u", rb_cpShapeGetFriction, 0);
476
+
477
+ rb_define_method(m_cpShape, "e=", rb_cpShapeSetElasticity, 1);
478
+ rb_define_method(m_cpShape, "u=", rb_cpShapeSetFriction, 1);
479
+
480
+ rb_define_method(m_cpShape, "surface_v", rb_cpShapeGetSurfaceV, 0);
481
+ rb_define_method(m_cpShape, "surface_v=", rb_cpShapeSetSurfaceV, 1);
482
+
384
483
  rb_define_method(m_cpShape, "point_query", rb_cpShapePointQuery, 1);
385
484
  rb_define_method(m_cpShape, "segment_query", rb_cpShapeSegmentQuery, 2);
386
-
387
-
388
-
389
- rb_define_singleton_method(m_cpShape, "reset_id_counter", rb_cpShapeResetIdCounter, 0);
390
-
391
-
392
- c_cpCircleShape = rb_define_class_under(m_cpShape, "Circle", rb_cObject);
393
- rb_include_module(c_cpCircleShape, m_cpShape);
394
- rb_define_alloc_func(c_cpCircleShape, rb_cpCircleAlloc);
395
- rb_define_method(c_cpCircleShape, "initialize", rb_cpCircleInitialize, 3);
396
-
397
-
398
- c_cpSegmentShape = rb_define_class_under(m_cpShape, "Segment", rb_cObject);
399
- rb_include_module(c_cpSegmentShape, m_cpShape);
400
- rb_define_alloc_func(c_cpSegmentShape, rb_cpSegmentAlloc);
401
- rb_define_method(c_cpSegmentShape, "initialize", rb_cpSegmentInitialize, 4);
402
-
403
-
404
- c_cpPolyShape = rb_define_class_under(m_cpShape, "Poly", rb_cObject);
405
- rb_include_module(c_cpPolyShape, m_cpShape);
406
- rb_define_alloc_func(c_cpPolyShape, rb_cpPolyAlloc);
407
- rb_define_method(c_cpPolyShape, "initialize", rb_cpPolyInitialize, 3);
408
-
485
+
486
+
487
+
488
+ rb_define_singleton_method(m_cpShape, "reset_id_counter", rb_cpShapeResetIdCounter, 0);
489
+
490
+
491
+ c_cpCircleShape = rb_define_class_under(m_cpShape, "Circle", rb_cObject);
492
+ rb_include_module(c_cpCircleShape, m_cpShape);
493
+ rb_define_alloc_func(c_cpCircleShape, rb_cpCircleAlloc);
494
+ rb_define_method(c_cpCircleShape, "initialize", rb_cpCircleInitialize, -1);
495
+
496
+ c_cpSegmentShape = rb_define_class_under(m_cpShape, "Segment", rb_cObject);
497
+ rb_include_module(c_cpSegmentShape, m_cpShape);
498
+ rb_define_alloc_func(c_cpSegmentShape, rb_cpSegmentAlloc);
499
+ rb_define_method(c_cpSegmentShape, "initialize", rb_cpSegmentInitialize, 4);
500
+
501
+
502
+ c_cpPolyShape = rb_define_class_under(m_cpShape, "Poly", rb_cObject);
503
+ rb_include_module(c_cpPolyShape, m_cpShape);
504
+ rb_define_alloc_func(c_cpPolyShape, rb_cpPolyAlloc);
505
+ rb_define_singleton_method(c_cpPolyShape, "valid?", rb_cpPolyValidate, 1);
506
+
507
+ rb_define_method(c_cpPolyShape, "initialize", rb_cpPolyInitialize, -1);
508
+
409
509
  rb_define_method(c_cpCircleShape, "offset", rb_cpCircleShapeGetOffset, 0);
410
510
  rb_define_method(c_cpCircleShape, "radius", rb_cpCircleShapeGetRadius, 0);
411
- rb_define_method(c_cpCircleShape, "r" , rb_cpCircleShapeGetRadius, 0);
412
-
413
- rb_define_method(c_cpSegmentShape, "a" , rb_cpSegmentShapeGetA, 0);
414
- rb_define_method(c_cpSegmentShape, "b" , rb_cpSegmentShapeGetB, 0);
415
- rb_define_method(c_cpSegmentShape, "radius" , rb_cpSegmentShapeGetRadius, 0);
416
- rb_define_method(c_cpSegmentShape, "r" , rb_cpSegmentShapeGetRadius, 0);
417
- rb_define_method(c_cpSegmentShape, "normal" , rb_cpSegmentShapeGetNormal, 0);
418
- rb_define_method(c_cpSegmentShape, "n" , rb_cpSegmentShapeGetNormal, 0);
419
-
420
- rb_define_method(c_cpPolyShape , "num_verts" , rb_cpPolyShapeGetNumVerts, 0);
421
- rb_define_method(c_cpPolyShape , "vert" , rb_cpPolyShapeGetVert, 1);
511
+ rb_define_method(c_cpCircleShape, "r", rb_cpCircleShapeGetRadius, 0);
512
+
513
+ rb_define_method(c_cpSegmentShape, "a", rb_cpSegmentShapeGetA, 0);
514
+ rb_define_method(c_cpSegmentShape, "b", rb_cpSegmentShapeGetB, 0);
515
+ rb_define_method(c_cpSegmentShape, "radius", rb_cpSegmentShapeGetRadius, 0);
516
+ rb_define_method(c_cpSegmentShape, "r", rb_cpSegmentShapeGetRadius, 0);
517
+ rb_define_method(c_cpSegmentShape, "normal", rb_cpSegmentShapeGetNormal, 0);
518
+ rb_define_method(c_cpSegmentShape, "n", rb_cpSegmentShapeGetNormal, 0);
519
+
520
+ rb_define_method(c_cpPolyShape, "num_verts", rb_cpPolyShapeGetNumVerts, 0);
521
+ rb_define_method(c_cpPolyShape, "vert", rb_cpPolyShapeGetVert, 1);
422
522
  // also include an array-ish interface
423
- rb_define_method(c_cpPolyShape , "length" , rb_cpPolyShapeGetNumVerts, 0);
424
- rb_define_method(c_cpPolyShape , "size" , rb_cpPolyShapeGetNumVerts, 0);
425
- rb_define_method(c_cpPolyShape , "[]" , rb_cpPolyShapeGetVert, 1);
426
-
523
+ rb_define_method(c_cpPolyShape, "length", rb_cpPolyShapeGetNumVerts, 0);
524
+ rb_define_method(c_cpPolyShape, "size", rb_cpPolyShapeGetNumVerts, 0);
525
+ rb_define_method(c_cpPolyShape, "[]", rb_cpPolyShapeGetVert, 1);
526
+ // Not in API yet:
527
+ rb_define_method(c_cpPolyShape, "value_on_axis", rb_cpPolyShapeValueOnAxis, 2);
528
+ rb_define_method(c_cpPolyShape, "contains?", rb_cpPolyShapeContainsVert, 1);
529
+ rb_define_method(c_cpPolyShape, "contains_partial?", rb_cpPolyShapeContainsVertPartial, 2);
530
+
427
531
  /* Use a struct for this small class. More efficient. */
428
532
  c_cpSegmentQueryInfo = rb_struct_define("SegmentQueryInfo",
429
- "shape", "t", "n", NULL);
430
- rb_define_const(m_Chipmunk, "SegmentQueryInfo", c_cpSegmentQueryInfo);
431
-
533
+ "shape", "t", "n", NULL);
534
+ rb_define_const(m_Chipmunk, "SegmentQueryInfo", c_cpSegmentQueryInfo);
535
+ /*"unsafe" API. */
536
+ rb_define_method(c_cpCircleShape, "set_radius!", rb_cpCircleShapeSetRadius, 1);
537
+ rb_define_method(c_cpCircleShape, "set_offset!", rb_cpCircleShapeSetOffset, 1);
538
+ rb_define_method(c_cpSegmentShape, "set_endpoints!", rb_cpSegmentShapeSetEndpoints, 2);
539
+ rb_define_method(c_cpSegmentShape, "set_radius!", rb_cpSegmentShapeSetRadius, 1);
540
+
541
+ rb_define_method(c_cpPolyShape, "set_verts!", rb_cpPolyShapeSetVerts, 2);
542
+
543
+ rb_define_method(m_cpShape, "collide!", rb_cpCollideShapes, 1);
544
+
432
545
  }
433
- //
546
+ //