chipmunk 5.3.4.0 → 5.3.4.2

Sign up to get free protection for your applications and to get access to all the features.
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,7 +18,7 @@
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
  extern VALUE m_Chipmunk;
23
23
 
24
24
  extern VALUE c_cpVect;
@@ -37,39 +37,37 @@ extern VALUE c_cpSegmentQueryInfo;
37
37
  extern ID id_parent;
38
38
 
39
39
  static inline VALUE
40
- VNEW(cpVect v)
41
- {
42
- cpVect *ptr = malloc(sizeof(cpVect));
43
- *ptr = v;
44
- return Data_Wrap_Struct(c_cpVect, NULL, free, ptr);
40
+ VNEW(cpVect v) {
41
+ cpVect *ptr = malloc(sizeof(cpVect));
42
+ *ptr = v;
43
+ return Data_Wrap_Struct(c_cpVect, NULL, free, ptr);
45
44
  }
46
45
 
47
46
  static inline VALUE
48
- VWRAP(VALUE parent, cpVect *v)
49
- {
50
- VALUE vec_obj = Data_Wrap_Struct(c_cpVect, NULL, NULL, v);
51
- rb_ivar_set(vec_obj, id_parent, parent);
52
-
53
- return vec_obj;
47
+ VWRAP(VALUE parent, cpVect *v) {
48
+ VALUE vec_obj = Data_Wrap_Struct(c_cpVect, NULL, NULL, v);
49
+ rb_ivar_set(vec_obj, id_parent, parent);
50
+
51
+ return vec_obj;
54
52
  }
55
53
 
56
- #define GETTER_TEMPLATE(func_name, klass, type)\
57
- static inline type *\
58
- func_name(VALUE self)\
59
- {\
60
- if(!rb_obj_is_kind_of(self, klass)){\
61
- VALUE klass_name = rb_funcall(klass, rb_intern("to_s"), 0);\
62
- rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", rb_obj_classname(self), StringValuePtr(klass_name));\
63
- }\
64
- type *ptr;\
65
- Data_Get_Struct(self, type, ptr);\
66
- return ptr;\
67
- }\
68
-
69
- GETTER_TEMPLATE(VGET , c_cpVect , cpVect )
70
- GETTER_TEMPLATE(BBGET, c_cpBB , cpBB )
71
- GETTER_TEMPLATE(BODY , c_cpBody , cpBody )
72
- GETTER_TEMPLATE(STATICBODY , c_cpStaticBody , cpBody)
54
+ #define GETTER_TEMPLATE(func_name, klass, type) \
55
+ static inline type * \
56
+ func_name(VALUE self) \
57
+ { \
58
+ if(!rb_obj_is_kind_of(self, klass)) { \
59
+ VALUE klass_name = rb_funcall(klass, rb_intern("to_s"), 0); \
60
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", rb_obj_classname(self), StringValuePtr(klass_name)); \
61
+ } \
62
+ type *ptr = NULL; \
63
+ Data_Get_Struct(self, type, ptr); \
64
+ return ptr; \
65
+ } \
66
+
67
+ GETTER_TEMPLATE(VGET, c_cpVect, cpVect )
68
+ GETTER_TEMPLATE(BBGET, c_cpBB, cpBB )
69
+ GETTER_TEMPLATE(BODY, c_cpBody, cpBody )
70
+ GETTER_TEMPLATE(STATICBODY, c_cpStaticBody, cpBody)
73
71
  GETTER_TEMPLATE(SHAPE, m_cpShape, cpShape)
74
72
  GETTER_TEMPLATE(CONSTRAINT, m_cpConstraint, cpConstraint)
75
73
  GETTER_TEMPLATE(SPACE, c_cpSpace, cpSpace)
@@ -79,9 +77,21 @@ GETTER_TEMPLATE(ARBITER, c_cpArbiter, cpArbiter)
79
77
  // Helper to wrap cpArbter objects.
80
78
  VALUE ARBWRAP(cpArbiter *arb);
81
79
 
80
+ // Like vget, but returns a zero vector if value is nil, and
81
+ // it also does not need to be dereferenced.
82
+ static inline cpVect
83
+ VGET_ZERO(VALUE value) {
84
+ if(NIL_P(value)) return cpvzero;
85
+ return *VGET(value);
86
+ }
87
+
82
88
  //Helper that allocates and initializes a SegmenQueryInfo struct
83
89
  VALUE rb_cpSegmentQueryInfoNew(VALUE shape, VALUE t, VALUE n);
84
90
 
91
+ // Helper that allocates and initializes a ContactPoint struct.
92
+ VALUE rb_cpContactPointNew(VALUE point, VALUE normal, VALUE dist);
93
+
94
+
85
95
  void Init_chipmunk(void);
86
96
  void Init_cpVect();
87
97
  void Init_cpBB();
@@ -95,9 +105,9 @@ void Init_cpArbiter(void);
95
105
  #define CP_BOOL_INT(VAL) (((VAL) == Qnil) || ((VAL) == Qfalse) ? 0 : 1)
96
106
 
97
107
  // transforms a C value (pointer or int) to Qtrue of Qfalse
98
- // For consistency with RBH_BOOL_INT.
108
+ // For consistency with CP_BOOL_INT.
99
109
  #define CP_INT_BOOL(VAL) ((VAL) ? Qtrue : Qfalse)
100
-
110
+
101
111
 
102
112
 
103
113
 
@@ -1,15 +1,15 @@
1
1
  /* Copyright (c) 2010 Beoran (beoran@rubyforge.org)
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
@@ -28,65 +28,64 @@
28
28
  VALUE c_cpArbiter;
29
29
 
30
30
  /*
31
- * I quote the C docs on cpArbiter:
32
- * Memory Management
33
- * You should never need to create an arbiter, nor will you ever need to free
34
- * one as they are handled by the space. More importantly, because they are
35
- * handled by the space you should never hold onto a reference to an arbiter as
36
- * you don't know when they will be destroyed. Use them within the callback
37
- * where they are given to you and then forget about them or copy out the
38
- * information you need from them.
39
- *
40
- * This means that Arbiter doesn't need an initialize, and also
41
- * does NOT need any garbage collection.
42
- */
43
-
44
- VALUE ARBWRAP(cpArbiter *arb)
45
- {
31
+ * I quote the C docs on cpArbiter:
32
+ * Memory Management
33
+ * You should never need to create an arbiter, nor will you ever need to free
34
+ * one as they are handled by the space. More importantly, because they are
35
+ * handled by the space you should never hold onto a reference to an arbiter as
36
+ * you don't know when they will be destroyed. Use them within the callback
37
+ * where they are given to you and then forget about them or copy out the
38
+ * information you need from them.
39
+ *
40
+ * This means that Arbiter doesn't need an initialize, and also
41
+ * does NOT need any garbage collection.
42
+ */
43
+
44
+ VALUE
45
+ ARBWRAP(cpArbiter *arb) {
46
46
  return Data_Wrap_Struct(c_cpArbiter, NULL, NULL, arb);
47
47
  }
48
48
 
49
49
 
50
50
  /*
51
- static VALUE
52
- rb_cpArbiterAlloc(VALUE klass)
53
- {
54
- cpArbiter *arb = cpArbiterAlloc();
55
- return Data_Wrap_Struct(klass, NULL, cpArbiterFree, arb);
56
- }
57
-
58
-
59
- static VALUE
60
- rb_cpArbiterInitialize(VALUE self, VALUE a, VALUE b, VALUE r, VALUE t)
61
- {
62
- cpArbiter *arb = ARBITER(self);
63
- cpShape *sa = SHAPE(a);
64
- cpShape *sb = SHAPE(b);
65
- cpArbiterInit(arb, sa, sb);
66
- return self;
67
- }
68
- */
51
+ static VALUE
52
+ rb_cpArbiterAlloc(VALUE klass)
53
+ {
54
+ cpArbiter *arb = cpArbiterAlloc();
55
+ return Data_Wrap_Struct(klass, NULL, cpArbiterFree, arb);
56
+ }
57
+
58
+
59
+ static VALUE
60
+ rb_cpArbiterInitialize(VALUE self, VALUE a, VALUE b, VALUE r, VALUE t)
61
+ {
62
+ cpArbiter *arb = ARBITER(self);
63
+ cpShape *sa = SHAPE(a);
64
+ cpShape *sb = SHAPE(b);
65
+ cpArbiterInit(arb, sa, sb);
66
+ return self;
67
+ }
68
+ */
69
69
 
70
70
  static VALUE
71
71
  rb_cpArbiterTotalImpulse(VALUE self) {
72
- cpArbiter *arb = ARBITER(self);
72
+ cpArbiter *arb = ARBITER(self);
73
73
  return VNEW(cpArbiterTotalImpulse(arb));
74
74
  }
75
75
 
76
76
  static VALUE
77
77
  rb_cpArbiterTotalImpulseWithFriction(VALUE self) {
78
- cpArbiter *arb = ARBITER(self);
78
+ cpArbiter *arb = ARBITER(self);
79
79
  return VNEW(cpArbiterTotalImpulseWithFriction(arb));
80
80
  }
81
81
 
82
82
  static VALUE
83
- rb_cpArbiterGetImpulse(int argc, VALUE *argv, VALUE self)
84
- {
83
+ rb_cpArbiterGetImpulse(int argc, VALUE *argv, VALUE self) {
85
84
  VALUE friction = Qnil;
86
85
  rb_scan_args(argc, argv, "01", &friction);
87
86
  if (NIL_P(friction) || friction == Qnil) {
88
87
  return rb_cpArbiterTotalImpulse(self);
89
- }
88
+ }
90
89
  /* Here, it's with friction */
91
90
  return rb_cpArbiterTotalImpulseWithFriction(self);
92
91
  }
@@ -102,66 +101,75 @@ rb_cpArbiterIgnore(VALUE self) {
102
101
  static VALUE
103
102
  rb_cpArbiterGetShapes(VALUE self) {
104
103
  cpArbiter *arb = ARBITER(self);
105
- CP_ARBITER_GET_SHAPES(arb, a, b)
104
+ CP_ARBITER_GET_SHAPES(arb, a, b)
105
+ return rb_ary_new3(2, (VALUE)a->data, (VALUE)b->data);
106
+ }
107
+
108
+ static VALUE
109
+ rb_cpArbiterGetBodies(VALUE self) {
110
+ cpArbiter *arb = ARBITER(self);
111
+ CP_ARBITER_GET_BODIES(arb, a, b)
106
112
  return rb_ary_new3(2, (VALUE)a->data, (VALUE)b->data);
107
113
  }
108
114
 
115
+
109
116
  static VALUE
110
117
  rb_cpArbiterGetA(VALUE self) {
111
118
  cpArbiter *arb = ARBITER(self);
112
- CP_ARBITER_GET_SHAPES(arb, a, b)
119
+ CP_ARBITER_GET_SHAPES(arb, a, b)
113
120
  return (VALUE)a->data;
114
121
  }
115
122
 
116
123
  static VALUE
117
124
  rb_cpArbiterGetB(VALUE self) {
118
125
  cpArbiter *arb = ARBITER(self);
119
- CP_ARBITER_GET_SHAPES(arb, a, b)
126
+ CP_ARBITER_GET_SHAPES(arb, a, b)
120
127
  return (VALUE)b->data;
121
128
  }
122
129
 
123
- static VALUE
130
+ static VALUE
124
131
  rb_cpArbiterGetE(VALUE self) {
125
132
  return rb_float_new(ARBITER(self)->e);
126
- }
127
-
128
- static VALUE
133
+ }
134
+
135
+ static VALUE
129
136
  rb_cpArbiterSetE(VALUE self, VALUE e) {
130
137
  ARBITER(self)->e = NUM2DBL(e);
131
138
  return e;
132
- }
139
+ }
133
140
 
134
- static VALUE
141
+ static VALUE
135
142
  rb_cpArbiterGetCount(VALUE self) {
136
143
  return INT2NUM(cpArbiterGetCount(ARBITER(self)));
137
- }
138
-
139
- static VALUE
144
+ }
145
+
146
+ static VALUE
140
147
  rb_cpArbiterGetU(VALUE self) {
141
148
  return rb_float_new(ARBITER(self)->u);
142
- }
149
+ }
143
150
 
