chipmunk 5.3.4.5 → 6.1.3.0.rc1
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.
- 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
|
|