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/cpBody.c
CHANGED
@@ -19,11 +19,10 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
#include <stdlib.h>
|
23
22
|
#include <float.h>
|
24
|
-
#include <stdarg.h>
|
25
23
|
|
26
24
|
#include "chipmunk_private.h"
|
25
|
+
#include "constraints/util.h"
|
27
26
|
|
28
27
|
// initialized in cpInitChipmunk()
|
29
28
|
cpBody cpStaticBodySingleton;
|
@@ -31,41 +30,42 @@ cpBody cpStaticBodySingleton;
|
|
31
30
|
cpBody*
|
32
31
|
cpBodyAlloc(void)
|
33
32
|
{
|
34
|
-
return (cpBody *)
|
33
|
+
return (cpBody *)cpcalloc(1, sizeof(cpBody));
|
35
34
|
}
|
36
35
|
|
37
|
-
|
38
|
-
cpBodyPositionFunc cpBodyUpdatePositionDefault = cpBodyUpdatePosition;
|
39
|
-
|
40
|
-
cpBody*
|
36
|
+
cpBody *
|
41
37
|
cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
|
42
38
|
{
|
43
|
-
body->
|
44
|
-
body->
|
39
|
+
body->space = NULL;
|
40
|
+
body->shapeList = NULL;
|
41
|
+
body->arbiterList = NULL;
|
42
|
+
body->constraintList = NULL;
|
43
|
+
|
44
|
+
body->velocity_func = cpBodyUpdateVelocity;
|
45
|
+
body->position_func = cpBodyUpdatePosition;
|
46
|
+
|
47
|
+
cpComponentNode node = {NULL, NULL, 0.0f};
|
48
|
+
body->node = node;
|
45
49
|
|
46
|
-
cpBodySetMass(body, m);
|
47
|
-
cpBodySetMoment(body, i);
|
48
|
-
|
49
50
|
body->p = cpvzero;
|
50
51
|
body->v = cpvzero;
|
51
52
|
body->f = cpvzero;
|
52
53
|
|
53
|
-
cpBodySetAngle(body, 0.0f);
|
54
54
|
body->w = 0.0f;
|
55
55
|
body->t = 0.0f;
|
56
56
|
|
57
57
|
body->v_bias = cpvzero;
|
58
58
|
body->w_bias = 0.0f;
|
59
59
|
|
60
|
-
body->data = NULL;
|
61
60
|
body->v_limit = (cpFloat)INFINITY;
|
62
61
|
body->w_limit = (cpFloat)INFINITY;
|
63
62
|
|
64
|
-
body->
|
65
|
-
body->shapesList = NULL;
|
63
|
+
body->data = NULL;
|
66
64
|
|
67
|
-
|
68
|
-
body
|
65
|
+
// Setters must be called after full initialization so the sanity checks don't assert on garbage data.
|
66
|
+
cpBodySetMass(body, m);
|
67
|
+
cpBodySetMoment(body, i);
|
68
|
+
cpBodySetAngle(body, 0.0f);
|
69
69
|
|
70
70
|
return body;
|
71
71
|
}
|
@@ -86,7 +86,7 @@ cpBodyInitStatic(cpBody *body)
|
|
86
86
|
}
|
87
87
|
|
88
88
|
cpBody *
|
89
|
-
cpBodyNewStatic()
|
89
|
+
cpBodyNewStatic(void)
|
90
90
|
{
|
91
91
|
return cpBodyInitStatic(cpBodyAlloc());
|
92
92
|
}
|
@@ -102,32 +102,131 @@ cpBodyFree(cpBody *body)
|
|
102
102
|
}
|
103
103
|
}
|
104
104
|
|
105
|
+
static void cpv_assert_nan(cpVect v, const char *message){cpAssertSoft(v.x == v.x && v.y == v.y, message);}
|
106
|
+
static void cpv_assert_infinite(cpVect v, const char *message){cpAssertSoft(cpfabs(v.x) != INFINITY && cpfabs(v.y) != INFINITY, message);}
|
107
|
+
static void cpv_assert_sane(cpVect v, const char *message){cpv_assert_nan(v, message); cpv_assert_infinite(v, message);}
|
108
|
+
|
109
|
+
#ifdef __cplusplus
|
110
|
+
extern "C" {
|
111
|
+
#endif
|
112
|
+
|
113
|
+
void
|
114
|
+
cpBodySanityCheck(cpBody *body)
|
115
|
+
{
|
116
|
+
cpAssertSoft(body->m == body->m && body->m_inv == body->m_inv, "Body's mass is invalid.");
|
117
|
+
cpAssertSoft(body->i == body->i && body->i_inv == body->i_inv, "Body's moment is invalid.");
|
118
|
+
|
119
|
+
cpv_assert_sane(body->p, "Body's position is invalid.");
|
120
|
+
cpv_assert_sane(body->v, "Body's velocity is invalid.");
|
121
|
+
cpv_assert_sane(body->f, "Body's force is invalid.");
|
122
|
+
|
123
|
+
cpAssertSoft(body->a == body->a && cpfabs(body->a) != INFINITY, "Body's angle is invalid.");
|
124
|
+
cpAssertSoft(body->w == body->w && cpfabs(body->w) != INFINITY, "Body's angular velocity is invalid.");
|
125
|
+
cpAssertSoft(body->t == body->t && cpfabs(body->t) != INFINITY, "Body's torque is invalid.");
|
126
|
+
|
127
|
+
cpv_assert_sane(body->rot, "Body's rotation vector is invalid.");
|
128
|
+
|
129
|
+
cpAssertSoft(body->v_limit == body->v_limit, "Body's velocity limit is invalid.");
|
130
|
+
cpAssertSoft(body->w_limit == body->w_limit, "Body's angular velocity limit is invalid.");
|
131
|
+
}
|
132
|
+
|
133
|
+
#ifdef __cplusplus
|
134
|
+
}
|
135
|
+
#endif
|
136
|
+
|
105
137
|
void
|
106
138
|
cpBodySetMass(cpBody *body, cpFloat mass)
|
107
139
|
{
|
140
|
+
cpAssertHard(mass > 0.0f, "Mass must be positive and non-zero.");
|
141
|
+
|
142
|
+
cpBodyActivate(body);
|
108
143
|
body->m = mass;
|
109
144
|
body->m_inv = 1.0f/mass;
|
145
|
+
cpBodyAssertSane(body);
|
110
146
|
}
|
111
147
|
|
112
148
|
void
|
113
149
|
cpBodySetMoment(cpBody *body, cpFloat moment)
|
114
150
|
{
|
151
|
+
cpAssertHard(moment > 0.0f, "Moment of Inertia must be positive and non-zero.");
|
152
|
+
|
153
|
+
cpBodyActivate(body);
|
115
154
|
body->i = moment;
|
116
155
|
body->i_inv = 1.0f/moment;
|
156
|
+
cpBodyAssertSane(body);
|
117
157
|
}
|
118
158
|
|
119
159
|
void
|
120
|
-
|
160
|
+
cpBodyAddShape(cpBody *body, cpShape *shape)
|
161
|
+
{
|
162
|
+
cpShape *next = body->shapeList;
|
163
|
+
if(next) next->prev = shape;
|
164
|
+
|
165
|
+
shape->next = next;
|
166
|
+
body->shapeList = shape;
|
167
|
+
}
|
168
|
+
|
169
|
+
void
|
170
|
+
cpBodyRemoveShape(cpBody *body, cpShape *shape)
|
171
|
+
{
|
172
|
+
cpShape *prev = shape->prev;
|
173
|
+
cpShape *next = shape->next;
|
174
|
+
|
175
|
+
if(prev){
|
176
|
+
prev->next = next;
|
177
|
+
} else {
|
178
|
+
body->shapeList = next;
|
179
|
+
}
|
180
|
+
|
181
|
+
if(next){
|
182
|
+
next->prev = prev;
|
183
|
+
}
|
184
|
+
|
185
|
+
shape->prev = NULL;
|
186
|
+
shape->next = NULL;
|
187
|
+
}
|
188
|
+
|
189
|
+
static cpConstraint *
|
190
|
+
filterConstraints(cpConstraint *node, cpBody *body, cpConstraint *filter)
|
191
|
+
{
|
192
|
+
if(node == filter){
|
193
|
+
return cpConstraintNext(node, body);
|
194
|
+
} else if(node->a == body){
|
195
|
+
node->next_a = filterConstraints(node->next_a, body, filter);
|
196
|
+
} else {
|
197
|
+
node->next_b = filterConstraints(node->next_b, body, filter);
|
198
|
+
}
|
199
|
+
|
200
|
+
return node;
|
201
|
+
}
|
202
|
+
|
203
|
+
void
|
204
|
+
cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint)
|
205
|
+
{
|
206
|
+
body->constraintList = filterConstraints(body->constraintList, body, constraint);
|
207
|
+
}
|
208
|
+
|
209
|
+
void
|
210
|
+
cpBodySetPos(cpBody *body, cpVect pos)
|
211
|
+
{
|
212
|
+
cpBodyActivate(body);
|
213
|
+
body->p = pos;
|
214
|
+
cpBodyAssertSane(body);
|
215
|
+
}
|
216
|
+
|
217
|
+
static inline void
|
218
|
+
setAngle(cpBody *body, cpFloat angle)
|
121
219
|
{
|
122
220
|
body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);
|
123
221
|
body->rot = cpvforangle(angle);
|
222
|
+
cpBodyAssertSane(body);
|
124
223
|
}
|
125
224
|
|
126
225
|
void
|
127
|
-
|
226
|
+
cpBodySetAngle(cpBody *body, cpFloat angle)
|
128
227
|
{
|
129
|
-
|
130
|
-
body
|
228
|
+
cpBodyActivate(body);
|
229
|
+
setAngle(body, angle);
|
131
230
|
}
|
132
231
|
|
133
232
|
void
|
@@ -137,21 +236,26 @@ cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
|
|
137
236
|
|
138
237
|
cpFloat w_limit = body->w_limit;
|
139
238
|
body->w = cpfclamp(body->w*damping + body->t*body->i_inv*dt, -w_limit, w_limit);
|
239
|
+
|
240
|
+
cpBodySanityCheck(body);
|
140
241
|
}
|
141
242
|
|
142
243
|
void
|
143
244
|
cpBodyUpdatePosition(cpBody *body, cpFloat dt)
|
144
245
|
{
|
145
246
|
body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));
|
146
|
-
|
247
|
+
setAngle(body, body->a + (body->w + body->w_bias)*dt);
|
147
248
|
|
148
249
|
body->v_bias = cpvzero;
|
149
250
|
body->w_bias = 0.0f;
|
251
|
+
|
252
|
+
cpBodySanityCheck(body);
|
150
253
|
}
|
151
254
|
|
152
255
|
void
|
153
256
|
cpBodyResetForces(cpBody *body)
|
154
257
|
{
|
258
|
+
cpBodyActivate(body);
|
155
259
|
body->f = cpvzero;
|
156
260
|
body->t = 0.0f;
|
157
261
|
}
|
@@ -159,34 +263,68 @@ cpBodyResetForces(cpBody *body)
|
|
159
263
|
void
|
160
264
|
cpBodyApplyForce(cpBody *body, cpVect force, cpVect r)
|
161
265
|
{
|
266
|
+
cpBodyActivate(body);
|
162
267
|
body->f = cpvadd(body->f, force);
|
163
268
|
body->t += cpvcross(r, force);
|
164
269
|
}
|
165
270
|
|
166
271
|
void
|
167
|
-
|
272
|
+
cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r)
|
168
273
|
{
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));
|
174
|
-
cpFloat dist = cpvlength(delta);
|
175
|
-
cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;
|
176
|
-
|
177
|
-
cpFloat f_spring = (dist - rlen)*k;
|
274
|
+
cpBodyActivate(body);
|
275
|
+
apply_impulse(body, j, r);
|
276
|
+
}
|
178
277
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
278
|
+
static inline cpVect
|
279
|
+
cpBodyGetVelAtPoint(cpBody *body, cpVect r)
|
280
|
+
{
|
281
|
+
return cpvadd(body->v, cpvmult(cpvperp(r), body->w));
|
282
|
+
}
|
283
|
+
|
284
|
+
cpVect
|
285
|
+
cpBodyGetVelAtWorldPoint(cpBody *body, cpVect point)
|
286
|
+
{
|
287
|
+
return cpBodyGetVelAtPoint(body, cpvsub(point, body->p));
|
288
|
+
}
|
289
|
+
|
290
|
+
cpVect
|
291
|
+
cpBodyGetVelAtLocalPoint(cpBody *body, cpVect point)
|
292
|
+
{
|
293
|
+
return cpBodyGetVelAtPoint(body, cpvrotate(point, body->rot));
|
294
|
+
}
|
295
|
+
|
296
|
+
void
|
297
|
+
cpBodyEachShape(cpBody *body, cpBodyShapeIteratorFunc func, void *data)
|
298
|
+
{
|
299
|
+
cpShape *shape = body->shapeList;
|
300
|
+
while(shape){
|
301
|
+
cpShape *next = shape->next;
|
302
|
+
func(body, shape, data);
|
303
|
+
shape = next;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
void
|
308
|
+
cpBodyEachConstraint(cpBody *body, cpBodyConstraintIteratorFunc func, void *data)
|
309
|
+
{
|
310
|
+
cpConstraint *constraint = body->constraintList;
|
311
|
+
while(constraint){
|
312
|
+
cpConstraint *next = cpConstraintNext(constraint, body);
|
313
|
+
func(body, constraint, data);
|
314
|
+
constraint = next;
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
void
|
319
|
+
cpBodyEachArbiter(cpBody *body, cpBodyArbiterIteratorFunc func, void *data)
|
320
|
+
{
|
321
|
+
cpArbiter *arb = body->arbiterList;
|
322
|
+
while(arb){
|
323
|
+
cpArbiter *next = cpArbiterNext(arb, body);
|
324
|
+
|
325
|
+
arb->swappedColl = (body == arb->body_b);
|
326
|
+
func(body, arb, data);
|
327
|
+
|
328
|
+
arb = next;
|
329
|
+
}
|
192
330
|
}
|
data/ext/chipmunk/cpBody.h
CHANGED
@@ -19,194 +19,213 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
22
|
+
/// @defgroup cpBody cpBody
|
23
|
+
/// Chipmunk's rigid body type. Rigid bodies hold the physical properties of an object like
|
24
|
+
/// it's mass, and position and velocity of it's center of gravity. They don't have an shape on their own.
|
25
|
+
/// They are given a shape by creating collision shapes (cpShape) that point to the body.
|
26
|
+
/// @{
|
27
|
+
|
28
|
+
/// Rigid body velocity update function type.
|
29
|
+
typedef void (*cpBodyVelocityFunc)(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
30
|
+
/// Rigid body position update function type.
|
31
|
+
typedef void (*cpBodyPositionFunc)(cpBody *body, cpFloat dt);
|
32
|
+
|
33
|
+
/// Used internally to track information on the collision graph.
|
34
|
+
/// @private
|
35
35
|
typedef struct cpComponentNode {
|
36
|
-
|
37
|
-
|
38
|
-
int rank;
|
36
|
+
cpBody *root;
|
37
|
+
cpBody *next;
|
39
38
|
cpFloat idleTime;
|
40
39
|
} cpComponentNode;
|
41
40
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
|
41
|
+
/// Chipmunk's rigid body struct.
|
42
|
+
struct cpBody {
|
43
|
+
/// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
|
46
44
|
cpBodyVelocityFunc velocity_func;
|
47
45
|
|
48
|
-
|
46
|
+
/// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)
|
49
47
|
cpBodyPositionFunc position_func;
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
cpFloat
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
cpFloat i
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
cpVect p
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
49
|
+
/// Mass of the body.
|
50
|
+
/// Must agree with cpBody.m_inv! Use cpBodySetMass() when changing the mass for this reason.
|
51
|
+
cpFloat m;
|
52
|
+
/// Mass inverse.
|
53
|
+
cpFloat m_inv;
|
54
|
+
|
55
|
+
/// Moment of inertia of the body.
|
56
|
+
/// Must agree with cpBody.i_inv! Use cpBodySetMoment() when changing the moment for this reason.
|
57
|
+
cpFloat i;
|
58
|
+
/// Moment of inertia inverse.
|
59
|
+
cpFloat i_inv;
|
60
|
+
|
61
|
+
/// Position of the rigid body's center of gravity.
|
62
|
+
cpVect p;
|
63
|
+
/// Velocity of the rigid body's center of gravity.
|
64
|
+
cpVect v;
|
65
|
+
/// Force acting on the rigid body's center of gravity.
|
66
|
+
cpVect f;
|
67
|
+
|
68
|
+
/// Rotation of the body around it's center of gravity in radians.
|
69
|
+
/// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
|
70
|
+
cpFloat a;
|
71
|
+
/// Angular velocity of the body around it's center of gravity in radians/second.
|
72
|
+
cpFloat w;
|
73
|
+
/// Torque applied to the body around it's center of gravity.
|
74
|
+
cpFloat t;
|
75
|
+
|
76
|
+
/// Cached unit length vector representing the angle of the body.
|
77
|
+
/// Used for fast rotations using cpvrotate().
|
72
78
|
cpVect rot;
|
73
79
|
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
/// User definable data pointer.
|
81
|
+
/// Generally this points to your the game object class so you can access it
|
82
|
+
/// when given a cpBody reference in a callback.
|
77
83
|
cpDataPointer data;
|
78
84
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
cpFloat
|
83
|
-
|
84
|
-
// *** Internally Used Fields
|
85
|
+
/// Maximum velocity allowed when updating the velocity.
|
86
|
+
cpFloat v_limit;
|
87
|
+
/// Maximum rotational rate (in radians/second) allowed when updating the angular velocity.
|
88
|
+
cpFloat w_limit;
|
85
89
|
|
86
|
-
// Velocity bias values used when solving penetrations and correcting constraints.
|
87
90
|
CP_PRIVATE(cpVect v_bias);
|
88
91
|
CP_PRIVATE(cpFloat w_bias);
|
89
92
|
|
90
|
-
|
91
|
-
CP_PRIVATE(struct cpSpace *space);
|
93
|
+
CP_PRIVATE(cpSpace *space);
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
-
CP_PRIVATE(
|
95
|
+
CP_PRIVATE(cpShape *shapeList);
|
96
|
+
CP_PRIVATE(cpArbiter *arbiterList);
|
97
|
+
CP_PRIVATE(cpConstraint *constraintList);
|
96
98
|
|
97
|
-
// Used by cpSpaceStep() to store contact graph information.
|
98
99
|
CP_PRIVATE(cpComponentNode node);
|
99
|
-
}
|
100
|
+
};
|
100
101
|
|
101
|
-
|
102
|
-
cpBody
|
103
|
-
|
104
|
-
cpBody *
|
102
|
+
/// Allocate a cpBody.
|
103
|
+
cpBody* cpBodyAlloc(void);
|
104
|
+
/// Initialize a cpBody.
|
105
|
+
cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
|
106
|
+
/// Allocate and initialize a cpBody.
|
107
|
+
cpBody* cpBodyNew(cpFloat m, cpFloat i);
|
105
108
|
|
106
|
-
|
107
|
-
cpBody *
|
109
|
+
/// Initialize a static cpBody.
|
110
|
+
cpBody* cpBodyInitStatic(cpBody *body);
|
111
|
+
/// Allocate and initialize a static cpBody.
|
112
|
+
cpBody* cpBodyNewStatic(void);
|
108
113
|
|
114
|
+
/// Destroy a cpBody.
|
109
115
|
void cpBodyDestroy(cpBody *body);
|
116
|
+
/// Destroy and free a cpBody.
|
110
117
|
void cpBodyFree(cpBody *body);
|
111
118
|
|
112
|
-
|
119
|
+
/// Check that the properties of a body is sane. (Only in debug mode)
|
120
|
+
#ifdef NDEBUG
|
121
|
+
#define cpBodyAssertSane(body)
|
122
|
+
#else
|
123
|
+
void cpBodySanityCheck(cpBody *body);
|
124
|
+
#define cpBodyAssertSane(body) cpBodySanityCheck(body)
|
125
|
+
#endif
|
126
|
+
|
127
|
+
// Defined in cpSpace.c
|
128
|
+
/// Wake up a sleeping or idle body.
|
113
129
|
void cpBodyActivate(cpBody *body);
|
130
|
+
/// Wake up any sleeping or idle bodies touching a static body.
|
131
|
+
void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
114
132
|
|
115
|
-
|
116
|
-
// defined in cpSpaceComponent.c
|
133
|
+
/// Force a body to fall asleep immediately.
|
117
134
|
void cpBodySleep(cpBody *body);
|
135
|
+
/// Force a body to fall asleep immediately along with other bodies in a group.
|
118
136
|
void cpBodySleepWithGroup(cpBody *body, cpBody *group);
|
119
137
|
|
120
|
-
|
121
|
-
cpBodyIsSleeping(const cpBody *body)
|
138
|
+
/// Returns true if the body is sleeping.
|
139
|
+
static inline cpBool cpBodyIsSleeping(const cpBody *body)
|
122
140
|
{
|
123
|
-
return (CP_PRIVATE(body->node).
|
141
|
+
return (CP_PRIVATE(body->node).root != ((cpBody*)0));
|
124
142
|
}
|
125
143
|
|
126
|
-
|
127
|
-
cpBodyIsStatic(const cpBody *body)
|
144
|
+
/// Returns true if the body is static.
|
145
|
+
static inline cpBool cpBodyIsStatic(const cpBody *body)
|
128
146
|
{
|
129
147
|
return CP_PRIVATE(body->node).idleTime == INFINITY;
|
130
148
|
}
|
131
149
|
|
132
|
-
|
133
|
-
|
150
|
+
/// Returns true if the body has not been added to a space.
|
151
|
+
/// Note: Static bodies are a subtype of rogue bodies.
|
152
|
+
static inline cpBool cpBodyIsRogue(const cpBody *body)
|
134
153
|
{
|
135
|
-
return (body->CP_PRIVATE(space) == ((
|
154
|
+
return (body->CP_PRIVATE(space) == ((cpSpace*)0));
|
136
155
|
}
|
137
156
|
|
138
157
|
|
139
|
-
#define
|
158
|
+
#define CP_DefineBodyStructGetter(type, member, name) \
|
140
159
|
static inline type cpBodyGet##name(const cpBody *body){return body->member;}
|
141
160
|
|
142
|
-
#define
|
143
|
-
static inline void \
|
144
|
-
cpBodySet##name(cpBody *body, const type value){ \
|
161
|
+
#define CP_DefineBodyStructSetter(type, member, name) \
|
162
|
+
static inline void cpBodySet##name(cpBody *body, const type value){ \
|
145
163
|
cpBodyActivate(body); \
|
146
164
|
body->member = value; \
|
147
|
-
|
165
|
+
cpBodyAssertSane(body); \
|
166
|
+
}
|
148
167
|
|
149
|
-
#define
|
150
|
-
|
151
|
-
|
168
|
+
#define CP_DefineBodyStructProperty(type, member, name) \
|
169
|
+
CP_DefineBodyStructGetter(type, member, name) \
|
170
|
+
CP_DefineBodyStructSetter(type, member, name)
|
152
171
|
|
172
|
+
// TODO add to docs
|
173
|
+
CP_DefineBodyStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
153
174
|
|
154
|
-
|
155
|
-
|
175
|
+
CP_DefineBodyStructGetter(cpFloat, m, Mass)
|
176
|
+
/// Set the mass of a body.
|
156
177
|
void cpBodySetMass(cpBody *body, cpFloat m);
|
157
178
|
|
158
|
-
|
179
|
+
CP_DefineBodyStructGetter(cpFloat, i, Moment)
|
180
|
+
/// Set the moment of a body.
|
159
181
|
void cpBodySetMoment(cpBody *body, cpFloat i);
|
160
182
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
183
|
+
CP_DefineBodyStructGetter(cpVect, p, Pos)
|
184
|
+
/// Set the position of a body.
|
185
|
+
void cpBodySetPos(cpBody *body, cpVect pos);
|
186
|
+
CP_DefineBodyStructProperty(cpVect, v, Vel)
|
187
|
+
CP_DefineBodyStructProperty(cpVect, f, Force)
|
188
|
+
CP_DefineBodyStructGetter(cpFloat, a, Angle)
|
189
|
+
/// Set the angle of a body.
|
166
190
|
void cpBodySetAngle(cpBody *body, cpFloat a);
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);
|
176
|
-
|
177
|
-
// Default Integration functions.
|
191
|
+
CP_DefineBodyStructProperty(cpFloat, w, AngVel)
|
192
|
+
CP_DefineBodyStructProperty(cpFloat, t, Torque)
|
193
|
+
CP_DefineBodyStructGetter(cpVect, rot, Rot)
|
194
|
+
CP_DefineBodyStructProperty(cpFloat, v_limit, VelLimit)
|
195
|
+
CP_DefineBodyStructProperty(cpFloat, w_limit, AngVelLimit)
|
196
|
+
CP_DefineBodyStructProperty(cpDataPointer, data, UserData)
|
197
|
+
|
198
|
+
/// Default Integration functions.
|
178
199
|
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
179
200
|
void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
|
180
201
|
|
181
|
-
|
182
|
-
static inline cpVect
|
183
|
-
cpBodyLocal2World(const cpBody *body, const cpVect v)
|
202
|
+
/// Convert body relative/local coordinates to absolute/world coordinates.
|
203
|
+
static inline cpVect cpBodyLocal2World(const cpBody *body, const cpVect v)
|
184
204
|
{
|
185
205
|
return cpvadd(body->p, cpvrotate(v, body->rot));
|
186
206
|
}
|
187
207
|
|
188
|
-
|
189
|
-
static inline cpVect
|
190
|
-
cpBodyWorld2Local(const cpBody *body, const cpVect v)
|
208
|
+
/// Convert body absolute/world coordinates to relative/local coordinates.
|
209
|
+
static inline cpVect cpBodyWorld2Local(const cpBody *body, const cpVect v)
|
191
210
|
{
|
192
211
|
return cpvunrotate(cpvsub(v, body->p), body->rot);
|
193
212
|
}
|
194
213
|
|
195
|
-
|
196
|
-
static inline void
|
197
|
-
cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r)
|
198
|
-
{
|
199
|
-
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
200
|
-
body->w += body->i_inv*cpvcross(r, j);
|
201
|
-
}
|
202
|
-
|
203
|
-
// Zero the forces on a body.
|
214
|
+
/// Set the forces and torque or a body to zero.
|
204
215
|
void cpBodyResetForces(cpBody *body);
|
205
|
-
|
216
|
+
/// Apply an force (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
|
206
217
|
void cpBodyApplyForce(cpBody *body, const cpVect f, const cpVect r);
|
218
|
+
/// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
|
219
|
+
void cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r);
|
220
|
+
|
221
|
+
/// Get the velocity on a body (in world units) at a point on the body in world coordinates.
|
222
|
+
cpVect cpBodyGetVelAtWorldPoint(cpBody *body, cpVect point);
|
223
|
+
/// Get the velocity on a body (in world units) at a point on the body in local coordinates.
|
224
|
+
cpVect cpBodyGetVelAtLocalPoint(cpBody *body, cpVect point);
|
225
|
+
|
207
226
|
|
208
|
-
|
209
|
-
cpBodyKineticEnergy(const cpBody *body)
|
227
|
+
/// Get the kinetic energy of a body.
|
228
|
+
static inline cpFloat cpBodyKineticEnergy(const cpBody *body)
|
210
229
|
{
|
211
230
|
// Need to do some fudging to avoid NaNs
|
212
231
|
cpFloat vsq = cpvdot(body->v, body->v);
|
@@ -214,6 +233,19 @@ cpBodyKineticEnergy(const cpBody *body)
|
|
214
233
|
return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);
|
215
234
|
}
|
216
235
|
|
217
|
-
|
218
|
-
|
219
|
-
|
236
|
+
/// Body/shape iterator callback function type.
|
237
|
+
typedef void (*cpBodyShapeIteratorFunc)(cpBody *body, cpShape *shape, void *data);
|
238
|
+
/// Call @c func once for each shape attached to @c body and added to the space.
|
239
|
+
void cpBodyEachShape(cpBody *body, cpBodyShapeIteratorFunc func, void *data);
|
240
|
+
|
241
|
+
/// Body/constraint iterator callback function type.
|
242
|
+
typedef void (*cpBodyConstraintIteratorFunc)(cpBody *body, cpConstraint *constraint, void *data);
|
243
|
+
/// Call @c func once for each constraint attached to @c body and added to the space.
|
244
|
+
void cpBodyEachConstraint(cpBody *body, cpBodyConstraintIteratorFunc func, void *data);
|
245
|
+
|
246
|
+
/// Body/arbiter iterator callback function type.
|
247
|
+
typedef void (*cpBodyArbiterIteratorFunc)(cpBody *body, cpArbiter *arbiter, void *data);
|
248
|
+
/// Call @c func once for each arbiter that is currently active on the body.
|
249
|
+
void cpBodyEachArbiter(cpBody *body, cpBodyArbiterIteratorFunc func, void *data);
|
250
|
+
|
251
|
+
///@}
|