chipmunk 5.3.4.5 → 6.1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/chipmunk/chipmunk.c +199 -28
- data/ext/chipmunk/chipmunk.h +123 -68
- data/ext/chipmunk/chipmunk_ffi.h +129 -11
- data/ext/chipmunk/chipmunk_private.h +232 -16
- data/ext/chipmunk/chipmunk_types.h +94 -30
- data/ext/chipmunk/chipmunk_unsafe.h +12 -3
- data/ext/chipmunk/constraints/cpConstraint.h +90 -34
- data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
- data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
- data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
- data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
- data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
- data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
- data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
- data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
- data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
- data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
- data/ext/chipmunk/constraints/util.h +36 -44
- data/ext/chipmunk/cpArbiter.c +159 -94
- data/ext/chipmunk/cpArbiter.h +135 -129
- data/ext/chipmunk/cpArray.c +37 -56
- data/ext/chipmunk/cpBB.c +1 -12
- data/ext/chipmunk/cpBB.h +80 -18
- data/ext/chipmunk/cpBBTree.c +891 -0
- data/ext/chipmunk/cpBody.c +185 -47
- data/ext/chipmunk/cpBody.h +156 -124
- data/ext/chipmunk/cpCollision.c +126 -115
- data/ext/chipmunk/cpConstraint.c +10 -6
- data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
- data/ext/chipmunk/cpDampedSpring.c +25 -18
- data/ext/chipmunk/cpGearJoint.c +23 -17
- data/ext/chipmunk/cpGrooveJoint.c +26 -22
- data/ext/chipmunk/cpHashSet.c +51 -51
- data/ext/chipmunk/cpPinJoint.c +26 -19
- data/ext/chipmunk/cpPivotJoint.c +23 -19
- data/ext/chipmunk/cpPolyShape.c +93 -69
- data/ext/chipmunk/cpPolyShape.h +33 -69
- data/ext/chipmunk/cpRatchetJoint.c +26 -21
- data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
- data/ext/chipmunk/cpShape.c +122 -133
- data/ext/chipmunk/cpShape.h +146 -95
- data/ext/chipmunk/cpSimpleMotor.c +24 -17
- data/ext/chipmunk/cpSlideJoint.c +28 -26
- data/ext/chipmunk/cpSpace.c +251 -196
- data/ext/chipmunk/cpSpace.h +173 -103
- data/ext/chipmunk/cpSpaceComponent.c +236 -159
- data/ext/chipmunk/cpSpaceHash.c +259 -159
- data/ext/chipmunk/cpSpaceQuery.c +127 -59
- data/ext/chipmunk/cpSpaceStep.c +235 -197
- data/ext/chipmunk/cpSpatialIndex.c +69 -0
- data/ext/chipmunk/cpSpatialIndex.h +227 -0
- data/ext/chipmunk/cpSweep1D.c +254 -0
- data/ext/chipmunk/cpVect.c +11 -26
- data/ext/chipmunk/cpVect.h +76 -71
- data/ext/chipmunk/extconf.rb +4 -31
- data/ext/chipmunk/prime.h +1 -1
- data/ext/chipmunk/rb_chipmunk.c +36 -45
- data/ext/chipmunk/rb_chipmunk.h +6 -3
- data/ext/chipmunk/rb_cpArbiter.c +2 -2
- data/ext/chipmunk/rb_cpBB.c +116 -35
- data/ext/chipmunk/rb_cpBody.c +5 -12
- data/ext/chipmunk/rb_cpConstraint.c +144 -9
- data/ext/chipmunk/rb_cpShape.c +69 -78
- data/ext/chipmunk/rb_cpSpace.c +81 -76
- metadata +61 -61
- data/LICENSE +0 -22
- data/README +0 -110
- data/Rakefile +0 -102
- data/ext/chipmunk/cpArray.h +0 -49
- data/ext/chipmunk/cpCollision.h +0 -28
- data/ext/chipmunk/cpHashSet.h +0 -82
- data/ext/chipmunk/cpSpaceHash.h +0 -110
- data/lib/chipmunk.rb +0 -194
data/ext/chipmunk/rb_chipmunk.h
CHANGED
@@ -33,6 +33,8 @@ extern VALUE c_cpSpace;
|
|
33
33
|
extern VALUE c_cpArbiter;
|
34
34
|
extern VALUE c_cpStaticBody;
|
35
35
|
extern VALUE c_cpSegmentQueryInfo;
|
36
|
+
extern VALUE c_cpNearestPointQueryInfo;
|
37
|
+
extern VALUE cpObjectToIntHash;
|
36
38
|
|
37
39
|
extern ID id_parent;
|
38
40
|
|
@@ -51,6 +53,8 @@ VWRAP(VALUE parent, cpVect *v) {
|
|
51
53
|
return vec_obj;
|
52
54
|
}
|
53
55
|
|
56
|
+
int cp_rb_obj_method_arity(VALUE self, ID id);
|
57
|
+
|
54
58
|
#define GETTER_TEMPLATE(func_name, klass, type) \
|
55
59
|
static inline type * \
|
56
60
|
func_name(VALUE self) \
|
@@ -85,10 +89,9 @@ VGET_ZERO(VALUE value) {
|
|
85
89
|
return *VGET(value);
|
86
90
|
}
|
87
91
|
|
88
|
-
|
92
|
+
int CP_OBJ2INT(VALUE object);
|
89
93
|
VALUE rb_cpSegmentQueryInfoNew(VALUE shape, VALUE t, VALUE n);
|
90
|
-
|
91
|
-
// Helper that allocates and initializes a ContactPoint struct.
|
94
|
+
VALUE rb_cpNearestPointQueryInfoNew(VALUE shape, VALUE p, VALUE d);
|
92
95
|
VALUE rb_cpContactPointNew(VALUE point, VALUE normal, VALUE dist);
|
93
96
|
|
94
97
|
|
data/ext/chipmunk/rb_cpArbiter.c
CHANGED
@@ -193,8 +193,8 @@ rb_cpArbiterGetDepth(VALUE self, VALUE index) {
|
|
193
193
|
if (arbiterBadIndex(arb, i)) {
|
194
194
|
rb_raise(rb_eIndexError, "No such depth.");
|
195
195
|
}
|
196
|
-
// there
|
197
|
-
return rb_float_new(
|
196
|
+
// there was a typo in the cpArbiter.h class but ,no more in 6.0.3.
|
197
|
+
return rb_float_new(cpArbiterGetDepth(arb, i));
|
198
198
|
}
|
199
199
|
|
200
200
|
|
data/ext/chipmunk/rb_cpBB.c
CHANGED
@@ -41,45 +41,94 @@ rb_cpBBAlloc(VALUE klass) {
|
|
41
41
|
}
|
42
42
|
|
43
43
|
static VALUE
|
44
|
-
rb_cpBBInitialize(
|
44
|
+
rb_cpBBInitialize(int argc, VALUE *argv, VALUE self) {
|
45
|
+
VALUE l, b, r, t;
|
45
46
|
cpBB *bb = BBGET(self);
|
46
|
-
bb->l = NUM2DBL(l);
|
47
|
-
bb->b = NUM2DBL(b);
|
48
|
-
bb->r = NUM2DBL(r);
|
49
|
-
bb->t = NUM2DBL(t);
|
50
47
|
|
48
|
+
rb_scan_args(argc, argv, "04", &l, &b, &r, &t);
|
49
|
+
// initialize as a circle bounds box if ony 2 params
|
50
|
+
if (NIL_P(r)) {
|
51
|
+
if(NIL_P(l)) {
|
52
|
+
(*bb) = cpBBNew(0, 0, 1, 1); // unit box.
|
53
|
+
} else {
|
54
|
+
cpVect * p = VGET(l);
|
55
|
+
(*bb) = cpBBNewForCircle(*p, NUM2DBL(b));
|
56
|
+
}
|
57
|
+
} else {
|
58
|
+
(*bb) = cpBBNew(NUM2DBL(l), NUM2DBL(b), NUM2DBL(r), NUM2DBL(t));
|
59
|
+
}
|
51
60
|
return self;
|
52
61
|
}
|
53
62
|
|
63
|
+
/*
|
54
64
|
static VALUE
|
55
|
-
rb_cpBBintersects(VALUE self, VALUE
|
56
|
-
|
57
|
-
|
65
|
+
rb_cpBBintersects(VALUE self, VALUE a, VALUE b) {
|
66
|
+
cpVect *a, *b;
|
67
|
+
if(IS_NIL(b)) { // box/box intersect
|
68
|
+
return CP_INT_BOOL(cpBBIntersects(*BBGET(self), *BBGET(a)));
|
69
|
+
}
|
70
|
+
// If we get here it's a box/segment intersect
|
71
|
+
a = VGET(va);
|
72
|
+
b = VGET(vb);
|
73
|
+
if(a && b) {
|
74
|
+
return CP_INT_BOOL(cpBBIntersectsSegment(*BBGET(self), *a, *b));
|
75
|
+
}
|
76
|
+
rb_raise(rb_eArgError, "intersects needs 1 Box or 2 Vect2 arguments");
|
77
|
+
return Qnil;
|
58
78
|
}
|
79
|
+
*/
|
59
80
|
|
60
81
|
static VALUE
|
61
|
-
|
62
|
-
int value =
|
63
|
-
return value
|
82
|
+
rb_cpBBContainsBB(VALUE self, VALUE other) {
|
83
|
+
int value = cpBBContainsBB(*BBGET(self), *BBGET(other));
|
84
|
+
return CP_INT_BOOL(value);
|
64
85
|
}
|
65
86
|
|
66
87
|
static VALUE
|
67
|
-
|
68
|
-
int value =
|
69
|
-
return value
|
88
|
+
rb_cpBBContainsVect(VALUE self, VALUE other) {
|
89
|
+
int value = cpBBContainsVect(*BBGET(self), *VGET(other));
|
90
|
+
return CP_INT_BOOL(value);
|
70
91
|
}
|
71
92
|
|
72
93
|
static VALUE
|
73
94
|
rb_cpBBcontains(VALUE self, VALUE other) {
|
74
95
|
if (rb_class_of(other) == c_cpBB) {
|
75
|
-
return
|
96
|
+
return rb_cpBBContainsBB(self, other);
|
76
97
|
} else if (rb_class_of(other) == c_cpVect) {
|
77
|
-
return
|
98
|
+
return rb_cpBBContainsVect(self, other);
|
78
99
|
}
|
79
|
-
rb_raise(rb_eArgError, "contains
|
100
|
+
rb_raise(rb_eArgError, "contains requires a BB or a Vect2 argument");
|
80
101
|
return Qnil;
|
81
102
|
}
|
82
103
|
|
104
|
+
static VALUE
|
105
|
+
rb_cpBBIntersectsBB(VALUE self, VALUE other) {
|
106
|
+
int value = cpBBIntersects(*BBGET(self), *BBGET(other));
|
107
|
+
return CP_INT_BOOL(value);
|
108
|
+
}
|
109
|
+
|
110
|
+
static VALUE
|
111
|
+
rb_cpBBIntersectsSegment(VALUE self, VALUE a, VALUE b) {
|
112
|
+
int value = cpBBIntersectsSegment(*BBGET(self), *VGET(a), *VGET(b));
|
113
|
+
return CP_INT_BOOL(value);
|
114
|
+
}
|
115
|
+
|
116
|
+
static VALUE
|
117
|
+
rb_cpBBintersects(int argc, VALUE *argv, VALUE self) {
|
118
|
+
VALUE other, b;
|
119
|
+
|
120
|
+
rb_scan_args(argc, argv, "11", &other, &b);
|
121
|
+
|
122
|
+
if (rb_class_of(other) == c_cpBB) {
|
123
|
+
return rb_cpBBIntersectsBB(self, other);
|
124
|
+
} else if ((rb_class_of(other) == c_cpVect) && (rb_class_of(b) == c_cpVect)) {
|
125
|
+
return rb_cpBBIntersectsSegment(self, other, b);
|
126
|
+
}
|
127
|
+
rb_raise(rb_eArgError, "contains requires a BB or 2 Vect2 arguments");
|
128
|
+
return Qnil;
|
129
|
+
}
|
130
|
+
|
131
|
+
|
83
132
|
static VALUE
|
84
133
|
rb_cpBBClampVect(VALUE self, VALUE v) {
|
85
134
|
return VNEW(cpBBClampVect(*BBGET(self), *VGET(v)));
|
@@ -146,12 +195,35 @@ rb_cpBBToString(VALUE self) {
|
|
146
195
|
|
147
196
|
static VALUE
|
148
197
|
rb_cpBBmerge(VALUE self, VALUE other) {
|
149
|
-
return BBNEW(
|
198
|
+
return BBNEW(cpBBMerge(*BBGET(self), *BBGET(other)));
|
150
199
|
}
|
151
200
|
|
152
201
|
static VALUE
|
153
202
|
rb_cpBBexpand(VALUE self, VALUE other) {
|
154
|
-
return BBNEW(
|
203
|
+
return BBNEW(cpBBExpand(*BBGET(self), *VGET(other)));
|
204
|
+
}
|
205
|
+
|
206
|
+
static VALUE
|
207
|
+
rb_cpBBArea(VALUE self) {
|
208
|
+
return DBL2NUM(cpBBArea(*BBGET(self)));
|
209
|
+
}
|
210
|
+
|
211
|
+
static VALUE
|
212
|
+
rb_cpBBMergedArea(VALUE self, VALUE other) {
|
213
|
+
return DBL2NUM(cpBBMergedArea(*BBGET(self), *BBGET(other)));
|
214
|
+
}
|
215
|
+
|
216
|
+
/// Returns the fraction along the segment query the cpBB is hit. Returns INFINITY if it doesn't hit.
|
217
|
+
static VALUE
|
218
|
+
rb_cpBBSegmentQuery(VALUE self, VALUE va, VALUE vb) {
|
219
|
+
cpVect *a, *b;
|
220
|
+
a = VGET(va);
|
221
|
+
b = VGET(vb);
|
222
|
+
if(a && b) {
|
223
|
+
return DBL2NUM(cpBBSegmentQuery(*BBGET(self), *a, *b));
|
224
|
+
}
|
225
|
+
rb_raise(rb_eArgError, "query requires 2 Vect2 arguments");
|
226
|
+
return Qnil;
|
155
227
|
}
|
156
228
|
|
157
229
|
|
@@ -159,7 +231,7 @@ void
|
|
159
231
|
Init_cpBB(void) {
|
160
232
|
c_cpBB = rb_define_class_under(m_Chipmunk, "BB", rb_cObject);
|
161
233
|
rb_define_alloc_func(c_cpBB, rb_cpBBAlloc);
|
162
|
-
rb_define_method(c_cpBB, "initialize", rb_cpBBInitialize,
|
234
|
+
rb_define_method(c_cpBB, "initialize", rb_cpBBInitialize, -1);
|
163
235
|
|
164
236
|
rb_define_method(c_cpBB, "l", rb_cpBBGetL, 0);
|
165
237
|
rb_define_method(c_cpBB, "b", rb_cpBBGetB, 0);
|
@@ -171,23 +243,32 @@ Init_cpBB(void) {
|
|
171
243
|
rb_define_method(c_cpBB, "r=", rb_cpBBSetR, 1);
|
172
244
|
rb_define_method(c_cpBB, "t=", rb_cpBBSetT, 1);
|
173
245
|
|
174
|
-
rb_define_method(c_cpBB, "intersect?", rb_cpBBintersects, 1);
|
175
|
-
rb_define_method(c_cpBB, "intersects?", rb_cpBBintersects, 1);
|
246
|
+
rb_define_method(c_cpBB, "intersect?", rb_cpBBintersects, -1);
|
247
|
+
rb_define_method(c_cpBB, "intersects?", rb_cpBBintersects, -1);
|
248
|
+
|
176
249
|
//containsBB
|
177
250
|
//containsVect
|
178
|
-
rb_define_method(c_cpBB, "contains?", rb_cpBBcontains, 1);
|
179
|
-
rb_define_method(c_cpBB, "contain?", rb_cpBBcontains, 1);
|
180
|
-
|
181
|
-
rb_define_method(c_cpBB, "contains_bb?",
|
182
|
-
rb_define_method(c_cpBB, "contain_bb?",
|
183
|
-
rb_define_method(c_cpBB, "contains_vect?",
|
184
|
-
rb_define_method(c_cpBB, "contain_vect?",
|
185
|
-
|
186
|
-
rb_define_method(c_cpBB, "clamp_vect", rb_cpBBClampVect, 1);
|
187
|
-
rb_define_method(c_cpBB, "wrap_vect", rb_cpBBWrapVect, 1);
|
188
|
-
rb_define_method(c_cpBB, "merge", rb_cpBBmerge, 1);
|
189
|
-
rb_define_method(c_cpBB, "expand", rb_cpBBexpand, 1);
|
190
|
-
|
251
|
+
rb_define_method(c_cpBB, "contains?" , rb_cpBBcontains, 1);
|
252
|
+
rb_define_method(c_cpBB, "contain?" , rb_cpBBcontains, 1);
|
253
|
+
|
254
|
+
rb_define_method(c_cpBB, "contains_bb?", rb_cpBBContainsBB, 1);
|
255
|
+
rb_define_method(c_cpBB, "contain_bb?", rb_cpBBContainsBB, 1);
|
256
|
+
rb_define_method(c_cpBB, "contains_vect?", rb_cpBBContainsVect, 1);
|
257
|
+
rb_define_method(c_cpBB, "contain_vect?", rb_cpBBContainsVect, 1);
|
258
|
+
|
259
|
+
rb_define_method(c_cpBB, "clamp_vect" , rb_cpBBClampVect, 1);
|
260
|
+
rb_define_method(c_cpBB, "wrap_vect" , rb_cpBBWrapVect, 1);
|
261
|
+
rb_define_method(c_cpBB, "merge" , rb_cpBBmerge, 1);
|
262
|
+
rb_define_method(c_cpBB, "expand" , rb_cpBBexpand, 1);
|
263
|
+
|
264
|
+
rb_define_method(c_cpBB, "area" , rb_cpBBArea, 0);
|
265
|
+
rb_define_method(c_cpBB, "merged_area" , rb_cpBBMergedArea, 1);
|
266
|
+
|
267
|
+
rb_define_method(c_cpBB, "intersect_bb?", rb_cpBBIntersectsBB, 1);
|
268
|
+
rb_define_method(c_cpBB, "intersects_bb?", rb_cpBBIntersectsBB, 1);
|
269
|
+
rb_define_method(c_cpBB, "intersect_segment?", rb_cpBBIntersectsSegment, 2);
|
270
|
+
rb_define_method(c_cpBB, "intersects_segment?", rb_cpBBIntersectsSegment, 2);
|
271
|
+
rb_define_method(c_cpBB, "segment_query", rb_cpBBSegmentQuery, 2);
|
191
272
|
|
192
273
|
rb_define_method(c_cpBB, "to_s", rb_cpBBToString, 0);
|
193
274
|
}
|
data/ext/chipmunk/rb_cpBody.c
CHANGED
@@ -242,7 +242,7 @@ rb_cpBodyActivate(VALUE self) {
|
|
242
242
|
static cpBody *
|
243
243
|
rb_cpBodySleepValidate(VALUE vbody) {
|
244
244
|
cpBody * body = BODY(vbody);
|
245
|
-
cpSpace *space = body->space;
|
245
|
+
cpSpace *space = body->CP_PRIVATE(space);
|
246
246
|
if(!space) {
|
247
247
|
rb_raise(rb_eArgError, "Cannot put a body to sleep that has not been added to a space.");
|
248
248
|
return NULL;
|
@@ -251,7 +251,7 @@ rb_cpBodySleepValidate(VALUE vbody) {
|
|
251
251
|
rb_raise(rb_eArgError, "Rogue AND static bodies cannot be put to sleep.");
|
252
252
|
return NULL;
|
253
253
|
}
|
254
|
-
if(space
|
254
|
+
if(cpSpaceIsLocked(space)) {
|
255
255
|
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.");
|
256
256
|
return NULL;
|
257
257
|
}
|
@@ -301,11 +301,13 @@ rb_cpBodyIsRogue(VALUE self) {
|
|
301
301
|
ID id_velocity_func;
|
302
302
|
ID id_speed_func;
|
303
303
|
|
304
|
+
/*
|
304
305
|
static int
|
305
306
|
respondsTo(VALUE obj, ID method) {
|
306
307
|
VALUE value = rb_funcall(obj, rb_intern("respond_to?"), 1, ID2SYM(method));
|
307
308
|
return RTEST(value);
|
308
309
|
}
|
310
|
+
*/
|
309
311
|
|
310
312
|
/*
|
311
313
|
|
@@ -327,7 +329,7 @@ static VALUE
|
|
327
329
|
rb_cpBodySetVelocityFunc(int argc, VALUE *argv, VALUE self) {
|
328
330
|
VALUE block;
|
329
331
|
cpBody * body = BODY(self);
|
330
|
-
rb_scan_args(argc, argv, "&", &block);
|
332
|
+
rb_scan_args(argc, argv, "0&", &block);
|
331
333
|
// Restore defaults if no block
|
332
334
|
if (NIL_P(block)) {
|
333
335
|
body->velocity_func = cpBodyUpdateVelocity; //Default;
|
@@ -374,19 +376,11 @@ rb_cpBodySetData(VALUE self, VALUE val) {
|
|
374
376
|
return val;
|
375
377
|
}
|
376
378
|
|
377
|
-
|
378
|
-
static VALUE
|
379
|
-
rb_cpBodySlew(VALUE self, VALUE pos, VALUE dt) {
|
380
|
-
cpBodySlew(BODY(self), *VGET(pos), NUM2DBL(dt));
|
381
|
-
return self;
|
382
|
-
}
|
383
|
-
|
384
379
|
static VALUE
|
385
380
|
rb_cpBodyKineticEnergy(VALUE self) {
|
386
381
|
return DBL2NUM(cpBodyKineticEnergy(BODY(self)));
|
387
382
|
}
|
388
383
|
|
389
|
-
|
390
384
|
void
|
391
385
|
Init_cpBody(void) {
|
392
386
|
c_cpBody = rb_define_class_under(m_Chipmunk, "Body", rb_cObject);
|
@@ -459,7 +453,6 @@ Init_cpBody(void) {
|
|
459
453
|
|
460
454
|
rb_define_method(c_cpBody, "update_velocity", rb_cpBodyUpdateVelocity, 3);
|
461
455
|
rb_define_method(c_cpBody, "update_position", rb_cpBodyUpdatePosition, 1);
|
462
|
-
rb_define_method(c_cpBody, "slew", rb_cpBodySlew, 2);
|
463
456
|
|
464
457
|
rb_define_method(c_cpBody, "static?", rb_cpBodyIsStatic, 0);
|
465
458
|
rb_define_method(c_cpBody, "rogue?", rb_cpBodyIsRogue, 0);
|
@@ -34,7 +34,7 @@ VALUE m_cpConstraint;
|
|
34
34
|
{ CONSTRAINT(self)->member = NUM2DBL(value); return value;}
|
35
35
|
|
36
36
|
CONSTRAINT_GETSET_FUNCS(maxForce)
|
37
|
-
CONSTRAINT_GETSET_FUNCS(
|
37
|
+
CONSTRAINT_GETSET_FUNCS(errorBias)
|
38
38
|
CONSTRAINT_GETSET_FUNCS(maxBias)
|
39
39
|
|
40
40
|
|
@@ -65,7 +65,12 @@ CONSTRAINT_GETSET_FUNCS(maxBias)
|
|
65
65
|
|
66
66
|
#define ALLOC_TEMPLATE(s, alloc) \
|
67
67
|
static VALUE rb_ ## s ## _alloc(VALUE klass) \
|
68
|
-
{
|
68
|
+
{ \
|
69
|
+
s * rb_cpStruct = alloc; \
|
70
|
+
VALUE rb_constraint = Data_Wrap_Struct(klass, NULL, cpConstraintFree, rb_cpStruct); \
|
71
|
+
rb_cpStruct->constraint.data = (void*)rb_constraint; \
|
72
|
+
return rb_constraint; \
|
73
|
+
}
|
69
74
|
|
70
75
|
ALLOC_TEMPLATE(cpPinJoint, cpPinJointAlloc())
|
71
76
|
|
@@ -139,9 +144,22 @@ MAKE_FLT_ACCESSORS(cpGearJoint, Ratio);
|
|
139
144
|
ALLOC_TEMPLATE(cpPivotJoint, cpPivotJointAlloc())
|
140
145
|
|
141
146
|
static VALUE
|
142
|
-
rb_cpPivotJoint_init(
|
147
|
+
rb_cpPivotJoint_init(int argc, VALUE *argv, VALUE self) {
|
148
|
+
/* rb_cpPivotJoint_init(VALUE self, VALUE a, VALUE b, VALUE anchr1, VALUE anchr2) { */
|
149
|
+
VALUE a, b, pivotOrAnchr1, anchr2;
|
150
|
+
|
151
|
+
rb_scan_args(argc, argv, "31", &a, &b, &pivotOrAnchr1, &anchr2);
|
152
|
+
|
143
153
|
cpPivotJoint *joint = (cpPivotJoint *)CONSTRAINT(self);
|
144
|
-
|
154
|
+
|
155
|
+
if(NIL_P(anchr2)) {
|
156
|
+
cpVect a1 = (a ? cpBodyWorld2Local(BODY(a), *VGET(pivotOrAnchr1)) : *VGET(pivotOrAnchr1));
|
157
|
+
cpVect a2 = (b ? cpBodyWorld2Local(BODY(b), *VGET(pivotOrAnchr1)) : *VGET(pivotOrAnchr1));
|
158
|
+
cpPivotJointInit(joint, BODY(a), BODY(b), a1, a2);
|
159
|
+
} else {
|
160
|
+
cpPivotJointInit(joint, BODY(a), BODY(b), *VGET(pivotOrAnchr1), *VGET(anchr2));
|
161
|
+
}
|
162
|
+
|
145
163
|
rb_iv_set(self, "@body_a", a);
|
146
164
|
rb_iv_set(self, "@body_b", b);
|
147
165
|
|
@@ -213,9 +231,9 @@ rb_cpGrooveJoint_init(VALUE self, VALUE a, VALUE b, VALUE grv_a, VALUE grv_b, VA
|
|
213
231
|
return self;
|
214
232
|
}
|
215
233
|
|
234
|
+
MAKE_VEC_ACCESSORS(cpGrooveJoint, Anchr2)
|
216
235
|
MAKE_VEC_ACCESSORS(cpGrooveJoint, GrooveA)
|
217
236
|
MAKE_VEC_ACCESSORS(cpGrooveJoint, GrooveB)
|
218
|
-
MAKE_VEC_ACCESSORS(cpGrooveJoint, Anchr2)
|
219
237
|
|
220
238
|
|
221
239
|
ALLOC_TEMPLATE(cpRatchetJoint, cpRatchetJointAlloc())
|
@@ -239,6 +257,118 @@ rb_cpConstraintGetImpulse(VALUE self) {
|
|
239
257
|
return rb_float_new(cpConstraintGetImpulse(CONSTRAINT(self)));
|
240
258
|
}
|
241
259
|
|
260
|
+
static void
|
261
|
+
rb_cpConstraintPreSolveFunc(cpConstraint *constraint, cpSpace *space) {
|
262
|
+
VALUE rb_constraint = (VALUE)constraint->data;
|
263
|
+
VALUE callback_block = rb_iv_get(rb_constraint, "@_cp_pre_solve");
|
264
|
+
|
265
|
+
ID call_id = rb_intern("call");
|
266
|
+
int arity = NUM2INT(rb_funcall(callback_block, rb_intern("arity"), 0));
|
267
|
+
switch(arity) {
|
268
|
+
case 1:
|
269
|
+
rb_funcall(callback_block, call_id, 1, (VALUE)space->data);
|
270
|
+
break;
|
271
|
+
default:
|
272
|
+
rb_funcall(callback_block, call_id, 0);
|
273
|
+
}
|
274
|
+
|
275
|
+
}
|
276
|
+
|
277
|
+
static void
|
278
|
+
rb_cpConstraintPostSolveFunc(cpConstraint *constraint, cpSpace *space) {
|
279
|
+
VALUE rb_constraint = (VALUE)constraint->data;
|
280
|
+
VALUE callback_block = rb_iv_get(rb_constraint, "@_cp_post_solve");
|
281
|
+
|
282
|
+
ID call_id = rb_intern("call");
|
283
|
+
int arity = NUM2INT(rb_funcall(callback_block, rb_intern("arity"), 0));
|
284
|
+
switch(arity) {
|
285
|
+
case 1:
|
286
|
+
rb_funcall(callback_block, call_id, 1, (VALUE)space->data);
|
287
|
+
break;
|
288
|
+
default:
|
289
|
+
rb_funcall(callback_block, call_id, 0);
|
290
|
+
}
|
291
|
+
|
292
|
+
}
|
293
|
+
|
294
|
+
static cpFloat
|
295
|
+
rb_cpDampedSpringForceFunc(cpConstraint *constraint, cpFloat dist) {
|
296
|
+
VALUE rb_constraint = (VALUE)constraint->data;
|
297
|
+
VALUE callback_block = rb_iv_get(rb_constraint, "@_cp_force_func");
|
298
|
+
|
299
|
+
ID call_id = rb_intern("call");
|
300
|
+
int arity = NUM2INT(rb_funcall(callback_block, rb_intern("arity"), 0));
|
301
|
+
switch(arity) {
|
302
|
+
case 1:
|
303
|
+
// TODO is NUM2DBL what I want here?
|
304
|
+
return NUM2DBL(rb_funcall(callback_block, call_id, 1, rb_float_new(dist)));
|
305
|
+
default:
|
306
|
+
return NUM2DBL(rb_funcall(callback_block, call_id, 0));
|
307
|
+
}
|
308
|
+
|
309
|
+
}
|
310
|
+
|
311
|
+
static cpFloat
|
312
|
+
rb_cpDampedRotarySpringTorqueFunc(cpConstraint *constraint, cpFloat relativeAngle) {
|
313
|
+
VALUE rb_constraint = (VALUE)constraint->data;
|
314
|
+
VALUE callback_block = rb_iv_get(rb_constraint, "@_cp_torque_func");
|
315
|
+
|
316
|
+
ID call_id = rb_intern("call");
|
317
|
+
int arity = NUM2INT(rb_funcall(callback_block, rb_intern("arity"), 0));
|
318
|
+
switch(arity) {
|
319
|
+
case 1:
|
320
|
+
// TODO is NUM2DBL what I want here?
|
321
|
+
return NUM2DBL(rb_funcall(callback_block, call_id, 1, rb_float_new(relativeAngle)));
|
322
|
+
default:
|
323
|
+
return NUM2DBL(rb_funcall(callback_block, call_id, 0));
|
324
|
+
}
|
325
|
+
|
326
|
+
}
|
327
|
+
|
328
|
+
static VALUE
|
329
|
+
rb_cpConstraintSetPreSolve(int argc, VALUE * argv, VALUE self) {
|
330
|
+
VALUE callback_block;
|
331
|
+
rb_scan_args(argc, argv, "0&", &callback_block);
|
332
|
+
rb_iv_set(self, "@_cp_pre_solve", callback_block);
|
333
|
+
|
334
|
+
cpConstraintSetPreSolveFunc(CONSTRAINT(self), rb_cpConstraintPreSolveFunc);
|
335
|
+
|
336
|
+
return Qnil;
|
337
|
+
}
|
338
|
+
|
339
|
+
static VALUE
|
340
|
+
rb_cpConstraintSetPostSolve(int argc, VALUE * argv, VALUE self) {
|
341
|
+
VALUE callback_block;
|
342
|
+
rb_scan_args(argc, argv, "0&", &callback_block);
|
343
|
+
rb_iv_set(self, "@_cp_post_solve", callback_block);
|
344
|
+
|
345
|
+
cpConstraintSetPostSolveFunc(CONSTRAINT(self), rb_cpConstraintPostSolveFunc);
|
346
|
+
|
347
|
+
return Qnil;
|
348
|
+
}
|
349
|
+
|
350
|
+
static VALUE
|
351
|
+
rb_cpDampedSpringSetForceFunc(int argc, VALUE * argv, VALUE self) {
|
352
|
+
VALUE callback_block;
|
353
|
+
rb_scan_args(argc, argv, "0&", &callback_block);
|
354
|
+
rb_iv_set(self, "@_cp_force_func", callback_block);
|
355
|
+
|
356
|
+
cpDampedSpringSetSpringForceFunc(CONSTRAINT(self), rb_cpDampedSpringForceFunc);
|
357
|
+
|
358
|
+
return Qnil;
|
359
|
+
}
|
360
|
+
|
361
|
+
static VALUE
|
362
|
+
rb_cpDampedRotarySpringSetTorqueFunc(int argc, VALUE * argv, VALUE self) {
|
363
|
+
VALUE callback_block;
|
364
|
+
rb_scan_args(argc, argv, "0&", &callback_block);
|
365
|
+
rb_iv_set(self, "@_cp_torque_func", callback_block);
|
366
|
+
|
367
|
+
cpDampedRotarySpringSetSpringTorqueFunc(CONSTRAINT(self), rb_cpDampedRotarySpringTorqueFunc);
|
368
|
+
|
369
|
+
return Qnil;
|
370
|
+
}
|
371
|
+
|
242
372
|
|
243
373
|
#define STRINGIFY(v) # v
|
244
374
|
#define ACCESSOR_METHODS(s, m, name) \
|
@@ -262,17 +392,19 @@ Init_cpConstraint(void) {
|
|
262
392
|
rb_define_attr(m_cpConstraint, "body_b", 1, 0);
|
263
393
|
rb_define_method(m_cpConstraint, "max_force", rb_cpConstraint_get_maxForce, 0);
|
264
394
|
rb_define_method(m_cpConstraint, "max_force=", rb_cpConstraint_set_maxForce, 1);
|
265
|
-
rb_define_method(m_cpConstraint, "
|
266
|
-
rb_define_method(m_cpConstraint, "
|
395
|
+
rb_define_method(m_cpConstraint, "error_bias", rb_cpConstraint_get_errorBias, 0);
|
396
|
+
rb_define_method(m_cpConstraint, "error_bias=", rb_cpConstraint_set_errorBias, 1);
|
267
397
|
rb_define_method(m_cpConstraint, "max_bias", rb_cpConstraint_get_maxBias, 0);
|
268
398
|
rb_define_method(m_cpConstraint, "max_bias=", rb_cpConstraint_set_maxBias, 1);
|
269
399
|
rb_define_method(m_cpConstraint, "impulse", rb_cpConstraintGetImpulse, 0);
|
270
|
-
|
400
|
+
rb_define_method(m_cpConstraint, "pre_solve", rb_cpConstraintSetPreSolve, -1);
|
401
|
+
rb_define_method(m_cpConstraint, "post_solve", rb_cpConstraintSetPostSolve, -1);
|
271
402
|
|
272
403
|
VALUE c_cpDampedRotarySpring = make_class("DampedRotarySpring", rb_cpDampedRotarySpring_alloc, rb_cpDampedRotarySpring_init, 5);
|
273
404
|
ACCESSOR_METHODS(cpDampedRotarySpring, RestAngle, rest_angle)
|
274
405
|
ACCESSOR_METHODS(cpDampedRotarySpring, Stiffness, stiffness)
|
275
406
|
ACCESSOR_METHODS(cpDampedRotarySpring, Damping, damping)
|
407
|
+
rb_define_method(c_cpDampedRotarySpring, "torque", rb_cpDampedRotarySpringSetTorqueFunc, -1);
|
276
408
|
|
277
409
|
VALUE c_cpDampedSpring = make_class("DampedSpring", rb_cpDampedSpring_alloc, rb_cpDampedSpring_init, 7);
|
278
410
|
ACCESSOR_METHODS(cpDampedSpring, Anchr1, anchr1)
|
@@ -280,6 +412,7 @@ Init_cpConstraint(void) {
|
|
280
412
|
ACCESSOR_METHODS(cpDampedSpring, RestLength, rest_length)
|
281
413
|
ACCESSOR_METHODS(cpDampedSpring, Stiffness, stiffness)
|
282
414
|
ACCESSOR_METHODS(cpDampedSpring, Damping, damping)
|
415
|
+
rb_define_method(c_cpDampedSpring, "force", rb_cpDampedSpringSetForceFunc, -1);
|
283
416
|
|
284
417
|
VALUE c_cpGearJoint = make_class("GearJoint", rb_cpGearJoint_alloc, rb_cpGearJoint_init, 4);
|
285
418
|
ACCESSOR_METHODS(cpGearJoint, Phase, phase)
|
@@ -287,6 +420,8 @@ Init_cpConstraint(void) {
|
|
287
420
|
|
288
421
|
VALUE c_cpGrooveJoint = make_class("GrooveJoint", rb_cpGrooveJoint_alloc, rb_cpGrooveJoint_init, 5);
|
289
422
|
ACCESSOR_METHODS(cpGrooveJoint, Anchr2, anchr2)
|
423
|
+
ACCESSOR_METHODS(cpGrooveJoint, GrooveA, groove_a)
|
424
|
+
ACCESSOR_METHODS(cpGrooveJoint, GrooveB, groove_b)
|
290
425
|
|
291
426
|
|
292
427
|
VALUE c_cpPinJoint = make_class("PinJoint", rb_cpPinJoint_alloc, rb_cpPinJoint_init, 4);
|
@@ -295,7 +430,7 @@ Init_cpConstraint(void) {
|
|
295
430
|
ACCESSOR_METHODS(cpPinJoint, Dist, dist)
|
296
431
|
|
297
432
|
|
298
|
-
VALUE c_cpPivotJoint = make_class("PivotJoint", rb_cpPivotJoint_alloc, rb_cpPivotJoint_init,
|
433
|
+
VALUE c_cpPivotJoint = make_class("PivotJoint", rb_cpPivotJoint_alloc, rb_cpPivotJoint_init, -1);
|
299
434
|
ACCESSOR_METHODS(cpPivotJoint, Anchr1, anchr1)
|
300
435
|
ACCESSOR_METHODS(cpPivotJoint, Anchr2, anchr2)
|
301
436
|
|