chipmunk 5.2.2 → 5.3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/LICENSE +21 -19
  2. data/README +67 -60
  3. data/Rakefile +85 -50
  4. data/ext/chipmunk/extconf.rb +42 -35
  5. data/ext/chipmunk/rb_chipmunk.c +250 -125
  6. data/ext/chipmunk/rb_chipmunk.h +105 -96
  7. data/ext/chipmunk/rb_cpArbiter.c +253 -225
  8. data/ext/chipmunk/rb_cpBB.c +210 -174
  9. data/ext/chipmunk/rb_cpBody.c +504 -347
  10. data/ext/chipmunk/rb_cpConstraint.c +336 -346
  11. data/ext/chipmunk/rb_cpShape.c +433 -455
  12. data/ext/chipmunk/rb_cpSpace.c +711 -544
  13. data/ext/chipmunk/rb_cpVect.c +346 -321
  14. data/lib/chipmunk.rb +183 -30
  15. metadata +12 -66
  16. data/ext/chipmunk/chipmunk.c +0 -105
  17. data/ext/chipmunk/cpArbiter.c +0 -274
  18. data/ext/chipmunk/cpArray.c +0 -128
  19. data/ext/chipmunk/cpBB.c +0 -47
  20. data/ext/chipmunk/cpBody.c +0 -188
  21. data/ext/chipmunk/cpCollision.c +0 -391
  22. data/ext/chipmunk/cpConstraint.c +0 -54
  23. data/ext/chipmunk/cpDampedRotarySpring.c +0 -106
  24. data/ext/chipmunk/cpDampedSpring.c +0 -117
  25. data/ext/chipmunk/cpGearJoint.c +0 -114
  26. data/ext/chipmunk/cpGrooveJoint.c +0 -138
  27. data/ext/chipmunk/cpHashSet.c +0 -253
  28. data/ext/chipmunk/cpPinJoint.c +0 -117
  29. data/ext/chipmunk/cpPivotJoint.c +0 -114
  30. data/ext/chipmunk/cpPolyShape.c +0 -241
  31. data/ext/chipmunk/cpRatchetJoint.c +0 -128
  32. data/ext/chipmunk/cpRotaryLimitJoint.c +0 -122
  33. data/ext/chipmunk/cpShape.c +0 -400
  34. data/ext/chipmunk/cpSimpleMotor.c +0 -99
  35. data/ext/chipmunk/cpSlideJoint.c +0 -131
  36. data/ext/chipmunk/cpSpace.c +0 -899
  37. data/ext/chipmunk/cpSpaceHash.c +0 -541
  38. data/ext/chipmunk/cpVect.c +0 -71
  39. data/ext/chipmunk/include/chipmunk/chipmunk.h +0 -148
  40. data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +0 -42
  41. data/ext/chipmunk/include/chipmunk/chipmunk_types.h +0 -80
  42. data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +0 -54
  43. data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +0 -92
  44. data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +0 -46
  45. data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +0 -53
  46. data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +0 -41
  47. data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +0 -44
  48. data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +0 -43
  49. data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +0 -42
  50. data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +0 -40
  51. data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +0 -39
  52. data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +0 -37
  53. data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +0 -44
  54. data/ext/chipmunk/include/chipmunk/constraints/util.h +0 -116
  55. data/ext/chipmunk/include/chipmunk/cpArbiter.h +0 -136
  56. data/ext/chipmunk/include/chipmunk/cpArray.h +0 -46
  57. data/ext/chipmunk/include/chipmunk/cpBB.h +0 -74
  58. data/ext/chipmunk/include/chipmunk/cpBody.h +0 -160
  59. data/ext/chipmunk/include/chipmunk/cpCollision.h +0 -23
  60. data/ext/chipmunk/include/chipmunk/cpHashSet.h +0 -82
  61. data/ext/chipmunk/include/chipmunk/cpPolyShape.h +0 -103
  62. data/ext/chipmunk/include/chipmunk/cpShape.h +0 -174
  63. data/ext/chipmunk/include/chipmunk/cpSpace.h +0 -180
  64. data/ext/chipmunk/include/chipmunk/cpSpaceHash.h +0 -109
  65. data/ext/chipmunk/include/chipmunk/cpVect.h +0 -157
  66. data/ext/chipmunk/prime.h +0 -68
  67. data/lib/chipmunk/version.rb +0 -3
