chipmunk 5.3.4.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,336 @@
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 "chipmunk.h"
24
+
25
+ #include "ruby.h"
26
+ #include "rb_chipmunk.h"
27
+
28
+ VALUE m_cpConstraint;
29
+
30
+ #define CONSTRAINT_GETSET_FUNCS(member) \
31
+ static VALUE rb_cpConstraint_get_##member(VALUE self) \
32
+ {return rb_float_new(CONSTRAINT(self)->member);} \
33
+ static VALUE rb_cpConstraint_set_##member(VALUE self, VALUE value) \
34
+ {CONSTRAINT(self)->member = NUM2DBL(value); return value;}
35
+
36
+ CONSTRAINT_GETSET_FUNCS(maxForce)
37
+ CONSTRAINT_GETSET_FUNCS(biasCoef)
38
+ CONSTRAINT_GETSET_FUNCS(maxBias)
39
+
40
+
41
+ #define MAKE_FLT_GETTER(func) \
42
+ static VALUE rb_##func(VALUE self) \
43
+ {return rb_float_new(func(CONSTRAINT(self)));}
44
+
45
+ #define MAKE_FLT_SETTER(func) \
46
+ static VALUE rb_##func(VALUE self, VALUE value) \
47
+ {func(CONSTRAINT(self), NUM2DBL(value)); return value;} \
48
+
49
+ #define MAKE_FLT_ACCESSORS(s, m) \
50
+ MAKE_FLT_GETTER(s##Get##m) \
51
+ MAKE_FLT_SETTER(s##Set##m)
52
+
53
+ #define MAKE_VEC_GETTER(func) \
54
+ static VALUE rb_##func(VALUE self) \
55
+ {return VNEW(func(CONSTRAINT(self)));}
56
+
57
+ #define MAKE_VEC_SETTER(func) \
58
+ static VALUE rb_##func(VALUE self, VALUE value) \
59
+ {func(CONSTRAINT(self), *VGET(value)); return value;} \
60
+
61
+ #define MAKE_VEC_ACCESSORS(s, m) \
62
+ MAKE_VEC_GETTER(s##Get##m) \
63
+ MAKE_VEC_SETTER(s##Set##m)
64
+
65
+
66
+ #define ALLOC_TEMPLATE(s, alloc) \
67
+ static VALUE rb_##s##_alloc(VALUE klass) \
68
+ {return Data_Wrap_Struct(klass, NULL, cpConstraintFree, alloc);}
69
+
70
+ ALLOC_TEMPLATE(cpPinJoint, cpPinJointAlloc())
71
+
72
+ static VALUE
73
+ rb_cpPinJoint_init(VALUE self, VALUE a, VALUE b, VALUE anchr1, VALUE anchr2)
74
+ {
75
+ cpPinJoint *joint = (cpPinJoint *)CONSTRAINT(self);
76
+ cpPinJointInit(joint, BODY(a), BODY(b), *VGET(anchr1), *VGET(anchr2));
77
+ rb_iv_set(self, "@body_a", a);
78
+ rb_iv_set(self, "@body_b", b);
79
+
80
+ return self;
81
+ }
82
+
83
+ MAKE_FLT_ACCESSORS(cpPinJoint, Dist)
84
+ MAKE_VEC_ACCESSORS(cpPinJoint, Anchr1)
85
+ MAKE_VEC_ACCESSORS(cpPinJoint, Anchr2)
86
+
87
+
88
+ ALLOC_TEMPLATE(cpDampedRotarySpring, cpDampedRotarySpringAlloc())
89
+
90
+ static VALUE
91
+ rb_cpDampedRotarySpring_init(VALUE self, VALUE a, VALUE b, VALUE restAngle, VALUE stiffness, VALUE damping)
92
+ {
93
+ cpDampedRotarySpring *spring = (cpDampedRotarySpring *)CONSTRAINT(self);
94
+ cpDampedRotarySpringInit(spring, BODY(a), BODY(b), NUM2DBL(restAngle), NUM2DBL(stiffness), NUM2DBL(damping));
95
+ rb_iv_set(self, "@body_a", a);
96
+ rb_iv_set(self, "@body_b", b);
97
+
98
+ return self;
99
+ }
100
+
101
+ MAKE_FLT_ACCESSORS(cpDampedRotarySpring, RestAngle);
102
+ MAKE_FLT_ACCESSORS(cpDampedRotarySpring, Stiffness);
103
+ MAKE_FLT_ACCESSORS(cpDampedRotarySpring, Damping);
104
+
105
+
106
+ ALLOC_TEMPLATE(cpDampedSpring, cpDampedSpringAlloc())
107
+
108
+ static VALUE
109
+ rb_cpDampedSpring_init(VALUE self, VALUE a, VALUE b, VALUE anchr1, VALUE anchr2, VALUE restLength, VALUE stiffness, VALUE damping)
110
+ {
111
+ cpDampedSpring *spring = (cpDampedSpring *)CONSTRAINT(self);
112
+ cpDampedSpringInit(spring, BODY(a), BODY(b), *VGET(anchr1), *VGET(anchr2), NUM2DBL(restLength), NUM2DBL(stiffness), NUM2DBL(damping));
113
+ rb_iv_set(self, "@body_a", a);
114
+ rb_iv_set(self, "@body_b", b);
115
+
116
+ return self;
117
+ }
118
+
119
+ MAKE_VEC_ACCESSORS(cpDampedSpring, Anchr1)
120
+ MAKE_VEC_ACCESSORS(cpDampedSpring, Anchr2)
121
+ MAKE_FLT_ACCESSORS(cpDampedSpring, RestLength);
122
+ MAKE_FLT_ACCESSORS(cpDampedSpring, Stiffness);
123
+ MAKE_FLT_ACCESSORS(cpDampedSpring, Damping);
124
+
125
+
126
+ ALLOC_TEMPLATE(cpGearJoint, cpGearJointAlloc())
127
+
128
+ static VALUE
129
+ rb_cpGearJoint_init(VALUE self, VALUE a, VALUE b, VALUE phase, VALUE ratio)
130
+ {
131
+ cpGearJoint *joint = (cpGearJoint *)CONSTRAINT(self);
132
+ cpGearJointInit(joint, BODY(a), BODY(b), NUM2DBL(phase), NUM2DBL(ratio));
133
+ rb_iv_set(self, "@body_a", a);
134
+ rb_iv_set(self, "@body_b", b);
135
+
136
+ return self;
137
+ }
138
+
139
+ MAKE_FLT_ACCESSORS(cpGearJoint, Phase);
140
+ MAKE_FLT_ACCESSORS(cpGearJoint, Ratio);
141
+
142
+
143
+ ALLOC_TEMPLATE(cpPivotJoint, cpPivotJointAlloc())
144
+
145
+ static VALUE
146
+ rb_cpPivotJoint_init(VALUE self, VALUE a, VALUE b, VALUE anchr1, VALUE anchr2)
147
+ {
148
+ cpPivotJoint *joint = (cpPivotJoint *)CONSTRAINT(self);
149
+ cpPivotJointInit(joint, BODY(a), BODY(b), *VGET(anchr1), *VGET(anchr2));
150
+ rb_iv_set(self, "@body_a", a);
151
+ rb_iv_set(self, "@body_b", b);
152
+
153
+ return self;
154
+ }
155
+
156
+ MAKE_VEC_ACCESSORS(cpPivotJoint, Anchr1);
157
+ MAKE_VEC_ACCESSORS(cpPivotJoint, Anchr2);
158
+
159
+
160
+ ALLOC_TEMPLATE(cpRotaryLimitJoint, cpRotaryLimitJointAlloc())
161
+
162
+ static VALUE
163
+ rb_cpRotaryLimitJoint_init(VALUE self, VALUE a, VALUE b, VALUE min, VALUE max)
164
+ {
165
+ cpRotaryLimitJoint *joint = (cpRotaryLimitJoint *)CONSTRAINT(self);
166
+ cpRotaryLimitJointInit(joint, BODY(a), BODY(b), NUM2DBL(min), NUM2DBL(max));
167
+ rb_iv_set(self, "@body_a", a);
168
+ rb_iv_set(self, "@body_b", b);
169
+
170
+ return self;
171
+ }
172
+
173
+ MAKE_FLT_ACCESSORS(cpRotaryLimitJoint, Min);
174
+ MAKE_FLT_ACCESSORS(cpRotaryLimitJoint, Max);
175
+
176
+
177
+ ALLOC_TEMPLATE(cpSimpleMotor, cpSimpleMotorAlloc())
178
+
179
+ static VALUE
180
+ rb_cpSimpleMotor_init(VALUE self, VALUE a, VALUE b, VALUE rate)
181
+ {
182
+ cpSimpleMotor *motor = (cpSimpleMotor *)CONSTRAINT(self);
183
+ cpSimpleMotorInit(motor, BODY(a), BODY(b), NUM2DBL(rate));
184
+ rb_iv_set(self, "@body_a", a);
185
+ rb_iv_set(self, "@body_b", b);
186
+
187
+ return self;
188
+ }
189
+
190
+ MAKE_FLT_ACCESSORS(cpSimpleMotor, Rate);
191
+
192
+
193
+ ALLOC_TEMPLATE(cpSlideJoint, cpSlideJointAlloc())
194
+
195
+ static VALUE
196
+ rb_cpSlideJoint_init(VALUE self, VALUE a, VALUE b, VALUE anchr1, VALUE anchr2, VALUE min, VALUE max)
197
+ {
198
+ cpSlideJoint *joint = (cpSlideJoint *)CONSTRAINT(self);
199
+ cpSlideJointInit(joint, BODY(a), BODY(b), *VGET(anchr1), *VGET(anchr2), NUM2DBL(min), NUM2DBL(max));
200
+ rb_iv_set(self, "@body_a", a);
201
+ rb_iv_set(self, "@body_b", b);
202
+
203
+ return self;
204
+ }
205
+
206
+ MAKE_VEC_ACCESSORS(cpSlideJoint, Anchr1)
207
+ MAKE_VEC_ACCESSORS(cpSlideJoint, Anchr2)
208
+ MAKE_FLT_ACCESSORS(cpSlideJoint, Min);
209
+ MAKE_FLT_ACCESSORS(cpSlideJoint, Max);
210
+
211
+
212
+ ALLOC_TEMPLATE(cpGrooveJoint, cpGrooveJointAlloc())
213
+
214
+ static VALUE
215
+ rb_cpGrooveJoint_init(VALUE self, VALUE a, VALUE b, VALUE grv_a, VALUE grv_b, VALUE anchr2)
216
+ {
217
+ cpGrooveJoint *joint = (cpGrooveJoint *)CONSTRAINT(self);
218
+ cpGrooveJointInit(joint, BODY(a), BODY(b), *VGET(grv_a), *VGET(grv_b), *VGET(anchr2));
219
+ rb_iv_set(self, "@body_a", a);
220
+ rb_iv_set(self, "@body_b", b);
221
+
222
+ return self;
223
+ }
224
+
225
+ MAKE_VEC_ACCESSORS(cpGrooveJoint, GrooveA)
226
+ MAKE_VEC_ACCESSORS(cpGrooveJoint, GrooveB)
227
+ MAKE_VEC_ACCESSORS(cpGrooveJoint, Anchr2)
228
+
229
+
230
+ ALLOC_TEMPLATE(cpRatchetJoint, cpRatchetJointAlloc())
231
+
232
+ static VALUE
233
+ rb_cpRatchetJoint_init(VALUE self, VALUE a, VALUE b, VALUE phase, VALUE ratchet)
234
+ {
235
+ cpRatchetJoint * joint = (cpRatchetJoint *)CONSTRAINT(self);
236
+ cpRatchetJointInit(joint, BODY(a), BODY(b), NUM2DBL(phase), NUM2DBL(ratchet));
237
+ rb_iv_set(self, "@body_a", a);
238
+ rb_iv_set(self, "@body_b", b);
239
+
240
+ return self;
241
+ }
242
+
243
+ MAKE_FLT_ACCESSORS(cpRatchetJoint, Angle);
244
+ MAKE_FLT_ACCESSORS(cpRatchetJoint, Phase);
245
+ MAKE_FLT_ACCESSORS(cpRatchetJoint, Ratchet);
246
+
247
+ static VALUE
248
+ rb_cpConstraintGetImpulse(VALUE self) {
249
+ return rb_float_new(cpConstraintGetImpulse(CONSTRAINT(self)));
250
+ }
251
+
252
+
253
+ #define STRINGIFY(v) #v
254
+ #define ACCESSOR_METHODS(s, m, name) \
255
+ rb_define_method(c_##s, STRINGIFY(name), rb_##s##Get##m, 0); \
256
+ rb_define_method(c_##s, STRINGIFY(name=), rb_##s##Set##m, 1);
257
+
258
+ static VALUE
259
+ make_class(const char *name, void *alloc_func, void *init_func, int init_params)
260
+ {
261
+ VALUE klass = rb_define_class_under(m_cpConstraint, name, rb_cObject);
262
+ rb_include_module(klass, m_cpConstraint);
263
+ rb_define_alloc_func(klass, alloc_func);
264
+ rb_define_method(klass, "initialize", init_func, init_params);
265
+
266
+ return klass;
267
+ }
268
+
269
+ void
270
+ Init_cpConstraint(void)
271
+ {
272
+ m_cpConstraint = rb_define_module_under(m_Chipmunk, "Constraint");
273
+ rb_define_attr(m_cpConstraint, "body_a", 1, 0);
274
+ rb_define_attr(m_cpConstraint, "body_b", 1, 0);
275
+ rb_define_method(m_cpConstraint, "max_force", rb_cpConstraint_get_maxForce, 0);
276
+ rb_define_method(m_cpConstraint, "max_force=", rb_cpConstraint_set_maxForce, 1);
277
+ rb_define_method(m_cpConstraint, "bias_coef", rb_cpConstraint_get_biasCoef, 0);
278
+ rb_define_method(m_cpConstraint, "bias_coef=", rb_cpConstraint_set_biasCoef, 1);
279
+ rb_define_method(m_cpConstraint, "max_bias", rb_cpConstraint_get_maxBias, 0);
280
+ rb_define_method(m_cpConstraint, "max_bias=" , rb_cpConstraint_set_maxBias, 1);
281
+ rb_define_method(m_cpConstraint, "impulse" , rb_cpConstraintGetImpulse, 0);
282
+
283
+
284
+ VALUE c_cpDampedRotarySpring = make_class("DampedRotarySpring", rb_cpDampedRotarySpring_alloc, rb_cpDampedRotarySpring_init, 5);
285
+ ACCESSOR_METHODS(cpDampedRotarySpring, RestAngle, rest_angle)
286
+ ACCESSOR_METHODS(cpDampedRotarySpring, Stiffness, stiffness)
287
+ ACCESSOR_METHODS(cpDampedRotarySpring, Damping, damping)
288
+
289
+ VALUE c_cpDampedSpring = make_class("DampedSpring", rb_cpDampedSpring_alloc, rb_cpDampedSpring_init, 7);
290
+ ACCESSOR_METHODS(cpDampedSpring, Anchr1, anchr1)
291
+ ACCESSOR_METHODS(cpDampedSpring, Anchr2, anchr2)
292
+ ACCESSOR_METHODS(cpDampedSpring, RestLength, rest_length)
293
+ ACCESSOR_METHODS(cpDampedSpring, Stiffness, stiffness)
294
+ ACCESSOR_METHODS(cpDampedSpring, Damping, damping)
295
+
296
+ VALUE c_cpGearJoint = make_class("GearJoint", rb_cpGearJoint_alloc, rb_cpGearJoint_init, 4);
297
+ ACCESSOR_METHODS(cpGearJoint, Phase, phase)
298
+ ACCESSOR_METHODS(cpGearJoint, Ratio, ratio)
299
+
300
+ VALUE c_cpGrooveJoint = make_class("GrooveJoint", rb_cpGrooveJoint_alloc, rb_cpGrooveJoint_init, 5);
301
+ ACCESSOR_METHODS(cpGrooveJoint, Anchr2, anchr2)
302
+
303
+
304
+ VALUE c_cpPinJoint = make_class("PinJoint", rb_cpPinJoint_alloc, rb_cpPinJoint_init, 4);
305
+ ACCESSOR_METHODS(cpPinJoint, Anchr1, anchr1)
306
+ ACCESSOR_METHODS(cpPinJoint, Anchr2, anchr2)
307
+ ACCESSOR_METHODS(cpPinJoint, Dist, dist)
308
+
309
+
310
+ VALUE c_cpPivotJoint = make_class("PivotJoint", rb_cpPivotJoint_alloc, rb_cpPivotJoint_init, 4);
311
+ ACCESSOR_METHODS(cpPivotJoint, Anchr1, anchr1)
312
+ ACCESSOR_METHODS(cpPivotJoint, Anchr2, anchr2)
313
+
314
+ VALUE c_cpRotaryLimitJoint = make_class("RotaryLimitJoint", rb_cpRotaryLimitJoint_alloc, rb_cpRotaryLimitJoint_init, 4);
315
+ ACCESSOR_METHODS(cpRotaryLimitJoint, Min, min)
316
+ ACCESSOR_METHODS(cpRotaryLimitJoint, Max, max)
317
+
318
+ VALUE c_cpSimpleMotor = make_class("SimpleMotor", rb_cpSimpleMotor_alloc, rb_cpSimpleMotor_init, 3);
319
+ ACCESSOR_METHODS(cpSimpleMotor, Rate, rate);
320
+
321
+ VALUE c_cpSlideJoint = make_class("SlideJoint", rb_cpSlideJoint_alloc, rb_cpSlideJoint_init, 6);
322
+ ACCESSOR_METHODS(cpSlideJoint, Anchr1, anchr1)
323
+ ACCESSOR_METHODS(cpSlideJoint, Anchr2, anchr2)
324
+ ACCESSOR_METHODS(cpSlideJoint, Min, min)
325
+ ACCESSOR_METHODS(cpSlideJoint, Max, max)
326
+
327
+
328
+ VALUE c_cpRatchetJoint = make_class("RatchetJoint", rb_cpRatchetJoint_alloc, rb_cpRatchetJoint_init, 4);
329
+ ACCESSOR_METHODS(cpRatchetJoint, Angle, angle)
330
+ ACCESSOR_METHODS(cpRatchetJoint, Phase, phase)
331
+ ACCESSOR_METHODS(cpRatchetJoint, Ratchet, ratchet)
332
+
333
+
334
+ // TODO: breakable joints. Seems to be missing in chipmunk 5.4.3.
335
+
336
+ }
@@ -0,0 +1,450 @@
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 "chipmunk.h"
24
+
25
+ #include "ruby.h"
26
+ #include "rb_chipmunk.h"
27
+
28
+ ID id_body;
29
+
30
+ VALUE m_cpShape;
31
+ VALUE c_cpCircleShape;
32
+ VALUE c_cpSegmentShape;
33
+ VALUE c_cpPolyShape;
34
+
35
+ VALUE c_cpSegmentQueryInfo;
36
+
37
+ //Helper that allocates and initializes a SegmenQueryInfo struct
38
+ VALUE
39
+ rb_cpSegmentQueryInfoNew(VALUE shape, VALUE t, VALUE n) {
40
+ return rb_struct_new(c_cpSegmentQueryInfo, shape, t, n);
41
+ }
42
+
43
+
44
+
45
+ static VALUE
46
+ rb_cpShapeGetBody(VALUE self)
47
+ {
48
+ return rb_ivar_get(self, id_body);
49
+ }
50
+
51
+ static VALUE
52
+ rb_cpShapeSensorP(VALUE self)
53
+ {
54
+ return SHAPE(self)->sensor ? Qtrue : Qfalse;
55
+ }
56
+
57
+ static VALUE
58
+ rb_cpShapeSetSensor(VALUE self, VALUE sensor)
59
+ {
60
+ int sens = (NIL_P(sensor) || (!sensor)) ? 0 : 1;
61
+ SHAPE(self)->sensor = sens;
62
+ return sensor;
63
+ }
64
+
65
+ 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;
72
+ }
73
+
74
+ static VALUE
75
+ rb_cpShapeGetCollType(VALUE self)
76
+ {
77
+ return rb_iv_get(self, "collType");
78
+ }
79
+
80
+ 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;
88
+ }
89
+
90
+ static VALUE
91
+ rb_cpShapeGetData(VALUE self)
92
+ {
93
+ return rb_iv_get(self, "data");
94
+ }
95
+
96
+ static VALUE
97
+ rb_cpShapeSetData(VALUE self, VALUE val)
98
+ {
99
+ rb_iv_set(self, "data", val);
100
+ return val;
101
+ }
102
+
103
+ static VALUE
104
+ rb_cpShapeGetSelf(VALUE self)
105
+ {
106
+ return self;
107
+ }
108
+
109
+
110
+ static VALUE
111
+ rb_cpShapeGetGroup(VALUE self)
112
+ {
113
+ return rb_iv_get(self, "group");
114
+ }
115
+
116
+ 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;
124
+ }
125
+
126
+ static VALUE
127
+ rb_cpShapeGetLayers(VALUE self)
128
+ {
129
+ return UINT2NUM(SHAPE(self)->layers);
130
+ }
131
+
132
+ static VALUE
133
+ rb_cpShapeSetLayers(VALUE self, VALUE layers)
134
+ {
135
+ SHAPE(self)->layers = NUM2UINT(layers);
136
+
137
+ return layers;
138
+ }
139
+
140
+ 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);
146
+ }
147
+
148
+ static VALUE
149
+ rb_cpShapeCacheBB(VALUE self)
150
+ {
151
+ cpShape *shape = SHAPE(self);
152
+ cpShapeCacheBB(shape);
153
+
154
+ return rb_cpShapeGetBB(self);
155
+ }
156
+
157
+ static VALUE
158
+ rb_cpShapeGetElasticity(VALUE self)
159
+ {
160
+ return rb_float_new(SHAPE(self)->e);
161
+ }
162
+
163
+ static VALUE
164
+ rb_cpShapeGetFriction(VALUE self)
165
+ {
166
+ return rb_float_new(SHAPE(self)->u);
167
+ }
168
+
169
+ static VALUE
170
+ rb_cpShapeSetElasticity(VALUE self, VALUE val)
171
+ {
172
+ SHAPE(self)->e = NUM2DBL(val);
173
+ return val;
174
+ }
175
+
176
+ static VALUE
177
+ rb_cpShapeSetFriction(VALUE self, VALUE val)
178
+ {
179
+ SHAPE(self)->u = NUM2DBL(val);
180
+ return val;
181
+ }
182
+
183
+ static VALUE
184
+ rb_cpShapeGetSurfaceV(VALUE self)
185
+ {
186
+ return VWRAP(self, &SHAPE(self)->surface_v);
187
+ }
188
+
189
+ static VALUE
190
+ rb_cpShapeSetSurfaceV(VALUE self, VALUE val)
191
+ {
192
+ SHAPE(self)->surface_v = *VGET(val);
193
+ return val;
194
+ }
195
+
196
+ static VALUE
197
+ rb_cpShapeResetIdCounter(VALUE self)
198
+ {
199
+ cpResetShapeIdCounter();
200
+ return Qnil;
201
+ }
202
+
203
+ // 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
+ }
208
+
209
+
210
+ static VALUE rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b) {
211
+ cpSegmentQueryInfo info;
212
+ 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));
215
+ }
216
+ return Qnil;
217
+ }
218
+
219
+
220
+
221
+ //cpCircle
222
+ static VALUE
223
+ rb_cpCircleAlloc(VALUE klass)
224
+ {
225
+ cpCircleShape *circle = cpCircleShapeAlloc();
226
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, circle);
227
+ }
228
+
229
+ 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;
237
+
238
+ rb_ivar_set(self, id_body, body);
239
+
240
+ return self;
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ //cpSegment
248
+ static VALUE
249
+ rb_cpSegmentAlloc(VALUE klass)
250
+ {
251
+ cpSegmentShape *seg = cpSegmentShapeAlloc();
252
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, seg);
253
+ }
254
+
255
+ 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;
263
+
264
+ rb_ivar_set(self, id_body, body);
265
+
266
+ return self;
267
+ }
268
+
269
+
270
+
271
+ //cpPoly
272
+ #define RBCP_ARRAY_POINTS(ARR, NUM, VERTS) \
273
+ Check_Type(ARR, T_ARRAY); \
274
+ VALUE *__rbcp_ptr = RARRAY_PTR(ARR); \
275
+ int NUM = RARRAY_LEN(ARR); \
276
+ cpVect VERTS[NUM]; \
277
+ for(int i=0; i<NUM; i++) \
278
+ VERTS[i] = *VGET(__rbcp_ptr[i]);
279
+
280
+
281
+ static VALUE rb_cpPolyValidate(VALUE arr) {
282
+ RBCP_ARRAY_POINTS(arr, num, verts)
283
+ return CP_INT_BOOL(cpPolyValidate(verts, num));
284
+ }
285
+
286
+
287
+ static VALUE
288
+ rb_cpPolyAlloc(VALUE klass)
289
+ {
290
+ cpPolyShape *poly = cpPolyShapeAlloc();
291
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
292
+ }
293
+
294
+ static VALUE
295
+ rb_cpPolyInitialize(VALUE self, VALUE body, VALUE arr, VALUE offset)
296
+ {
297
+ cpPolyShape *poly = (cpPolyShape *)SHAPE(self);
298
+
299
+ Check_Type(arr, T_ARRAY);
300
+ int numVerts = RARRAY_LEN(arr);
301
+ VALUE *ary_ptr = RARRAY_PTR(arr);
302
+ cpVect verts[numVerts];
303
+
304
+ for(int i=0; i<numVerts; i++)
305
+ verts[i] = *VGET(ary_ptr[i]);
306
+
307
+ cpPolyShapeInit(poly, BODY(body), numVerts, verts, *VGET(offset));
308
+ poly->shape.data = (void *)self;
309
+ poly->shape.collision_type = Qnil;
310
+
311
+ rb_ivar_set(self, id_body, body);
312
+
313
+ return self;
314
+ }
315
+
316
+ // some getters
317
+ static VALUE rb_cpCircleShapeGetOffset(VALUE self) {
318
+ return VNEW(cpCircleShapeGetOffset(SHAPE(self)));
319
+ }
320
+
321
+ static VALUE rb_cpCircleShapeGetRadius(VALUE self) {
322
+ return rb_float_new(cpCircleShapeGetRadius(SHAPE(self)));
323
+ }
324
+
325
+ static VALUE rb_cpSegmentShapeGetA(VALUE self) {
326
+ return VNEW(cpSegmentShapeGetA(SHAPE(self)));
327
+ }
328
+
329
+ static VALUE rb_cpSegmentShapeGetB(VALUE self) {
330
+ return VNEW(cpSegmentShapeGetB(SHAPE(self)));
331
+ }
332
+
333
+ static VALUE rb_cpSegmentShapeGetRadius(VALUE self) {
334
+ return rb_float_new(cpSegmentShapeGetRadius(SHAPE(self)));
335
+ }
336
+
337
+ static VALUE rb_cpSegmentShapeGetNormal(VALUE self) {
338
+ return VNEW(cpSegmentShapeGetNormal(SHAPE(self)));
339
+ }
340
+
341
+ static VALUE rb_cpPolyShapeGetNumVerts(VALUE self) {
342
+ return INT2NUM(cpPolyShapeGetNumVerts(SHAPE(self)));
343
+ }
344
+
345
+ static VALUE rb_cpPolyShapeGetVert(VALUE self, VALUE vindex) {
346
+ cpShape *shape = SHAPE(self);
347
+ int index = NUM2INT(vindex);
348
+ if ((index < 0) || (index >= cpPolyShapeGetNumVerts(shape))) {
349
+ return Qnil;
350
+ }
351
+ return VNEW(cpPolyShapeGetVert(shape, index));
352
+ }
353
+
354
+
355
+ void
356
+ Init_cpShape(void)
357
+ {
358
+ id_body = rb_intern("body");
359
+
360
+ m_cpShape = rb_define_module_under(m_Chipmunk, "Shape");
361
+ rb_define_attr(m_cpShape, "obj", 1, 1);
362
+
363
+ rb_define_method(m_cpShape, "body", rb_cpShapeGetBody, 0);
364
+ rb_define_method(m_cpShape, "body=", rb_cpShapeSetBody, 1);
365
+
366
+ rb_define_method(m_cpShape, "sensor?", rb_cpShapeSensorP, 0);
367
+ rb_define_method(m_cpShape, "sensor=", rb_cpShapeSetSensor, 1);
368
+
369
+
370
+ rb_define_method(m_cpShape, "collision_type", rb_cpShapeGetCollType, 0);
371
+ rb_define_method(m_cpShape, "collision_type=", rb_cpShapeSetCollType, 1);
372
+
373
+ // this method only exists for Chipmunk-FFI compatibility as it seems useless
374
+ // to me.
375
+ rb_define_method(m_cpShape, "data", rb_cpShapeGetSelf, 0);
376
+ // So we use this as the object setter
377
+ rb_define_method(m_cpShape, "object" , rb_cpShapeGetData, 0);
378
+ rb_define_method(m_cpShape, "object=", rb_cpShapeSetData, 1);
379
+
380
+ rb_define_method(m_cpShape, "group", rb_cpShapeGetGroup, 0);
381
+ rb_define_method(m_cpShape, "group=", rb_cpShapeSetGroup, 1);
382
+
383
+ rb_define_method(m_cpShape, "layers", rb_cpShapeGetLayers, 0);
384
+ rb_define_method(m_cpShape, "layers=", rb_cpShapeSetLayers, 1);
385
+
386
+ rb_define_method(m_cpShape, "bb" , rb_cpShapeCacheBB, 0);
387
+ rb_define_method(m_cpShape, "cache_bb" , rb_cpShapeCacheBB, 0);
388
+ rb_define_method(m_cpShape, "raw_bb" , rb_cpShapeGetBB, 0);
389
+
390
+ rb_define_method(m_cpShape, "e", rb_cpShapeGetElasticity, 0);
391
+ rb_define_method(m_cpShape, "u", rb_cpShapeGetFriction, 0);
392
+
393
+ rb_define_method(m_cpShape, "e=", rb_cpShapeSetElasticity, 1);
394
+ rb_define_method(m_cpShape, "u=", rb_cpShapeSetFriction, 1);
395
+
396
+ rb_define_method(m_cpShape, "surface_v", rb_cpShapeGetSurfaceV, 0);
397
+ rb_define_method(m_cpShape, "surface_v=", rb_cpShapeSetSurfaceV, 1);
398
+
399
+ rb_define_method(m_cpShape, "point_query", rb_cpShapePointQuery, 1);
400
+ rb_define_method(m_cpShape, "segment_query", rb_cpShapeSegmentQuery, 2);
401
+
402
+
403
+
404
+ rb_define_singleton_method(m_cpShape, "reset_id_counter", rb_cpShapeResetIdCounter, 0);
405
+
406
+
407
+ c_cpCircleShape = rb_define_class_under(m_cpShape, "Circle", rb_cObject);
408
+ rb_include_module(c_cpCircleShape, m_cpShape);
409
+ rb_define_alloc_func(c_cpCircleShape, rb_cpCircleAlloc);
410
+ rb_define_method(c_cpCircleShape, "initialize", rb_cpCircleInitialize, 3);
411
+
412
+
413
+ c_cpSegmentShape = rb_define_class_under(m_cpShape, "Segment", rb_cObject);
414
+ rb_include_module(c_cpSegmentShape, m_cpShape);
415
+ rb_define_alloc_func(c_cpSegmentShape, rb_cpSegmentAlloc);
416
+ rb_define_method(c_cpSegmentShape, "initialize", rb_cpSegmentInitialize, 4);
417
+
418
+
419
+ c_cpPolyShape = rb_define_class_under(m_cpShape, "Poly", rb_cObject);
420
+ rb_include_module(c_cpPolyShape, m_cpShape);
421
+ rb_define_alloc_func(c_cpPolyShape, rb_cpPolyAlloc);
422
+ rb_define_singleton_method(c_cpPolyShape, "valid?", rb_cpPolyValidate, 1);
423
+
424
+ rb_define_method(c_cpPolyShape, "initialize", rb_cpPolyInitialize, 3);
425
+
426
+ rb_define_method(c_cpCircleShape, "offset", rb_cpCircleShapeGetOffset, 0);
427
+ rb_define_method(c_cpCircleShape, "radius", rb_cpCircleShapeGetRadius, 0);
428
+ rb_define_method(c_cpCircleShape, "r" , rb_cpCircleShapeGetRadius, 0);
429
+
430
+ rb_define_method(c_cpSegmentShape, "a" , rb_cpSegmentShapeGetA, 0);
431
+ rb_define_method(c_cpSegmentShape, "b" , rb_cpSegmentShapeGetB, 0);
432
+ rb_define_method(c_cpSegmentShape, "radius" , rb_cpSegmentShapeGetRadius, 0);
433
+ rb_define_method(c_cpSegmentShape, "r" , rb_cpSegmentShapeGetRadius, 0);
434
+ rb_define_method(c_cpSegmentShape, "normal" , rb_cpSegmentShapeGetNormal, 0);
435
+ rb_define_method(c_cpSegmentShape, "n" , rb_cpSegmentShapeGetNormal, 0);
436
+
437
+ rb_define_method(c_cpPolyShape , "num_verts" , rb_cpPolyShapeGetNumVerts, 0);
438
+ rb_define_method(c_cpPolyShape , "vert" , rb_cpPolyShapeGetVert, 1);
439
+ // also include an array-ish interface
440
+ rb_define_method(c_cpPolyShape , "length" , rb_cpPolyShapeGetNumVerts, 0);
441
+ rb_define_method(c_cpPolyShape , "size" , rb_cpPolyShapeGetNumVerts, 0);
442
+ rb_define_method(c_cpPolyShape , "[]" , rb_cpPolyShapeGetVert, 1);
443
+
444
+ /* Use a struct for this small class. More efficient. */
445
+ c_cpSegmentQueryInfo = rb_struct_define("SegmentQueryInfo",
446
+ "shape", "t", "n", NULL);
447
+ rb_define_const(m_Chipmunk, "SegmentQueryInfo", c_cpSegmentQueryInfo);
448
+
449
+ }
450
+ //