chipmunk 5.3.4.5 → 6.1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. data/lib/chipmunk.rb +0 -194
@@ -22,6 +22,8 @@
22
22
  #include <stdlib.h>
23
23
  #include "chipmunk.h"
24
24
  #include "chipmunk_unsafe.h"
25
+ // looks like certain functions I exposed are supposed to be private?
26
+ // #include "chipmunk_private.h"
25
27
 
26
28
  #include "ruby.h"
27
29
  #include "rb_chipmunk.h"
@@ -34,6 +36,7 @@ VALUE c_cpSegmentShape;
34
36
  VALUE c_cpPolyShape;
35
37
 
36
38
  VALUE c_cpSegmentQueryInfo;
39
+ VALUE c_cpNearestPointQueryInfo;
37
40
 
38
41
  //Helper that allocates and initializes a SegmenQueryInfo struct
39
42
  VALUE
@@ -41,6 +44,11 @@ rb_cpSegmentQueryInfoNew(VALUE shape, VALUE t, VALUE n) {
41
44
  return rb_struct_new(c_cpSegmentQueryInfo, shape, t, n);
42
45
  }
43
46
 
47
+ VALUE
48
+ rb_cpNearestPointQueryInfoNew(VALUE shape, VALUE p, VALUE d) {
49
+ return rb_struct_new(c_cpNearestPointQueryInfo, shape, p, d);
50
+ }
51
+
44
52
 
45
53
 
46
54
  static VALUE
@@ -101,16 +109,15 @@ rb_cpShapeGetSelf(VALUE self) {
101
109
 
102
110
  static VALUE
103
111
  rb_cpShapeGetGroup(VALUE self) {
104
- return rb_iv_get(self, "group");
112
+ return rb_iv_get(self, "@group");
105
113
  }
106
114
 
107
115
  static VALUE
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);
116
+ rb_cpShapeSetGroup(VALUE self, VALUE groupValue) {
117
+ rb_iv_set(self, "@group", groupValue);
118
+ SHAPE(self)->group = CP_OBJ2INT(groupValue);
112
119
 
113
- return val;
120
+ return groupValue;
114
121
  }
115
122
 
116
123
  static VALUE
@@ -186,6 +193,16 @@ rb_cpShapePointQuery(VALUE self, VALUE point) {
186
193
  return res ? Qtrue : Qfalse;
187
194
  }
188
195
 
196
+ static VALUE
197
+ rb_cpShapeNearestPointQuery(VALUE self, VALUE point) {
198
+ cpNearestPointQueryInfo info;
199
+ cpShapeNearestPointQuery(SHAPE(self), *VGET(point), &info);
200
+ if(info.shape) {
201
+ return rb_cpNearestPointQueryInfoNew((VALUE)info.shape->data, VNEW(info.p), rb_float_new(info.d));
202
+ }
203
+ return Qnil;
204
+ }
205
+
189
206
 
190
207
  static VALUE
191
208
  rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
@@ -198,13 +215,6 @@ rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
198
215
  }
199
216
 
200
217
 
201
-
202
- //cpCircle
203
- static void
204
- rb_cpCircleMark(void * data) {
205
- cpCircleShape *circle = (cpCircleShape *) data;
206
- }
207
-
208
218
  static VALUE