144
- static VALUE
151
+ static VALUE
145
152
  rb_cpArbiterSetU(VALUE self, VALUE u) {
146
153
  ARBITER(self)->u = NUM2DBL(u);
147
154
  return u;
148
- }
155
+ }
149
156
 
150
157
  static VALUE
151
158
  rb_cpArbiterIsFirstContact(VALUE self) {
152
- int bool = cpArbiterIsFirstContact(ARBITER(self));
153
- return bool ? Qtrue : Qfalse;
159
+ int b = cpArbiterIsFirstContact(ARBITER(self));
160
+ return b ? Qtrue : Qfalse;
154
161
  }
155
162
 
156
- static int arbiterBadIndex(cpArbiter *arb, int i) {
157
- return ((i<0) || (i >= cpArbiterGetCount(arb)));
158
- }
163
+ static int
164
+ arbiterBadIndex(cpArbiter *arb, int i) {
165
+ return ((i < 0) || (i >= cpArbiterGetCount(arb)));
166
+ }
159
167
 
160
168
 
161
169
  static VALUE
162
170
  rb_cpArbiterGetNormal(VALUE self, VALUE index) {
163
171
  cpArbiter *arb = ARBITER(self);
164
- int i = NUM2LONG(index);
172
+ int i = NUM2INT(index);
165
173
  if (arbiterBadIndex(arb, i)) {
166
174
  rb_raise(rb_eIndexError, "No such normal.");
167
175
  }
@@ -171,17 +179,17 @@ rb_cpArbiterGetNormal(VALUE self, VALUE index) {
171
179
  static VALUE
172
180
  rb_cpArbiterGetPoint(VALUE self, VALUE index) {
173
181
  cpArbiter *arb = ARBITER(self);
174
- int i = NUM2LONG(index);
182
+ int i = NUM2INT(index);
175
183
  if (arbiterBadIndex(arb, i)) {
176
184
  rb_raise(rb_eIndexError, "No such contact point.");
177
- }
185
+ }
178
186
  return VNEW(cpArbiterGetPoint(arb, i));
179
187
  }
180
188
 
181
189
  static VALUE
182
190
  rb_cpArbiterGetDepth(VALUE self, VALUE index) {
183
191
  cpArbiter *arb = ARBITER(self);
184
- int i = NUM2LONG(index);
192
+ int i = NUM2INT(index);
185
193
  if (arbiterBadIndex(arb, i)) {
186
194
  rb_raise(rb_eIndexError, "No such depth.");
187
195
  }
@@ -191,19 +199,17 @@ rb_cpArbiterGetDepth(VALUE self, VALUE index) {
191
199
 
192
200
 
193
201
  static VALUE
194
- rb_cpArbiterToString(VALUE self)
195
- {
202
+ rb_cpArbiterToString(VALUE self) {
196
203
  char str[256];
197
- cpArbiter *arb = ARBITER(self);
198
- sprintf(str, "#<CP::Arbiter:%p>", arb);
204
+ cpArbiter *arb = ARBITER(self);
205
+ sprintf(str, "#<CP::Arbiter:%p>", arb);
199
206
  return rb_str_new2(str);
200
207
  }
201
208
 
202
- static VALUE
203
- rb_cpArbiterEachContact(VALUE self)
204
- {
209
+ static VALUE
210
+ rb_cpArbiterEachContact(VALUE self) {
205
211
  cpArbiter *arb = ARBITER(self);
206
- int i = 0;
212
+ int i = 0;
207
213
  for( i = 0; i < cpArbiterGetCount(arb); i++) {
208
214
  VALUE index = INT2NUM(i);
209
215
  VALUE contact, normal;
@@ -211,43 +217,74 @@ rb_cpArbiterEachContact(VALUE self)
211
217
  contact = rb_cpArbiterGetPoint(self, index);
212
218
  /* Yield an array of contact and normal */
213
219
  rb_yield(rb_ary_new3(2, contact, normal));
214
- }
220
+ }
215
221
  return self;
216
222
  }
217
223
 
224
+ VALUE c_cpContactPoint;
225
+
226
+ // Helper that allocates and initializes a ContactPoint struct.
227
+ VALUE
228
+ rb_cpContactPointNew(VALUE point, VALUE normal, VALUE dist) {
229
+ return rb_struct_new(c_cpContactPoint, point, normal, dist);
230
+ }
231
+
232
+ VALUE
233
+ rb_cpArbiterGetContactPointSet(VALUE arbiter) {
234
+ cpArbiter * arb = ARBITER(arbiter);
235
+ cpContactPointSet set = cpArbiterGetContactPointSet(arb);
236
+ VALUE result = rb_ary_new();
237
+ for(int index = 0; index < set.count; index++) {
238
+ VALUE point = VNEW(set.points[index].point);
239
+ VALUE normal = VNEW(set.points[index].normal);
240
+ VALUE dist = DBL2NUM(set.points[index].dist);
241
+ VALUE contact = rb_cpContactPointNew(point, normal, dist);
242
+ rb_ary_push(result, contact);
243
+ }
244
+ return result;
245
+ }
246
+
218
247
 
219
248
 
220
249
  void
221
- Init_cpArbiter(void)
222
- {
250
+ Init_cpArbiter(void) {
223
251
  c_cpArbiter = rb_define_class_under(m_Chipmunk, "Arbiter", rb_cObject);
224
- /*
225
- rb_define_alloc_func(c_cpArbiter, rb_cpArbiterAlloc);
226
- rb_define_method(c_cpArbiter , "initialize", rb_cpArbiterInitialize, 2);
227
- */
252
+ /*
253
+ rb_define_alloc_func(c_cpArbiter, rb_cpArbiterAlloc);
254
+ rb_define_method(c_cpArbiter , "initialize", rb_cpArbiterInitialize, 2);
255
+ */
228
256
  rb_define_method(c_cpArbiter, "a", rb_cpArbiterGetA, 0);
229
- rb_define_method(c_cpArbiter, "b", rb_cpArbiterGetB, 0);
230
- rb_define_method(c_cpArbiter, "e" , rb_cpArbiterGetE, 0);
231
- rb_define_method(c_cpArbiter, "u" , rb_cpArbiterGetU, 0);
257
+ rb_define_method(c_cpArbiter, "b", rb_cpArbiterGetB, 0);
258
+ rb_define_method(c_cpArbiter, "e", rb_cpArbiterGetE, 0);
259
+ rb_define_method(c_cpArbiter, "u", rb_cpArbiterGetU, 0);
232
260
  rb_define_method(c_cpArbiter, "e=", rb_cpArbiterSetE, 1);
233
261
  rb_define_method(c_cpArbiter, "u=", rb_cpArbiterSetU, 1);
234
262
 
235
- rb_define_method(c_cpArbiter, "point" , rb_cpArbiterGetPoint , 1);
236
- rb_define_method(c_cpArbiter, "normal" , rb_cpArbiterGetNormal , 1);
237
- rb_define_method(c_cpArbiter, "normal" , rb_cpArbiterGetDepth , 1);
238
- rb_define_method(c_cpArbiter, "impulse" , rb_cpArbiterGetImpulse , -1);
239
-
263
+ rb_define_method(c_cpArbiter, "point", rb_cpArbiterGetPoint, 1);
264
+ rb_define_method(c_cpArbiter, "normal", rb_cpArbiterGetNormal, 1);
265
+ rb_define_method(c_cpArbiter, "depth" , rb_cpArbiterGetDepth, 1);
266
+ rb_define_method(c_cpArbiter, "impulse", rb_cpArbiterGetImpulse, -1);
267
+
240
268
  rb_define_method(c_cpArbiter, "to_s", rb_cpArbiterToString, 0);
241
-
269
+
242
270
  rb_define_method(c_cpArbiter, "first_contact?", rb_cpArbiterIsFirstContact, 0);
243
- rb_define_method(c_cpArbiter, "count" , rb_cpArbiterGetCount, 0);
244
- rb_define_method(c_cpArbiter, "contacts" , rb_cpArbiterGetCount, 0);
245
- rb_define_method(c_cpArbiter, "size" , rb_cpArbiterGetCount, 0);
246
- rb_define_method(c_cpArbiter, "length" , rb_cpArbiterGetCount, 0);
247
- rb_define_method(c_cpArbiter, "each_contact" , rb_cpArbiterEachContact , 0);
248
-
249
- rb_define_method(c_cpArbiter, "shapes" , rb_cpArbiterGetShapes , 0);
271
+ rb_define_method(c_cpArbiter, "count", rb_cpArbiterGetCount, 0);
272
+ rb_define_method(c_cpArbiter, "contacts", rb_cpArbiterGetCount, 0);
273
+ rb_define_method(c_cpArbiter, "size", rb_cpArbiterGetCount, 0);
274
+ rb_define_method(c_cpArbiter, "length", rb_cpArbiterGetCount, 0);
275
+ rb_define_method(c_cpArbiter, "each_contact", rb_cpArbiterEachContact, 0);
276
+
277
+ rb_define_method(c_cpArbiter, "shapes", rb_cpArbiterGetShapes, 0);
278
+ rb_define_method(c_cpArbiter, "bodies", rb_cpArbiterGetBodies, 0);
250
279
  /* Ignore is new in the 5.x API, I think. */
251
- rb_define_method(c_cpArbiter, "ignore" , rb_cpArbiterIgnore , 0);
252
-
280
+ rb_define_method(c_cpArbiter, "ignore", rb_cpArbiterIgnore, 0);
281
+ rb_define_method(c_cpArbiter, "points", rb_cpArbiterGetContactPointSet, 0);
282
+
283
+
284
+ /* Use a struct for this small class. More efficient. */
285
+ c_cpContactPoint = rb_struct_define("ContactPoint",
286
+ "point", "normal", "dist", NULL);
287
+ rb_define_const(m_Chipmunk, "ContactPoint", c_cpContactPoint);
288
+
289
+
253
290
  }