@@ -1,455 +1,433 @@
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
- VALUE c_cpSegmentQueryInfo;
35
-
36
- //c_cpSegmentQueryInfo
37
- GETTER_TEMPLATE(SQINFO, c_cpSegmentQueryInfo, cpSegmentQueryInfo)
38
-
39
- static cpSegmentQueryInfo * cpSegmentQueryInfoAlloc()
40
- {
41
- return malloc(sizeof(cpSegmentQueryInfo));
42
- }
43
-
44
- static cpSegmentQueryInfo * cpSegmentQueryInfoInit(cpSegmentQueryInfo * self,
45
- cpShape * shape, cpFloat t, cpVect n)
46
- {
47
- self->shape = shape;
48
- self->t = t;
49
- self->n = n;
50
- return self;
51
- }
52
-
53
- static VALUE
54
- rb_cpSegmentQueryInfoAlloc(VALUE klass)
55
- {
56
- struct cpSegmentQueryInfo * info = cpSegmentQueryInfoAlloc();
57
- return Data_Wrap_Struct(klass, NULL, free, info);
58
- }
59
-
60
- static VALUE
61
- rb_cpSeqmentQueryInfoInitialize(VALUE self, VALUE shape, VALUE t, VALUE n)
62
- {
63
- struct cpSegmentQueryInfo * info;
64
- info = SQINFO(self);
65
- cpSegmentQueryInfoInit(info, SHAPE(shape), NUM2DBL(t), *VGET(n));
66
- return self;
67
- }
68
-
69
- static VALUE
70
- rb_cpSeqmentQueryInfoGetShape(VALUE self)
71
- {
72
- cpShape * shape = SQINFO(self)->shape;
73
- if (!shape) return Qnil;
74
- //XXX: technically speaking, this is wrong... :p.
75
- // It's hard to wrap, though...
76
- return (VALUE) SQINFO(self)->shape->data;
77
- // return Qtrue;
78
- // return Data_Wrap_Struct(c_cpShape, 0, cpShapeFree, SQINFO(self)->shape);
79
- }
80
-
81
- static VALUE
82
- rb_cpSeqmentQueryInfoGetT(VALUE self)
83
- {
84
- return rb_float_new(SQINFO(self)->t);
85
- }
86
-
87
- static VALUE
88
- rb_cpSeqmentQueryInfoGetN(VALUE self)
89
- {
90
- return VNEW(SQINFO(self)->n);
91
- }
92
-
93
- static VALUE
94
- rb_cpSeqmentQueryInfoHitPoint(VALUE self, VALUE start, VALUE end)
95
- {
96
- return VNEW(cpSegmentQueryHitPoint(*VGET(start), *VGET(end), *SQINFO(self)));
97
- }
98
-
99
- static VALUE
100
- rb_cpSeqmentQueryInfoHitDist(VALUE self, VALUE start, VALUE end)
101
- {
102
- return rb_float_new(cpSegmentQueryHitDist(*VGET(start), *VGET(end), *SQINFO(self)));
103
- }
104
-
105
-
106
- //c_cpShape
107
- static VALUE
108
- rb_cpShapeGetBody(VALUE self)
109
- {
110
- return rb_ivar_get(self, id_body);
111
- }
112
-
113
- static VALUE
114
- rb_cpShapeSetBody(VALUE self, VALUE body)
115
- {
116
- SHAPE(self)->body = BODY(body);
117
- rb_ivar_set(self, id_body, body);
118
-
119
- return body;
120
- }
121
-
122
- static VALUE
123
- rb_cpShapeGetCollType(VALUE self)
124
- {
125
- return rb_iv_get(self, "collType");
126
- }
127
-
128
- static VALUE
129
- rb_cpShapeSetCollType(VALUE self, VALUE val)
130
- {
131
- VALUE col_type = rb_obj_id(val);
132
- rb_iv_set(self, "collType", val);
133
- SHAPE(self)->collision_type = NUM2UINT(col_type);
134
-
135
- return val;
136
- }
137
-
138
- static VALUE
139
- rb_cpShapeGetGroup(VALUE self)
140
- {
141
- return rb_iv_get(self, "group");
142
- }
143
-
144
- static VALUE
145
- rb_cpShapeSetGroup(VALUE self, VALUE val)
146
- {
147
- VALUE group_type = rb_obj_id(val);
148
- rb_iv_set(self, "group", val);
149
-
150
- if (val == rb_intern("no_group")) {
151
- SHAPE(self)->group = CP_NO_GROUP;
152
- } else {
153
- SHAPE(self)->group = NUM2UINT(group_type);
154
- }
155
-
156
- return val;
157
- }
158
-
159
- static VALUE
160
- rb_cpShapeGetLayers(VALUE self)
161
- {
162
- if(SHAPE(self)->layers == CP_ALL_LAYERS) {
163
- return rb_intern("all_layers");
164
- }
165
- return UINT2NUM(SHAPE(self)->layers);
166
- }
167
-
168
- static VALUE
169
- rb_cpShapeSetLayers(VALUE self, VALUE layers)
170
- {
171
- if (layers == rb_intern("all_layers")) {
172
- SHAPE(self)->layers = CP_ALL_LAYERS;
173
- } else {
174
- SHAPE(self)->layers = NUM2UINT(layers);
175
- }
176
- return layers;
177
- }
178
-
179
- static VALUE
180
- rb_cpShapeGetBB(VALUE self)
181
- {
182
- cpBB *bb = malloc(sizeof(cpBB));
183
- *bb = SHAPE(self)->bb;
184
- return Data_Wrap_Struct(c_cpBB, NULL, free, bb);
185
- }
186
-
187
- static VALUE
188
- rb_cpShapeCacheBB(VALUE self)
189
- {
190
- cpShape *shape = SHAPE(self);
191
- cpShapeCacheBB(shape);
192
-
193
- return rb_cpShapeGetBB(self);
194
- }
195
-
196
- static VALUE
197
- rb_cpShapeGetElasticity(VALUE self)
198
- {
199
- return rb_float_new(SHAPE(self)->e);
200
- }
201
-
202
- static VALUE
203
- rb_cpShapeGetFriction(VALUE self)
204
- {
205
- return rb_float_new(SHAPE(self)->u);
206
- }
207
-
208
-
209
- static VALUE
210
- rb_cpShapeSetElasticity(VALUE self, VALUE val)
211
- {
212
- SHAPE(self)->e = NUM2DBL(val);
213
- return val;
214
- }
215
-
216
- static VALUE
217
- rb_cpShapeSetFriction(VALUE self, VALUE val)
218
- {
219
- SHAPE(self)->u = NUM2DBL(val);
220
- return val;
221
- }
222
-
223
- static VALUE
224
- rb_cpShapeGetSurfaceV(VALUE self)
225
- {
226
- return VWRAP(self, &SHAPE(self)->surface_v);
227
- }
228
-
229
- static VALUE
230
- rb_cpShapeSetSurfaceV(VALUE self, VALUE val)
231
- {
232
- SHAPE(self)->surface_v = *VGET(val);
233
- return val;
234
- }
235
-
236
- static VALUE
237
- rb_cpShapeResetIdCounter(VALUE self)
238
- {
239
- cpResetShapeIdCounter();
240
- return Qnil;
241
- }
242
-
243
- static VALUE
244
- rb_cpShapeGetData(VALUE self)
245
- {
246
- return (VALUE) (SHAPE(self)->data);
247
- }
248
-
249
-
250
- static VALUE
251
- rb_cpShapeGetSensor(VALUE self)
252
- {
253
- int bool = (SHAPE(self)->sensor);
254
- return bool ? Qtrue : Qfalse;
255
- }
256
-
257
- static VALUE
258
- rb_cpShapeSetSensor(VALUE self, VALUE val)
259
- {
260
- int bool = ((val == Qnil) || (val == Qfalse)) ? 0 : 1;
261
- SHAPE(self)->sensor = bool;
262
- return val;
263
- }
264
-
265
- static VALUE
266
- rb_cpShapePointQuery(VALUE self, VALUE point) {
267
- int bool = cpShapePointQuery(SHAPE(self), *VGET(point));
268
- return bool ? Qtrue : Qfalse;
269
- }
270
-
271
- // Shape/segment query
272
- static VALUE
273
- rb_cpShapeSegmentQuery(VALUE self, VALUE a, VALUE b)
274
- {
275
- cpSegmentQueryInfo * info = cpSegmentQueryInfoAlloc();
276
- int bool = cpShapeSegmentQuery(SHAPE(self), *VGET(a), *VGET(b), info);
277
- if (bool) {
278
- return Data_Wrap_Struct(c_cpSegmentQueryInfo, NULL, free, info);
279
- } else {
280
- return Qnil;
281
- }
282
- }
283
-
284
-
285
- //cpCircle
286
- static VALUE
287
- rb_cpCircleAlloc(VALUE klass)
288
- {
289
- cpCircleShape *circle = cpCircleShapeAlloc();
290
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, circle);
291
- }
292
-
293
- static VALUE
294
- rb_cpCircleInitialize(VALUE self, VALUE body, VALUE radius, VALUE offset)
295
- {
296
- cpCircleShape *circle = (cpCircleShape *)SHAPE(self);
297
-
298
- cpCircleShapeInit(circle, BODY(body), NUM2DBL(radius), *VGET(offset));
299
- circle->shape.data = (void *)self;
300
- circle->shape.collision_type = Qnil;
301
-
302
- rb_ivar_set(self, id_body, body);
303
-
304
- return self;
305
- }
306
-
307
-
308
-
309
- //cpSegment
310
- static VALUE
311
- rb_cpSegmentAlloc(VALUE klass)
312
- {
313
- cpSegmentShape *seg = cpSegmentShapeAlloc();
314
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, seg);
315
- }
316
-
317
- static VALUE
318
- rb_cpSegmentInitialize(VALUE self, VALUE body, VALUE a, VALUE b, VALUE r)
319
- {
320
- cpSegmentShape *seg = (cpSegmentShape *)SHAPE(self);
321
-
322
- cpSegmentShapeInit(seg, BODY(body), *VGET(a), *VGET(b), NUM2DBL(r));
323
- seg->shape.data = (void *)self;
324
- seg->shape.collision_type = Qnil;
325
-
326
- rb_ivar_set(self, id_body, body);
327
-
328
- return self;
329
- }
330
-
331
-
332
-
333
- //cpPoly
334
- static VALUE
335
- rb_cpPolyAlloc(VALUE klass)
336
- {
337
- cpPolyShape *poly = cpPolyShapeAlloc();
338
- return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
339
- }
340
-
341
- static VALUE
342
- rb_cpPolyInitialize(VALUE self, VALUE body, VALUE arr, VALUE offset)
343
- {
344
- cpPolyShape *poly = (cpPolyShape *)SHAPE(self);
345
-
346
- Check_Type(arr, T_ARRAY);
347
- int numVerts = RARRAY_LEN(arr);
348
- VALUE *ary_ptr = RARRAY_PTR(arr);
349
- cpVect verts[numVerts];
350
-
351
- for(int i=0; i<numVerts; i++)
352
- verts[i] = *VGET(ary_ptr[i]);
353
-
354
- cpPolyShapeInit(poly, BODY(body), numVerts, verts, *VGET(offset));
355
- poly->shape.data = (void *)self;
356
- poly->shape.collision_type = Qnil;
357
-
358
- rb_ivar_set(self, id_body, body);
359
-
360
- return self;
361
- }
362
-
363
-
364
-
365
-
366
-
367
-
368
- void
369
- Init_cpShape(void)
370
- {
371
- id_body = rb_intern("body");
372
-
373
- m_cpShape = rb_define_module_under(m_Chipmunk, "Shape");
374
- rb_define_attr(m_cpShape, "obj", 1, 1);
375
-
376
- rb_define_method(m_cpShape, "body", rb_cpShapeGetBody, 0);
377
- rb_define_method(m_cpShape, "body=", rb_cpShapeSetBody, 1);
378
-
379
- rb_define_method(m_cpShape, "collision_type", rb_cpShapeGetCollType, 0);
380
- rb_define_method(m_cpShape, "collision_type=", rb_cpShapeSetCollType, 1);
381
-
382
- rb_define_method(m_cpShape, "group", rb_cpShapeGetGroup, 0);
383
- rb_define_method(m_cpShape, "group=", rb_cpShapeSetGroup, 1);
384
-
385
- rb_define_method(m_cpShape, "layers", rb_cpShapeGetLayers, 0);
386
- rb_define_method(m_cpShape, "layers=", rb_cpShapeSetLayers, 1);
387
-
388
- rb_define_method(m_cpShape, "bb", rb_cpShapeGetBB, 0);
389
- rb_define_method(m_cpShape, "cache_bb", rb_cpShapeCacheBB, 0);
390
-
391
- rb_define_method(m_cpShape, "e", rb_cpShapeGetElasticity, 0);
392
- rb_define_method(m_cpShape, "u", rb_cpShapeGetFriction, 0);
393
-
394
- rb_define_method(m_cpShape, "e=", rb_cpShapeSetElasticity, 1);
395
- rb_define_method(m_cpShape, "u=", rb_cpShapeSetFriction, 1);
396
-
397
- rb_define_method(m_cpShape, "surface_v" , rb_cpShapeGetSurfaceV, 0);
398
- rb_define_method(m_cpShape, "surface_v=" , rb_cpShapeSetSurfaceV, 1);
399
-
400
- rb_define_method(m_cpShape, "data" , rb_cpShapeGetData, 0);
401
- /*
402
- XXX: do we need data= ? Data is used internally, so perhaps what
403
- chipmunk-ffi isdoing doesn't make sense here?
404
- */
405
- rb_define_method(m_cpShape, "sensor" , rb_cpShapeGetSensor, 0);
406
- rb_define_method(m_cpShape, "sensor?" , rb_cpShapeGetSensor, 0);
407
- rb_define_method(m_cpShape, "sensor=" , rb_cpShapeSetSensor, 1);
408
-
409
- rb_define_method(m_cpShape, "point_query" , rb_cpShapePointQuery, 1);
410
- rb_define_method(m_cpShape, "segment_query", rb_cpShapeSegmentQuery, 2);
411
-
412
-
413
-
414
- rb_define_singleton_method(m_cpShape, "reset_id_counter", rb_cpShapeResetIdCounter, 0);
415
-
416
-
417
- c_cpCircleShape = rb_define_class_under(m_cpShape, "Circle", rb_cObject);
418
- rb_include_module(c_cpCircleShape, m_cpShape);
419
- rb_define_alloc_func(c_cpCircleShape, rb_cpCircleAlloc);
420
- rb_define_method(c_cpCircleShape, "initialize", rb_cpCircleInitialize, 3);
421
-
422
-
423
- c_cpSegmentShape = rb_define_class_under(m_cpShape, "Segment", rb_cObject);
424
- rb_include_module(c_cpSegmentShape, m_cpShape);
425
- rb_define_alloc_func(c_cpSegmentShape, rb_cpSegmentAlloc);
426
- rb_define_method(c_cpSegmentShape, "initialize", rb_cpSegmentInitialize, 4);
427
-
428
-
429
- c_cpPolyShape = rb_define_class_under(m_cpShape, "Poly", rb_cObject);
430
- rb_include_module(c_cpPolyShape, m_cpShape);
431
- rb_define_alloc_func(c_cpPolyShape, rb_cpPolyAlloc);
432
- rb_define_method(c_cpPolyShape, "initialize", rb_cpPolyInitialize, 3);
433
-
434
-
435
- c_cpSegmentQueryInfo = rb_define_class_under(m_cpShape,
436
- "SegmentQueryInfo", rb_cObject);
437
- rb_define_alloc_func(c_cpSegmentQueryInfo, rb_cpSegmentQueryInfoAlloc);
438
- rb_define_method(c_cpSegmentQueryInfo, "initialize",
439
- rb_cpSeqmentQueryInfoInitialize, 3);
440
-
441
- rb_define_method(c_cpSegmentQueryInfo, "shape",
442
- rb_cpSeqmentQueryInfoGetShape, 0);
443
- rb_define_method(c_cpSegmentQueryInfo, "hit",
444
- rb_cpSeqmentQueryInfoGetShape, 0);
445
- rb_define_method(c_cpSegmentQueryInfo, "t",
446
- rb_cpSeqmentQueryInfoGetT, 0);
447
- rb_define_method(c_cpSegmentQueryInfo, "n",
448
- rb_cpSeqmentQueryInfoGetN, 0);
449
- rb_define_method(c_cpSegmentQueryInfo, "hit_point",
450
- rb_cpSeqmentQueryInfoHitPoint, 2);
451
- rb_define_method(c_cpSegmentQueryInfo, "hit_distance",
452
- rb_cpSeqmentQueryInfoHitDist, 2);
453
-
454
- }
455
-
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
+ static VALUE
273
+ rb_cpPolyAlloc(VALUE klass)
274
+ {
275
+ cpPolyShape *poly = cpPolyShapeAlloc();
276
+ return Data_Wrap_Struct(klass, NULL, cpShapeFree, poly);
277
+ }
278
+
279
+ 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;
295
+
296
+ rb_ivar_set(self, id_body, body);
297
+
298
+ return self;
299
+ }
300
+
301
+ // some getters
302
+ static VALUE rb_cpCircleShapeGetOffset(VALUE self) {
303
+ return VNEW(cpCircleShapeGetOffset(SHAPE(self)));
304
+ }
305
+
306
+ static VALUE rb_cpCircleShapeGetRadius(VALUE self) {
307
+ return rb_float_new(cpCircleShapeGetRadius(SHAPE(self)));
308
+ }
309
+
310
+ static VALUE rb_cpSegmentShapeGetA(VALUE self) {
311
+ return VNEW(cpSegmentShapeGetA(SHAPE(self)));
312
+ }
313
+
314
+ static VALUE rb_cpSegmentShapeGetB(VALUE self) {
315
+ return VNEW(cpSegmentShapeGetB(SHAPE(self)));
316
+ }
317
+
318
+ static VALUE rb_cpSegmentShapeGetRadius(VALUE self) {
319
+ return rb_float_new(cpSegmentShapeGetRadius(SHAPE(self)));
320
+ }
321
+
322
+ static VALUE rb_cpSegmentShapeGetNormal(VALUE self) {
323
+ return VNEW(cpSegmentShapeGetNormal(SHAPE(self)));
324
+ }
325
+
326
+ static VALUE rb_cpPolyShapeGetNumVerts(VALUE self) {
327
+ return INT2NUM(cpPolyShapeGetNumVerts(SHAPE(self)));
328
+ }
329
+
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))) {
334
+ return Qnil;
335
+ }
336
+ return VNEW(cpPolyShapeGetVert(shape, index));
337
+ }
338
+
339
+
340
+ 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
+
351
+ rb_define_method(m_cpShape, "sensor?", rb_cpShapeSensorP, 0);
352
+ 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.
360
+ rb_define_method(m_cpShape, "data", rb_cpShapeGetSelf, 0);
361
+ // So we use this as the object setter
362
+ rb_define_method(m_cpShape, "object" , rb_cpShapeGetData, 0);
363
+ 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
+
384
+ rb_define_method(m_cpShape, "point_query", rb_cpShapePointQuery, 1);
385
+ 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
+
409
+ rb_define_method(c_cpCircleShape, "offset", rb_cpCircleShapeGetOffset, 0);
410
+ 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);
422
+ // 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
+
427
+ /* Use a struct for this small class. More efficient. */
428
+ c_cpSegmentQueryInfo = rb_struct_define("SegmentQueryInfo",
429
+ "shape", "t", "n", NULL);
430
+ rb_define_const(m_Chipmunk, "SegmentQueryInfo", c_cpSegmentQueryInfo);
431
+
432
+ }
433
+ //