209
219
  rb_cpCircleAlloc(VALUE klass) {
210
220
  cpCircleShape *circle = cpCircleShapeAlloc();
@@ -260,10 +270,11 @@ rb_cpSegmentInitialize(VALUE self, VALUE body, VALUE a, VALUE b, VALUE r) {
260
270
 
261
271
  // Syntactic macro to handle fetching the vertices from a ruby array
262
272
  // to a C array.
273
+ // TODO get rid of this cast by using stdint.h
263
274
  #define RBCP_ARRAY_POINTS(ARR, NUM, VERTS) \
264
275
  Check_Type(ARR, T_ARRAY); \
265
276
  VALUE *__rbcp_ptr = RARRAY_PTR(ARR); \
266
- long NUM = RARRAY_LEN(ARR); \
277
+ int NUM = (int)RARRAY_LEN(ARR); \
267
278
  cpVect VERTS[NUM]; \
268
279
  for(long i = 0; i < NUM; i++) \
269
280
  VERTS[i] = *VGET(__rbcp_ptr[i]);
@@ -283,6 +294,30 @@ rb_cpPolyAlloc(VALUE klass) {
283
294
  return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
284
295
  }
285
296
 
297
+ static VALUE
298
+ rb_cpShapeBoxInitialize(int argc, VALUE * argv, VALUE self) {
299
+ VALUE body, widthOrBB, height;
300
+ rb_scan_args(argc, argv, "21", &body, &widthOrBB, &height);
301
+
302
+ VALUE newPoly = rb_cpPolyAlloc(c_cpPolyShape);
303
+ cpPolyShape *poly = (cpPolyShape *)SHAPE(newPoly);
304
+
305
+ if(NIL_P(height)) {
306
+ // takes bb
307
+ cpBoxShapeInit2(poly, BODY(body), *BBGET(widthOrBB));
308
+ } else {
309
+ // takes w / h
310
+ cpBoxShapeInit(poly, BODY(body), NUM2DBL(widthOrBB), NUM2DBL(height));
311
+ }
312
+
313
+ poly->shape.data = (void *)self;
314
+ poly->shape.collision_type = Qnil;
315
+
316
+ rb_ivar_set(newPoly, id_body, body);
317
+
318
+ return newPoly;
319
+ }
320
+
286
321
  static VALUE
287
322
  rb_cpPolyInitialize(int argc, VALUE * argv, VALUE self) {
288
323
  VALUE body, arr, offset;
@@ -392,51 +427,6 @@ rb_cpPolyShapeSetVerts(VALUE self, VALUE arr, VALUE offset) {
392
427
  return self;
393
428
  }
394
429
 
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
-
439
-
440
430
  void
441
431
  Init_cpShape(void) {
442
432
  id_body = rb_intern("body");
@@ -454,6 +444,19 @@ Init_cpShape(void) {
454
444
  rb_define_method(m_cpShape, "collision_type", rb_cpShapeGetCollType, 0);
455
445
  rb_define_method(m_cpShape, "collision_type=", rb_cpShapeSetCollType, 1);
456
446
 
447
+ rb_define_method(m_cpShape, "bb", rb_cpShapeCacheBB, 0);
448
+ rb_define_method(m_cpShape, "cache_bb", rb_cpShapeCacheBB, 0);
449
+ rb_define_method(m_cpShape, "raw_bb", rb_cpShapeGetBB, 0);
450
+
451
+ rb_define_method(m_cpShape, "e", rb_cpShapeGetElasticity, 0);
452
+ rb_define_method(m_cpShape, "e=", rb_cpShapeSetElasticity, 1);
453
+
454
+ rb_define_method(m_cpShape, "u", rb_cpShapeGetFriction, 0);
455
+ rb_define_method(m_cpShape, "u=", rb_cpShapeSetFriction, 1);
456
+
457
+ rb_define_method(m_cpShape, "surface_v", rb_cpShapeGetSurfaceV, 0);
458
+ rb_define_method(m_cpShape, "surface_v=", rb_cpShapeSetSurfaceV, 1);
459
+
457
460
  // this method only exists for Chipmunk-FFI compatibility as it seems useless
458
461
  // to me.
459
462
  rb_define_method(m_cpShape, "data", rb_cpShapeGetSelf, 0);
@@ -461,26 +464,15 @@ Init_cpShape(void) {
461
464
  rb_define_method(m_cpShape, "object", rb_cpShapeGetData, 0);
462
465
  rb_define_method(m_cpShape, "object=", rb_cpShapeSetData, 1);
463
466
 
467
+
464
468
  rb_define_method(m_cpShape, "group", rb_cpShapeGetGroup, 0);
465
469
  rb_define_method(m_cpShape, "group=", rb_cpShapeSetGroup, 1);
466
470
 
467
471
  rb_define_method(m_cpShape, "layers", rb_cpShapeGetLayers, 0);
468
472
  rb_define_method(m_cpShape, "layers=", rb_cpShapeSetLayers, 1);
469
473
 
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
-
483
474
  rb_define_method(m_cpShape, "point_query", rb_cpShapePointQuery, 1);
475
+ rb_define_method(m_cpShape, "nearest_point_query", rb_cpShapeNearestPointQuery, 1);
484
476
  rb_define_method(m_cpShape, "segment_query", rb_cpShapeSegmentQuery, 2);
485
477
 
486
478
 
@@ -503,6 +495,7 @@ Init_cpShape(void) {
503
495
  rb_include_module(c_cpPolyShape, m_cpShape);
504
496
  rb_define_alloc_func(c_cpPolyShape, rb_cpPolyAlloc);
505
497
  rb_define_singleton_method(c_cpPolyShape, "valid?", rb_cpPolyValidate, 1);
498
+ rb_define_singleton_method(c_cpPolyShape, "box", rb_cpShapeBoxInitialize, -1);
506
499
 
507
500
  rb_define_method(c_cpPolyShape, "initialize", rb_cpPolyInitialize, -1);
508
501
 
@@ -523,15 +516,15 @@ Init_cpShape(void) {
523
516
  rb_define_method(c_cpPolyShape, "length", rb_cpPolyShapeGetNumVerts, 0);
524
517
  rb_define_method(c_cpPolyShape, "size", rb_cpPolyShapeGetNumVerts, 0);
525
518
  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
519
 
531
520
  /* Use a struct for this small class. More efficient. */
532
521
  c_cpSegmentQueryInfo = rb_struct_define("SegmentQueryInfo",
533
522
  "shape", "t", "n", NULL);
534
523
  rb_define_const(m_Chipmunk, "SegmentQueryInfo", c_cpSegmentQueryInfo);
524
+ c_cpNearestPointQueryInfo = rb_struct_define("NearestPointQueryInfo",
525
+ "shape", "p", "d", NULL);
526
+ rb_define_const(m_Chipmunk, "NearestPointQueryInfo", c_cpNearestPointQueryInfo);
527
+
535
528
  /*"unsafe" API. */
536
529
  rb_define_method(c_cpCircleShape, "set_radius!", rb_cpCircleShapeSetRadius, 1);
537
530
  rb_define_method(c_cpCircleShape, "set_offset!", rb_cpCircleShapeSetOffset, 1);
@@ -540,7 +533,5 @@ Init_cpShape(void) {
540
533
 
541
534
  rb_define_method(c_cpPolyShape, "set_verts!", rb_cpPolyShapeSetVerts, 2);
542
535
 
543
- rb_define_method(m_cpShape, "collide!", rb_cpCollideShapes, 1);
544
-
545
536
  }
546
537
  //
@@ -34,11 +34,25 @@ static ID id_separate;
34
34
 
35
35
  VALUE c_cpSpace;
36
36
 
37
+ #define SPACE_GETSET_FUNCS(member) \
38
+ static VALUE rb_cpSpace_get_ ## member(VALUE self) \
39
+ { return rb_float_new(SPACE(self)->member);} \
40
+ static VALUE rb_cpSpace_set_ ## member(VALUE self, VALUE value) \
41
+ { SPACE(self)->member = NUM2DBL(value); return value;}
42
+
43
+
44
+ SPACE_GETSET_FUNCS(collisionBias)
45
+ SPACE_GETSET_FUNCS(collisionSlop)
46
+
47
+ // TODO this needs to be uint not float
48
+ SPACE_GETSET_FUNCS(collisionPersistence)
37
49
 
38
50
  static VALUE
39
51
  rb_cpSpaceAlloc(VALUE klass) {
40
52
  cpSpace *space = cpSpaceAlloc();
41
- return Data_Wrap_Struct(klass, NULL, cpSpaceFree, space);
53
+ VALUE rbSpace = Data_Wrap_Struct(klass, NULL, cpSpaceFree, space);
54
+ space->data = (void*)rbSpace;
55
+ return rbSpace;
42
56
  }
43
57
 
44
58
  static VALUE
@@ -47,20 +61,16 @@ rb_cpSpaceInitialize(VALUE self) {
47
61
  cpSpaceInit(space);
48
62
 
49
63
  // These might as well be in one shared hash.
50
- rb_iv_set(self, "static_shapes", rb_ary_new());
51
- rb_iv_set(self, "active_shapes", rb_ary_new());
52
- rb_iv_set(self, "bodies", rb_ary_new());
53
- rb_iv_set(self, "constraints", rb_ary_new());
54
- rb_iv_set(self, "blocks", rb_hash_new());
64
+ rb_iv_set(self, "@static_shapes", rb_ary_new());
65
+ rb_iv_set(self, "@active_shapes", rb_ary_new());
66
+ rb_iv_set(self, "@bodies", rb_ary_new());
67
+ rb_iv_set(self, "@constraints", rb_ary_new());
68
+ rb_iv_set(self, "@blocks", rb_hash_new());
69
+ rb_iv_set(self, "@post_step_blocks", rb_hash_new());
55
70
 
56
71
  return self;
57
72
  }
58
73
 
59
- static VALUE
60
- SPACEWRAP(cpSpace * space) {
61
- return Data_Wrap_Struct(c_cpSpace, NULL, cpSpaceFree, space);
62
- }
63
-
64
74
  static VALUE
65
75
  rb_cpSpaceGetSleepTimeThreshold(VALUE self) {
66
76
  return INT2NUM(SPACE(self)->sleepTimeThreshold);
@@ -68,13 +78,13 @@ rb_cpSpaceGetSleepTimeThreshold(VALUE self) {
68
78
 
69
79
  static VALUE
70
80
  rb_cpSpaceSetSleepTimeThreshold(VALUE self, VALUE val) {
71
- SPACE(self)->sleepTimeThreshold = NUM2INT(val);
81
+ SPACE(self)->sleepTimeThreshold = NUM2UINT(val);
72
82
  return val;
73
83
  }
74
84
 
75
85
  static VALUE
76
86
  rb_cpSpaceGetIdleSpeedThreshold(VALUE self) {
77
- return INT2NUM(SPACE(self)->idleSpeedThreshold);
87
+ return UINT2NUM(SPACE(self)->idleSpeedThreshold);
78
88
  }
79
89
 
80
90
  static VALUE
@@ -97,27 +107,28 @@ rb_cpSpaceSetIterations(VALUE self, VALUE val) {
97
107
  }
98
108
 
99
109
  static VALUE
100
- rb_cpSpaceGetElasticIterations(VALUE self) {
101
- return INT2NUM(SPACE(self)->elasticIterations);
110
+ rb_cpSpaceGetDamping(VALUE self) {
111
+ return rb_float_new(SPACE(self)->damping);
102
112
  }
103
113
 
104
114
  static VALUE
105
- rb_cpSpaceSetElasticIterations(VALUE self, VALUE val) {
106
- SPACE(self)->elasticIterations = NUM2INT(val);
115
+ rb_cpSpaceSetDamping(VALUE self, VALUE val) {
116
+ SPACE(self)->damping = NUM2DBL(val);
107
117
  return val;
108
118
  }
109
119
 
110
120
  static VALUE
111
- rb_cpSpaceGetDamping(VALUE self) {
112
- return rb_float_new(SPACE(self)->damping);
121
+ rb_cpSpaceGetContactGraphEnabled(VALUE self) {
122
+ return CP_INT_BOOL(SPACE(self)->enableContactGraph);
113
123
  }
114
124
 
115
125
  static VALUE
116
- rb_cpSpaceSetDamping(VALUE self, VALUE val) {
117
- SPACE(self)->damping = NUM2DBL(val);
126
+ rb_cpSpaceSetContactGraphEnabled(VALUE self, VALUE val) {
127
+ SPACE(self)->enableContactGraph = CP_BOOL_INT(val);
118
128
  return val;
119
129
  }
120
130
 
131
+
121
132
  static VALUE
122
133
  rb_cpSpaceGetGravity(VALUE self) {
123
134
  return VWRAP(self, &SPACE(self)->gravity);
@@ -134,16 +145,6 @@ doNothingCallback(cpArbiter *arb, cpSpace *space, void *data) {
134
145
  return 0;
135
146
  }
136
147
 
137
- // We need this as rb_obj_method_arity is not in 1.8.7
138
- static int
139
- cp_rb_obj_method_arity(VALUE self, ID id) {
140
- VALUE metho = rb_funcall(self, rb_intern("method"), 1, ID2SYM(id));
141
- VALUE arity = rb_funcall(metho, rb_intern("arity"), 0, 0);
142
- return NUM2INT(arity);
143
- }
144
-
145
-
146
-
147
148
  // This callback function centralizes all collision callbacks.
148
149
  // it also adds flexibility by changing theway the callback is called on the
149
150
  // arity of the callback block or method. With arity0, no args are pased,
@@ -171,6 +172,7 @@ do_callback(void * data, ID method, cpArbiter *arb) {
171
172
  return CP_BOOL_INT(rb_funcall(object, method, 3, va, vb, varb));
172
173
  }
173
174
  // we never get here
175
+ return res;
174
176
  }
175
177
 
176
178
 
@@ -206,11 +208,6 @@ respondsTo(VALUE obj, ID method) {
206
208
  return RTEST(value);
207
209
  }
208
210
 
209
- static int
210
- isBlock(VALUE obj) {
211
- return respondsTo(obj, id_call);
212
- }
213
-
214
211
  static VALUE
215
212
  rb_cpSpaceAddCollisionHandler(int argc, VALUE *argv, VALUE self) {
216
213
  VALUE a, b, obj, block;
@@ -219,7 +216,7 @@ rb_cpSpaceAddCollisionHandler(int argc, VALUE *argv, VALUE self) {
219
216
 
220
217
  VALUE id_a = rb_obj_id(a);
221
218
  VALUE id_b = rb_obj_id(b);
222
- VALUE blocks = rb_iv_get(self, "blocks");
219
+ VALUE blocks = rb_iv_get(self, "@blocks");
223
220
 
224
221
  if(RTEST(obj) && RTEST(block)) {
225
222
  rb_raise(rb_eArgError, "Cannot specify both a handler object and a block.");
@@ -261,7 +258,7 @@ rb_cpSpaceRemoveCollisionHandler(VALUE self, VALUE a, VALUE b) {
261
258
  VALUE id_b = rb_obj_id(b);
262
259
  cpSpaceRemoveCollisionHandler(SPACE(self), NUM2UINT(id_a), NUM2UINT(id_b));
263
260
 
264
- VALUE blocks = rb_iv_get(self, "blocks");
261
+ VALUE blocks = rb_iv_get(self, "@blocks");
265
262
  rb_hash_delete(blocks, rb_ary_new3(2, id_a, id_b));
266
263
 
267
264
  return Qnil;
@@ -284,7 +281,7 @@ rb_cpSpaceSetDefaultCollisionHandler(int argc, VALUE *argv, VALUE self) {
284
281
  (void *)block
285
282
  );
286
283
 
287
- rb_hash_aset(rb_iv_get(self, "blocks"), ID2SYM(rb_intern("default")), block);
284
+ rb_hash_aset(rb_iv_get(self, "@blocks"), ID2SYM(rb_intern("default")), block);
288
285
  } else if(RTEST(obj)) {
289
286
  cpSpaceSetDefaultCollisionHandler(
290
287
  SPACE(self),
@@ -295,7 +292,7 @@ rb_cpSpaceSetDefaultCollisionHandler(int argc, VALUE *argv, VALUE self) {
295
292
  (void *)obj
296
293
  );
297
294
 
298
- rb_hash_aset(rb_iv_get(self, "blocks"), ID2SYM(rb_intern("default")), obj);
295
+ rb_hash_aset(rb_iv_get(self, "@blocks"), ID2SYM(rb_intern("default")), obj);
299
296
  } else {
300
297
  cpSpaceSetDefaultCollisionHandler(
301
298
  SPACE(self), NULL, doNothingCallback, NULL, NULL, NULL
@@ -307,96 +304,114 @@ rb_cpSpaceSetDefaultCollisionHandler(int argc, VALUE *argv, VALUE self) {
307
304
 
308
305
  static void
309
306
  poststepCallback(cpSpace *space, void *obj, void *data) {
310
- rb_funcall((VALUE)data, id_call, 2, SPACEWRAP(space), (VALUE)obj);
307
+ rb_funcall((VALUE)data, id_call, 2, (VALUE)space->data, (VALUE)obj);
311
308
  }
312
309
 
313
310
 
314
311
  static VALUE
315
312
  rb_cpSpaceAddPostStepCallback(int argc, VALUE *argv, VALUE self) {
316
313
  VALUE obj, block;
314
+ VALUE blocks = rb_iv_get(self, "@post_step_blocks");
315
+
317
316
  rb_scan_args(argc, argv, "10&", &obj, &block);
317
+ if(!RTEST(block)) {
318
+ rb_raise(rb_eArgError, "Cannot omit the block.");
319
+ }
320
+
321
+ rb_hash_aset(blocks, obj, block);
322
+
318
323
  cpSpaceAddPostStepCallback(SPACE(self),
319
324
  poststepCallback, (void *) obj, (void *) block);
325
+
320
326
  return self;
321
327
  }
322
328
 
323
329
  static VALUE
324
330
  rb_cpSpaceAddShape(VALUE self, VALUE shape) {
325
331
  cpSpaceAddShape(SPACE(self), SHAPE(shape));
326
- rb_ary_push(rb_iv_get(self, "active_shapes"), shape);
332
+ rb_ary_push(rb_iv_get(self, "@active_shapes"), shape);
327
333
  return shape;
328
334
  }
329
335
 
330
336
  static VALUE
331
337
  rb_cpSpaceAddStaticShape(VALUE self, VALUE shape) {
332
338
  cpSpaceAddStaticShape(SPACE(self), SHAPE(shape));
333
- rb_ary_push(rb_iv_get(self, "static_shapes"), shape);
339
+ rb_ary_push(rb_iv_get(self, "@static_shapes"), shape);
334
340
  return shape;
335
341
  }
336
342
 
337
343
  static VALUE
338
344
  rb_cpSpaceAddBody(VALUE self, VALUE body) {
339
345
  cpSpaceAddBody(SPACE(self), BODY(body));
340
- rb_ary_push(rb_iv_get(self, "bodies"), body);
346
+ rb_ary_push(rb_iv_get(self, "@bodies"), body);
341
347
  return body;
342
348
  }
343
349
 
344
350
  static VALUE
345
351
  rb_cpSpaceAddConstraint(VALUE self, VALUE constraint) {
346
352
  cpSpaceAddConstraint(SPACE(self), CONSTRAINT(constraint));
347
- rb_ary_push(rb_iv_get(self, "constraints"), constraint);
353
+ rb_ary_push(rb_iv_get(self, "@constraints"), constraint);
348
354
  return constraint;
349
355
  }
350
356
 
351
357
  static VALUE
352
358
  rb_cpSpaceRemoveShape(VALUE self, VALUE shape) {
353
- VALUE ok = rb_ary_delete(rb_iv_get(self, "active_shapes"), shape);
359
+ VALUE ok = rb_ary_delete(rb_iv_get(self, "@active_shapes"), shape);
354
360
  if(!(NIL_P(ok))) cpSpaceRemoveShape(SPACE(self), SHAPE(shape));
355
361
  return ok;
356
362
  }
357
363
 
358
364
  static VALUE
359
365
  rb_cpSpaceRemoveStaticShape(VALUE self, VALUE shape) {
360
- VALUE ok = rb_ary_delete(rb_iv_get(self, "static_shapes"), shape);
366
+ VALUE ok = rb_ary_delete(rb_iv_get(self, "@static_shapes"), shape);
361
367
  if(!(NIL_P(ok))) cpSpaceRemoveStaticShape(SPACE(self), SHAPE(shape));
362
368
  return ok;
363
369
  }
364
370
 
365
371
  static VALUE
366
372
  rb_cpSpaceRemoveBody(VALUE self, VALUE body) {
367
- VALUE ok = rb_ary_delete(rb_iv_get(self, "bodies"), body);
373
+ VALUE ok = rb_ary_delete(rb_iv_get(self, "@bodies"), body);
368
374
  if(!(NIL_P(ok))) cpSpaceRemoveBody(SPACE(self), BODY(body));
369
375
  return ok;
370
376
  }
371
377
 
372
378
  static VALUE
373
379
  rb_cpSpaceRemoveConstraint(VALUE self, VALUE constraint) {
374
- VALUE ok = rb_ary_delete(rb_iv_get(self, "constraints"), constraint);
380
+ VALUE ok = rb_ary_delete(rb_iv_get(self, "@constraints"), constraint);
375
381
  if(!(NIL_P(ok))) cpSpaceRemoveConstraint(SPACE(self), CONSTRAINT(constraint));
376
382
  return ok;
377
383
  }
378
384
 
379
385
  static VALUE
380
386
  rb_cpSpaceResizeStaticHash(VALUE self, VALUE dim, VALUE count) {
387
+ rb_raise(rb_eArgError, "resize_static_hash is obsolete");
388
+ return Qnil;
389
+ /*
381
390
  cpSpaceResizeStaticHash(SPACE(self), NUM2DBL(dim), NUM2INT(count));
382
391
  return Qnil;
392
+ */
383
393
  }
384
394
 
385
395
  static VALUE
386
396
  rb_cpSpaceResizeActiveHash(VALUE self, VALUE dim, VALUE count) {
387
- cpSpaceResizeActiveHash(SPACE(self), NUM2DBL(dim), NUM2INT(count));
397
+ rb_raise(rb_eArgError, "resize_active_hash is obsolete");
388
398
  return Qnil;
399
+ /* cpSpaceResizeActiveHash(SPACE(self), NUM2DBL(dim), NUM2INT(count));
400
+ return Qnil;
401
+ */
389
402
  }
390
403
 
391
404
  static VALUE
392
405
  rb_cpSpaceRehashStatic(VALUE self) {
393
- cpSpaceRehashStatic(SPACE(self));
406
+ rb_raise(rb_eArgError, "rehash_static is obsolete");
407
+ /* cpSpaceRehashStatic(SPACE(self)); */
394
408
  return Qnil;
395
409
  }
396
410
 
397
411
  static VALUE
398
412
  rb_cpSpaceRehashShape(VALUE self, VALUE shape) {
399
- cpSpaceRehashShape(SPACE(self), SHAPE(shape));
413
+ rb_raise(rb_eArgError, "rehash_shape is obsolete");
414
+ /* cpSpaceRehashShape(SPACE(self), SHAPE(shape)); */
400
415
  return Qnil;
401
416
  }
402
417
 
@@ -528,21 +543,10 @@ rb_cpSpaceShapeQuery(int argc, VALUE *argv, VALUE self) {
528
543
  static VALUE
529
544
  rb_cpSpaceStep(VALUE self, VALUE dt) {
530
545
  cpSpaceStep(SPACE(self), NUM2DBL(dt));
546
+ rb_iv_set(self, "@post_step_blocks", rb_hash_new());
531
547
  return Qnil;
532
548
  }
533
549
 
534
- static VALUE
535
- rb_cpSpaceGetData(VALUE self) {
536
- return rb_iv_get(self, "data");
537
- }
538
-
539
- static VALUE
540
- rb_cpSpaceSetData(VALUE self, VALUE val) {
541
- rb_iv_set(self, "data", val);
542
- return val;
543
- }
544
-
545
-
546
550
  static VALUE
547
551
  rb_cpSpaceActivateShapesTouchingShape(VALUE self, VALUE shape) {
548
552
  cpSpaceActivateShapesTouchingShape(SPACE(self), SHAPE(shape));
@@ -575,12 +579,6 @@ Init_cpSpace(void) {
575
579
  rb_define_method(c_cpSpace, "iterations", rb_cpSpaceGetIterations, 0);
576
580
  rb_define_method(c_cpSpace, "iterations=", rb_cpSpaceSetIterations, 1);
577
581
 
578
- rb_define_method(c_cpSpace, "elastic_iterations", rb_cpSpaceGetElasticIterations, 0);
579
- rb_define_method(c_cpSpace, "elastic_iterations=", rb_cpSpaceSetElasticIterations, 1);
580
-
581
- rb_define_method(c_cpSpace, "damping", rb_cpSpaceGetDamping, 0);
582
- rb_define_method(c_cpSpace, "damping=", rb_cpSpaceSetDamping, 1);
583
-
584
582
  rb_define_method(c_cpSpace, "gravity", rb_cpSpaceGetGravity, 0);
585
583
  rb_define_method(c_cpSpace, "gravity=", rb_cpSpaceSetGravity, 1);
586
584
 
@@ -613,9 +611,13 @@ Init_cpSpace(void) {
613
611
  rb_define_method(c_cpSpace, "on_post_step",
614
612
  rb_cpSpaceAddPostStepCallback, -1);
615
613
 
616
-
617
-
618
-
614
+ rb_define_method(c_cpSpace, "collision_bias", rb_cpSpace_get_collisionBias, 0);
615
+ rb_define_method(c_cpSpace, "collision_bias=", rb_cpSpace_set_collisionBias, 1);
616
+ rb_define_method(c_cpSpace, "collision_slop", rb_cpSpace_get_collisionSlop, 0);
617
+ rb_define_method(c_cpSpace, "collision_slop=", rb_cpSpace_set_collisionSlop, 1);
618
+ rb_define_method(c_cpSpace, "collision_persistence", rb_cpSpace_get_collisionPersistence, 0);
619
+ rb_define_method(c_cpSpace, "collision_persistence=", rb_cpSpace_set_collisionPersistence, 1);
620
+
619
621
  rb_define_method(c_cpSpace, "add_shape", rb_cpSpaceAddShape, 1);
620
622
  rb_define_method(c_cpSpace, "add_static_shape", rb_cpSpaceAddStaticShape, 1);
621
623
  rb_define_method(c_cpSpace, "add_body", rb_cpSpaceAddBody, 1);
@@ -645,9 +647,6 @@ Init_cpSpace(void) {
645
647
 
646
648
  rb_define_method(c_cpSpace, "step", rb_cpSpaceStep, 1);
647
649
 
648
- rb_define_method(c_cpSpace, "object", rb_cpSpaceGetData, 0);
649
- rb_define_method(c_cpSpace, "object=", rb_cpSpaceSetData, 1);
650
-
651
650
  rb_define_method(c_cpSpace, "sleep_time_threshold=",
652
651
  rb_cpSpaceSetSleepTimeThreshold, 1);
653
652
  rb_define_method(c_cpSpace, "sleep_time_threshold",
@@ -667,6 +666,12 @@ Init_cpSpace(void) {
667
666
  rb_define_method(c_cpSpace, "idle_speed",
668
667
  rb_cpSpaceGetIdleSpeedThreshold, 0);
669
668
 
669
+ rb_define_method(c_cpSpace, "damping", rb_cpSpaceGetDamping, 0);
670
+ rb_define_method(c_cpSpace, "damping=", rb_cpSpaceSetDamping, 1);
671
+
672
+ rb_define_method(c_cpSpace, "contact_graph_enabled", rb_cpSpaceGetContactGraphEnabled, 0);
673
+ rb_define_method(c_cpSpace, "contact_graph_enabled=", rb_cpSpaceSetContactGraphEnabled, 1);
674
+
670
675
  rb_define_method(c_cpSpace, "activate_shapes_touching_shape",
671
676
  rb_cpSpaceActivateShapesTouchingShape, 1);
672
677