chipmunk 5.3.4.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,504 @@
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 c_cpBody;
29
+ VALUE c_cpStaticBody;
30
+
31
+ static VALUE
32
+ rb_cpBodyAlloc(VALUE klass)
33
+ {
34
+ cpBody *body = cpBodyNew(1.0f, 1.0f);
35
+ return Data_Wrap_Struct(klass, NULL, cpBodyFree, body);
36
+ }
37
+
38
+ static VALUE
39
+ rb_cpBodyInitialize(VALUE self, VALUE m, VALUE i)
40
+ {
41
+ cpBody *body = BODY(self);
42
+ cpBodyInit(body, NUM2DBL(m), NUM2DBL(i));
43
+ body->data = (void *)self;
44
+ return self;
45
+ }
46
+
47
+ static VALUE
48
+ rb_cpBodyAllocStatic(VALUE klass)
49
+ {
50
+ cpBody *body = cpBodyNewStatic();
51
+ return Data_Wrap_Struct(c_cpStaticBody, NULL, cpBodyFree, body);
52
+ }
53
+
54
+ static VALUE
55
+ rb_cpBodyInitializeStatic(VALUE self)
56
+ {
57
+ cpBody *body = STATICBODY(self);
58
+ cpBodyInitStatic(body);
59
+ body->data = (void *)self;
60
+ return self;
61
+ }
62
+
63
+ static VALUE
64
+ rb_cpStaticBodyNew(VALUE klass) {
65
+ return rb_cpBodyInitializeStatic(rb_cpBodyAllocStatic(klass));
66
+ }
67
+
68
+
69
+ static VALUE
70
+ rb_cpBodyGetMass(VALUE self)
71
+ {
72
+ return rb_float_new(BODY(self)->m);
73
+ }
74
+
75
+ static VALUE
76
+ rb_cpBodyGetMassInv(VALUE self)
77
+ {
78
+ return rb_float_new(BODY(self)->m_inv);
79
+ }
80
+
81
+ static VALUE
82
+ rb_cpBodyGetMoment(VALUE self)
83
+ {
84
+ return rb_float_new(BODY(self)->i);
85
+ }
86
+
87
+
88
+ static VALUE
89
+ rb_cpBodyGetMomentInv(VALUE self)
90
+ {
91
+ return rb_float_new(BODY(self)->i_inv);
92
+ }
93
+
94
+ static VALUE
95
+ rb_cpBodyGetPos(VALUE self)
96
+ {
97
+ return VWRAP(self, &BODY(self)->p);
98
+ }
99
+
100
+ static VALUE
101
+ rb_cpBodyGetVel(VALUE self)
102
+ {
103
+ return VWRAP(self, &BODY(self)->v);
104
+ }
105
+
106
+ static VALUE
107
+ rb_cpBodyGetForce(VALUE self)
108
+ {
109
+ return VWRAP(self, &BODY(self)->f);
110
+ }
111
+
112
+ static VALUE
113
+ rb_cpBodyGetAngle(VALUE self)
114
+ {
115
+ return rb_float_new(BODY(self)->a);
116
+ }
117
+
118
+ static VALUE
119
+ rb_cpBodyGetAVel(VALUE self)
120
+ {
121
+ return rb_float_new(BODY(self)->w);
122
+ }
123
+
124
+ static VALUE
125
+ rb_cpBodyGetTorque(VALUE self)
126
+ {
127
+ return rb_float_new(BODY(self)->t);
128
+ }
129
+
130
+ static VALUE
131
+ rb_cpBodyGetVLimit(VALUE self)
132
+ {
133
+ return rb_float_new(BODY(self)->v_limit);
134
+ }
135
+
136
+ static VALUE
137
+ rb_cpBodyGetWLimit(VALUE self)
138
+ {
139
+ return rb_float_new(BODY(self)->w_limit);
140
+ }
141
+
142
+
143
+ static VALUE
144
+ rb_cpBodyGetRot(VALUE self)
145
+ {
146
+ return VWRAP(self, &BODY(self)->rot);
147
+ }
148
+
149
+
150
+ static VALUE
151
+ rb_cpBodySetMass(VALUE self, VALUE val)
152
+ {
153
+ cpBodySetMass(BODY(self), NUM2DBL(val));
154
+ return val;
155
+ }
156
+
157
+ static VALUE
158
+ rb_cpBodySetMoment(VALUE self, VALUE val)
159
+ {
160
+ cpBodySetMoment(BODY(self), NUM2DBL(val));
161
+ return val;
162
+ }
163
+
164
+ static VALUE
165
+ rb_cpBodySetPos(VALUE self, VALUE val)
166
+ {
167
+ BODY(self)->p = *VGET(val);
168
+ return val;
169
+ }
170
+
171
+ static VALUE
172
+ rb_cpBodySetVel(VALUE self, VALUE val)
173
+ {
174
+ BODY(self)->v = *VGET(val);
175
+ return val;
176
+ }
177
+
178
+ static VALUE
179
+ rb_cpBodySetForce(VALUE self, VALUE val)
180
+ {
181
+ BODY(self)->f = *VGET(val);
182
+ return val;
183
+ }
184
+
185
+ static VALUE
186
+ rb_cpBodySetAngle(VALUE self, VALUE val)
187
+ {
188
+ cpBodySetAngle(BODY(self), NUM2DBL(val));
189
+ return val;
190
+ }
191
+
192
+ static VALUE
193
+ rb_cpBodySetAVel(VALUE self, VALUE val)
194
+ {
195
+ BODY(self)->w = NUM2DBL(val);
196
+ return val;
197
+ }
198
+
199
+ static VALUE
200
+ rb_cpBodySetTorque(VALUE self, VALUE val)
201
+ {
202
+ BODY(self)->t = NUM2DBL(val);
203
+ return val;
204
+ }
205
+
206
+
207
+ static VALUE
208
+ rb_cpBodySetVLimit(VALUE self, VALUE val)
209
+ {
210
+ BODY(self)->v_limit = NUM2DBL(val);
211
+ return val;
212
+ }
213
+
214
+ static VALUE
215
+ rb_cpBodySetWLimit(VALUE self, VALUE val)
216
+ {
217
+ BODY(self)->w_limit = NUM2DBL(val);
218
+ return val;
219
+ }
220
+
221
+
222
+
223
+ static VALUE
224
+ rb_cpBodyLocal2World(VALUE self, VALUE v)
225
+ {
226
+ return VNEW(cpBodyLocal2World(BODY(self), *VGET(v)));
227
+ }
228
+
229
+ static VALUE
230
+ rb_cpBodyWorld2Local(VALUE self, VALUE v)
231
+ {
232
+ return VNEW(cpBodyWorld2Local(BODY(self), *VGET(v)));
233
+ }
234
+
235
+ static VALUE
236
+ rb_cpBodyResetForces(VALUE self)
237
+ {
238
+ cpBodyResetForces(BODY(self));
239
+ return self;
240
+ }
241
+
242
+ static VALUE
243
+ rb_cpBodyApplyForce(VALUE self, VALUE f, VALUE r)
244
+ {
245
+ cpBodyApplyForce(BODY(self), *VGET(f), *VGET(r));
246
+ return self;
247
+ }
248
+
249
+ static VALUE
250
+ rb_cpBodyApplyImpulse(VALUE self, VALUE j, VALUE r)
251
+ {
252
+ cpBodyApplyImpulse(BODY(self), *VGET(j), *VGET(r));
253
+ return self;
254
+ }
255
+
256
+ static VALUE
257
+ rb_cpBodyUpdateVelocity(VALUE self, VALUE g, VALUE dmp, VALUE dt)
258
+ {
259
+ cpBodyUpdateVelocity(BODY(self), *VGET(g), NUM2DBL(dmp), NUM2DBL(dt));
260
+ return self;
261
+ }
262
+
263
+ static VALUE
264
+ rb_cpBodyUpdatePosition(VALUE self, VALUE dt)
265
+ {
266
+ cpBodyUpdatePosition(BODY(self), NUM2DBL(dt));
267
+ return self;
268
+ }
269
+
270
+ static VALUE rb_cpBodyActivate(VALUE self) {
271
+ cpBodyActivate(BODY(self));
272
+ return self;
273
+ }
274
+
275
+ static cpBody * rb_cpBodySleepValidate(VALUE vbody) {
276
+ cpBody * body = BODY(vbody);
277
+ cpSpace *space = body->space;
278
+ if(!space) {
279
+ rb_raise(rb_eArgError, "Cannot put a body to sleep that has not been added to a space.");
280
+ return NULL;
281
+ }
282
+ if (cpBodyIsStatic(body) && cpBodyIsRogue(body)) {
283
+ rb_raise(rb_eArgError, "Rogue AND static bodies cannot be put to sleep.");
284
+ return NULL;
285
+ }
286
+ if(space->locked) {
287
+ rb_raise(rb_eArgError, "Bodies can not be put to sleep during a query or a call to Space#add_collision_func. Put these calls into a post-step callback using Space#add_collision_handler.");
288
+ return NULL;
289
+ }
290
+ return body;
291
+ }
292
+
293
+ static VALUE rb_cpBodySleep(VALUE self) {
294
+ cpBody * body = rb_cpBodySleepValidate(self);
295
+ cpBodySleep(body);
296
+ return self;
297
+ }
298
+
299
+ static VALUE rb_cpBodySleepWithGroup(VALUE self, VALUE vgroup) {
300
+ cpBody * group = NIL_P(vgroup) ? NULL : rb_cpBodySleepValidate(vgroup);
301
+ cpBody * body = rb_cpBodySleepValidate(self);
302
+
303
+ if (!cpBodyIsSleeping(group)) {
304
+ rb_raise(rb_eArgError, "Cannot use a non-sleeping body as a group identifier.");
305
+ }
306
+ cpBodySleepWithGroup(body, group);
307
+ return self;
308
+ }
309
+
310
+
311
+ static VALUE rb_cpBodyIsSleeping(VALUE self) {
312
+ return cpBodyIsSleeping(BODY(self)) ? Qtrue : Qfalse;
313
+ }
314
+
315
+ static VALUE rb_cpBodyIsStatic(VALUE self) {
316
+ cpBody * body = BODY(self);
317
+ cpBool stat = 0;
318
+ // cpBodyInitStatic(body);
319
+ stat = cpBodyIsStatic(body);
320
+ return stat ? Qtrue : Qfalse;
321
+ //
322
+ }
323
+
324
+ static VALUE rb_cpBodyIsRogue(VALUE self) {
325
+ return cpBodyIsRogue(BODY(self)) ? Qtrue : Qfalse;
326
+ }
327
+
328
+ ID id_velocity_func;
329
+ ID id_speed_func;
330
+
331
+ static int
332
+ respondsTo(VALUE obj, ID method) {
333
+ VALUE value = rb_funcall(obj, rb_intern("respond_to?"), 1, ID2SYM(method));
334
+ return RTEST(value);
335
+ }
336
+
337
+ /*
338
+
339
+ typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
340
+ typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);
341
+ */
342
+
343
+ static void
344
+ bodyVelocityCallback(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt) {
345
+ VALUE vbody = (VALUE)(body->data);
346
+ VALUE block = rb_iv_get(vbody, "velocity_func");
347
+ VALUE vgravity = VNEW(gravity);
348
+ VALUE vdamping = rb_float_new(damping);
349
+ VALUE vdt = rb_float_new(dt);
350
+ rb_funcall(block, rb_intern("call"), 4, vbody, vgravity, vdamping, vdt);
351
+ }
352
+
353
+ static VALUE
354
+ rb_cpBodySetVelocityFunc(int argc, VALUE *argv, VALUE self)
355
+ {
356
+ VALUE block;
357
+ cpBody * body = BODY(self);
358
+ rb_scan_args(argc, argv, "&", &block);
359
+ // Restore defaults if no block
360
+ if (NIL_P(block)) {
361
+ body->velocity_func = cpBodyUpdateVelocity; //Default;
362
+ return Qnil;
363
+ }
364
+ // set block for use in callback
365
+ rb_iv_set(self, "velocity_func", block);
366
+ body->velocity_func = bodyVelocityCallback;
367
+ return self;
368
+ }
369
+
370
+ static void
371
+ bodyPositionCallback(cpBody *body, cpFloat dt) {
372
+ VALUE vbody = (VALUE)(body->data);
373
+ VALUE block = rb_iv_get(vbody, "position_func");
374
+ VALUE vdt = rb_float_new(dt);
375
+ rb_funcall(block, rb_intern("call"), 2, vbody, vdt);
376
+ }
377
+
378
+ static VALUE
379
+ rb_cpBodySetPositionFunc(int argc, VALUE *argv, VALUE self)
380
+ {
381
+ VALUE block;
382
+ cpBody * body = BODY(self);
383
+ rb_scan_args(argc, argv, "&", &block);
384
+ // Restore defaults if no block
385
+ if (NIL_P(block)) {
386
+ body->position_func = cpBodyUpdatePosition; //Default;
387
+ return Qnil;
388
+ }
389
+ // set block for use in callback
390
+ rb_iv_set(self, "position_func", block);
391
+ body->position_func = bodyPositionCallback;
392
+ return self;
393
+ }
394
+
395
+ static VALUE
396
+ rb_cpBodyGetData(VALUE self) {
397
+ return rb_iv_get(self, "data");
398
+ }
399
+
400
+ static VALUE
401
+ rb_cpBodySetData(VALUE self, VALUE val) {
402
+ rb_iv_set(self, "data", val);
403
+ return val;
404
+ }
405
+
406
+
407
+ static VALUE
408
+ rb_cpBodySlew(VALUE self, VALUE pos, VALUE dt) {
409
+ cpBodySlew(BODY(self), *VGET(pos), NUM2DBL(dt));
410
+ return self;
411
+ }
412
+
413
+
414
+ void
415
+ Init_cpBody(void)
416
+ {
417
+ c_cpBody = rb_define_class_under(m_Chipmunk, "Body", rb_cObject);
418
+ rb_define_alloc_func(c_cpBody, rb_cpBodyAlloc);
419
+ rb_define_method(c_cpBody, "initialize", rb_cpBodyInitialize, 2);
420
+
421
+ c_cpStaticBody = rb_define_class_under(m_Chipmunk, "StaticBody", c_cpBody);
422
+ // rb_define_alloc_func will not work here, since superclass defines this.
423
+ // so, we define new here in stead.
424
+ rb_define_singleton_method(c_cpStaticBody, "new", rb_cpStaticBodyNew, 0);
425
+ rb_define_method(c_cpStaticBody, "initialize", rb_cpBodyInitializeStatic, 0);
426
+ rb_define_singleton_method(c_cpBody, "new_static", rb_cpStaticBodyNew, 0);
427
+
428
+ rb_define_method(c_cpBody, "m" , rb_cpBodyGetMass, 0);
429
+ rb_define_method(c_cpBody, "i" , rb_cpBodyGetMoment, 0);
430
+
431
+ rb_define_method(c_cpBody, "p" , rb_cpBodyGetPos, 0);
432
+ rb_define_method(c_cpBody, "v" , rb_cpBodyGetVel, 0);
433
+ rb_define_method(c_cpBody, "f" , rb_cpBodyGetForce, 0);
434
+ rb_define_method(c_cpBody, "a" , rb_cpBodyGetAngle, 0);
435
+ rb_define_method(c_cpBody, "w" , rb_cpBodyGetAVel, 0);
436
+ rb_define_method(c_cpBody, "t" , rb_cpBodyGetTorque, 0);
437
+ rb_define_method(c_cpBody, "rot" , rb_cpBodyGetRot, 0);
438
+
439
+ rb_define_method(c_cpBody, "m=", rb_cpBodySetMass, 1);
440
+ rb_define_method(c_cpBody, "i=", rb_cpBodySetMoment, 1);
441
+ rb_define_method(c_cpBody, "p=", rb_cpBodySetPos, 1);
442
+ rb_define_method(c_cpBody, "v=", rb_cpBodySetVel, 1);
443
+ rb_define_method(c_cpBody, "f=", rb_cpBodySetForce, 1);
444
+ rb_define_method(c_cpBody, "a=", rb_cpBodySetAngle, 1);
445
+ rb_define_method(c_cpBody, "w=", rb_cpBodySetAVel, 1);
446
+ rb_define_method(c_cpBody, "t=", rb_cpBodySetTorque, 1);
447
+
448
+ rb_define_method(c_cpBody, "mass" , rb_cpBodyGetMass, 0);
449
+ rb_define_method(c_cpBody, "moment" , rb_cpBodyGetMoment, 0);
450
+ rb_define_method(c_cpBody, "pos" , rb_cpBodyGetPos, 0);
451
+ rb_define_method(c_cpBody, "vel" , rb_cpBodyGetVel, 0);
452
+ rb_define_method(c_cpBody, "force" , rb_cpBodyGetForce, 0);
453
+ rb_define_method(c_cpBody, "angle" , rb_cpBodyGetAngle, 0);
454
+ rb_define_method(c_cpBody, "ang_vel" , rb_cpBodyGetAVel, 0);
455
+ rb_define_method(c_cpBody, "torque" , rb_cpBodyGetTorque, 0);
456
+ rb_define_method(c_cpBody, "rot", rb_cpBodyGetRot, 0);
457
+
458
+ rb_define_method(c_cpBody, "m_inv" , rb_cpBodyGetMassInv, 0);
459
+ rb_define_method(c_cpBody, "mass_inv" , rb_cpBodyGetMassInv, 0);
460
+ rb_define_method(c_cpBody, "moment_inv" , rb_cpBodyGetMomentInv, 0);
461
+ rb_define_method(c_cpBody, "v_limit" , rb_cpBodyGetVLimit, 0);
462
+ rb_define_method(c_cpBody, "w_limit" , rb_cpBodyGetWLimit, 0);
463
+
464
+
465
+ rb_define_method(c_cpBody, "mass=" , rb_cpBodySetMass, 1);
466
+ rb_define_method(c_cpBody, "moment=" , rb_cpBodySetMoment, 1);
467
+ rb_define_method(c_cpBody, "pos=" , rb_cpBodySetPos, 1);
468
+ rb_define_method(c_cpBody, "vel=" , rb_cpBodySetVel, 1);
469
+ rb_define_method(c_cpBody, "force=" , rb_cpBodySetForce, 1);
470
+ rb_define_method(c_cpBody, "angle=" , rb_cpBodySetAngle, 1);
471
+ rb_define_method(c_cpBody, "ang_vel=" , rb_cpBodySetAVel, 1);
472
+ rb_define_method(c_cpBody, "torque=" , rb_cpBodySetTorque, 1);
473
+ rb_define_method(c_cpBody, "v_limit=" , rb_cpBodySetVLimit, 1);
474
+ rb_define_method(c_cpBody, "w_limit=" , rb_cpBodySetWLimit, 1);
475
+
476
+
477
+ rb_define_method(c_cpBody, "local2world", rb_cpBodyLocal2World, 1);
478
+ rb_define_method(c_cpBody, "world2local", rb_cpBodyWorld2Local, 1);
479
+
480
+ rb_define_method(c_cpBody, "reset_forces", rb_cpBodyResetForces, 0);
481
+ rb_define_method(c_cpBody, "apply_force", rb_cpBodyApplyForce, 2);
482
+ rb_define_method(c_cpBody, "apply_impulse", rb_cpBodyApplyImpulse, 2);
483
+
484
+ rb_define_method(c_cpBody, "update_velocity", rb_cpBodyUpdateVelocity, 3);
485
+ rb_define_method(c_cpBody, "update_position", rb_cpBodyUpdatePosition, 1);
486
+ rb_define_method(c_cpBody, "slew" , rb_cpBodySlew , 2);
487
+
488
+ rb_define_method(c_cpBody, "static?", rb_cpBodyIsStatic, 0);
489
+ rb_define_method(c_cpBody, "rogue?", rb_cpBodyIsRogue, 0);
490
+ rb_define_method(c_cpBody, "sleeping?", rb_cpBodyIsSleeping, 0);
491
+ rb_define_method(c_cpBody, "sleep?", rb_cpBodyIsSleeping, 0);
492
+ rb_define_method(c_cpBody, "sleep_with_self" , rb_cpBodySleep, 0);
493
+ rb_define_method(c_cpBody, "sleep_self" , rb_cpBodySleep, 0);
494
+ rb_define_method(c_cpBody, "sleep_alone" , rb_cpBodySleep, 0);
495
+ rb_define_method(c_cpBody, "sleep_with_group", rb_cpBodySleepWithGroup, 1);
496
+ rb_define_method(c_cpBody, "sleep_group" , rb_cpBodySleepWithGroup, 1);
497
+ rb_define_method(c_cpBody, "activate" , rb_cpBodyActivate , 0);
498
+ rb_define_method(c_cpBody, "velocity_func" , rb_cpBodySetVelocityFunc, -1);
499
+ rb_define_method(c_cpBody, "position_func" , rb_cpBodySetPositionFunc, -1);
500
+
501
+ rb_define_method(c_cpBody, "object=" , rb_cpBodySetData, 1);
502
+ rb_define_method(c_cpBody, "object" , rb_cpBodyGetData, 0);
503
+
504
+ }