22 #ifndef CHIPMUNK_PRIVATE_H
23 #define CHIPMUNK_PRIVATE_H
25 #include "chipmunk/chipmunk.h"
26 #include "chipmunk/chipmunk_structs.h"
28 #define CP_HASH_COEF (3344921057ul)
29 #define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
32 #define MAGIC_EPSILON 1e-5
41 void cpArrayPush(
cpArray *arr,
void *
object);
43 void cpArrayDeleteObj(
cpArray *arr,
void *obj);
46 void cpArrayFreeEach(
cpArray *arr,
void (freeFunc)(
void*));
51 typedef cpBool (*cpHashSetEqlFunc)(
const void *ptr,
const void *elt);
52 typedef void *(*cpHashSetTransFunc)(
const void *ptr,
void *data);
54 cpHashSet *cpHashSetNew(
int size, cpHashSetEqlFunc eqlFunc);
55 void cpHashSetSetDefaultValue(cpHashSet *
set,
void *default_value);
57 void cpHashSetFree(cpHashSet *
set);
59 int cpHashSetCount(cpHashSet *
set);
60 const void *cpHashSetInsert(cpHashSet *
set,
cpHashValue hash,
const void *ptr, cpHashSetTransFunc trans,
void *data);
61 const void *cpHashSetRemove(cpHashSet *
set,
cpHashValue hash,
const void *ptr);
62 const void *cpHashSetFind(cpHashSet *
set,
cpHashValue hash,
const void *ptr);
64 typedef void (*cpHashSetIteratorFunc)(
void *elt,
void *data);
65 void cpHashSetEach(cpHashSet *
set, cpHashSetIteratorFunc func,
void *data);
67 typedef cpBool (*cpHashSetFilterFunc)(
void *elt,
void *data);
68 void cpHashSetFilter(cpHashSet *
set, cpHashSetFilterFunc func,
void *data);
77 void cpBodyAccumulateMassFromShapes(
cpBody *body);
94 return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
102 void cpArbiterApplyImpulse(
cpArbiter *arb);
114 return (shape->prev || (shape->body && shape->body->shapeList == shape));
132 cpFloat t = (-qb - cpfsqrt(det))/(qa);
133 if(0.0f<= t && t <= 1.0f){
157 void cpLoopIndexes(
const cpVect *verts,
int count,
int *start,
int *end);
177 return cpvsub(v2_sum, v1_sum);
182 return cpvdot(relative_velocity(a, b, r1, r2), n);
188 body->w += body->i_inv*
cpvcross(r, j);
194 apply_impulse(a,
cpvneg(j), r1);
195 apply_impulse(b, j, r2);
201 body->v_bias =
cpvadd(body->v_bias,
cpvmult(j, body->m_inv));
202 body->w_bias += body->i_inv*
cpvcross(r, j);
208 apply_bias_impulse(a,
cpvneg(j), r1);
209 apply_bias_impulse(b, j, r2);
216 return body->m_inv + body->i_inv*rcn*rcn;
222 cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
223 cpAssertSoft(value != 0.0,
"Unsolvable collision or constraint.");
231 cpFloat m_sum = a->m_inv + b->m_inv;
234 cpFloat k11 = m_sum, k12 = 0.0f;
235 cpFloat k21 = 0.0f, k22 = m_sum;
239 cpFloat r1xsq = r1.x * r1.x * a_i_inv;
240 cpFloat r1ysq = r1.y * r1.y * a_i_inv;
241 cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
242 k11 += r1ysq; k12 += r1nxy;
243 k21 += r1nxy; k22 += r1xsq;
247 cpFloat r2xsq = r2.x * r2.x * b_i_inv;
248 cpFloat r2ysq = r2.y * r2.y * b_i_inv;
249 cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
250 k11 += r2ysq; k12 += r2nxy;
251 k21 += r2nxy; k22 += r2xsq;
254 cpFloat det = k11*k22 - k12*k21;
255 cpAssertSoft(det != 0.0,
"Unsolvable constraint.");
259 k22*det_inv, -k12*det_inv,
260 -k21*det_inv, k11*det_inv
267 return 1.0f - cpfpow(errorBias, dt);
273 #define cpAssertSpaceUnlocked(space) \
274 cpAssertHard(!space->locked, \
275 "This operation cannot be done safely during a call to cpSpaceStep() or during a query. " \
276 "Put these calls into a post-step callback." \
285 void cpSpacePushFreshContactBuffer(
cpSpace *space);
287 void cpSpacePushContacts(
cpSpace *space,
int count);
295 void cpSpaceLock(
cpSpace *space);
301 const cpShape *a = arb->a, *b = arb->b;
302 const cpShape *shape_pair[] = {a, b};
304 cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
305 cpArrayDeleteObj(space->arbiters, arb);
314 void cpShapeUpdateFunc(
cpShape *shape,
void *unused);
323 return (node->a == body ? node->next_a : node->next_b);
326 #define CP_BODY_FOREACH_CONSTRAINT(bdy, var)\
327 for(cpConstraint *var = bdy->constraintList; var; var = cpConstraintNext(var, bdy))
332 return (node->body_a == body ? node->thread_a.next : node->thread_b.next);
335 #define CP_BODY_FOREACH_ARBITER(bdy, var)\
336 for(cpArbiter *var = bdy->arbiterList; var; var = cpArbiterNext(var, bdy))
338 #define CP_BODY_FOREACH_SHAPE(body, var)\
339 for(cpShape *var = body->shapeList; var; var = var->next)
341 #define CP_BODY_FOREACH_COMPONENT(root, var)\
342 for(cpBody *var = root; var; var = var->sleeping.next)