21 #ifndef CHIPMUNK_PRIVATE_H
22 #define CHIPMUNK_PRIVATE_H
24 #error Cannot include chipmunk_private.h after chipmunk.h.
27 #define CP_ALLOW_PRIVATE_ACCESS 1
28 #include "chipmunk/chipmunk.h"
30 #define CP_HASH_COEF (3344921057ul)
31 #define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
34 #define MAGIC_EPSILON 1e-5
48 void cpArrayPush(
cpArray *arr,
void *
object);
50 void cpArrayDeleteObj(
cpArray *arr,
void *obj);
53 void cpArrayFreeEach(
cpArray *arr,
void (freeFunc)(
void*));
58 typedef cpBool (*cpHashSetEqlFunc)(
void *ptr,
void *elt);
59 typedef void *(*cpHashSetTransFunc)(
void *ptr,
void *data);
61 cpHashSet *cpHashSetNew(
int size, cpHashSetEqlFunc eqlFunc);
62 void cpHashSetSetDefaultValue(cpHashSet *
set,
void *default_value);
64 void cpHashSetFree(cpHashSet *
set);
66 int cpHashSetCount(cpHashSet *
set);
67 void *cpHashSetInsert(cpHashSet *
set,
cpHashValue hash,
void *ptr, cpHashSetTransFunc trans,
void *data);
68 void *cpHashSetRemove(cpHashSet *
set,
cpHashValue hash,
void *ptr);
69 void *cpHashSetFind(cpHashSet *
set,
cpHashValue hash,
void *ptr);
71 typedef void (*cpHashSetIteratorFunc)(
void *elt,
void *data);
72 void cpHashSetEach(cpHashSet *
set, cpHashSetIteratorFunc func,
void *data);
74 typedef cpBool (*cpHashSetFilterFunc)(
void *elt,
void *data);
75 void cpHashSetFilter(cpHashSet *
set, cpHashSetFilterFunc func,
void *data);
132 void cpBodyAccumulateMassFromShapes(
cpBody *body);
144 enum cpArbiterState {
146 CP_ARBITER_STATE_FIRST_COLLISION,
148 CP_ARBITER_STATE_NORMAL,
151 CP_ARBITER_STATE_IGNORE,
153 CP_ARBITER_STATE_CACHED,
155 CP_ARBITER_STATE_INVALIDATED,
205 enum cpArbiterState state;
213 return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
221 void cpArbiterApplyImpulse(
cpArbiter *arb);
233 typedef enum cpShapeType{
241 typedef void (*cpShapeDestroyImpl)(
cpShape *shape);
250 cpShapeCacheDataImpl cacheData;
251 cpShapeDestroyImpl destroy;
252 cpShapePointQueryImpl pointQuery;
253 cpShapeSegmentQueryImpl segmentQuery;
295 cpVect a_tangent, b_tangent;
302 #define CP_POLY_SHAPE_INLINE_ALLOC 6
324 return (shape->prev || (shape->body && shape->body->shapeList == shape));
342 cpFloat t = (-qb - cpfsqrt(det))/(qa);
343 if(0.0f<= t && t <= 1.0f){
367 void cpLoopIndexes(
const cpVect *verts,
int count,
int *start,
int *end);
374 typedef void (*cpConstraintApplyCachedImpulseImpl)(
cpConstraint *constraint,
cpFloat dt_coef);
379 cpConstraintPreStepImpl preStep;
380 cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
381 cpConstraintApplyImpulseImpl applyImpulse;
382 cpConstraintGetImpulseImpl getImpulse;
444 cpVect grv_n, grv_a, grv_b;
542 return cpvsub(v2_sum, v1_sum);
547 return cpvdot(relative_velocity(a, b, r1, r2), n);
552 body->CP_PRIVATE(v) =
cpvadd(body->CP_PRIVATE(v),
cpvmult(j, body->CP_PRIVATE(m_inv)));
553 body->CP_PRIVATE(w) += body->CP_PRIVATE(i_inv)*
cpvcross(r, j);
559 apply_impulse(a,
cpvneg(j), r1);
560 apply_impulse(b, j, r2);
566 body->CP_PRIVATE(v_bias) =
cpvadd(body->CP_PRIVATE(v_bias),
cpvmult(j, body->CP_PRIVATE(m_inv)));
567 body->CP_PRIVATE(w_bias) += body->CP_PRIVATE(i_inv)*
cpvcross(r, j);
573 apply_bias_impulse(a,
cpvneg(j), r1);
574 apply_bias_impulse(b, j, r2);
581 return body->CP_PRIVATE(m_inv) + body->CP_PRIVATE(i_inv)*rcn*rcn;
587 cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
588 cpAssertSoft(value != 0.0,
"Unsolvable collision or constraint.");
596 cpFloat m_sum = a->CP_PRIVATE(m_inv) + b->CP_PRIVATE(m_inv);
599 cpFloat k11 = m_sum, k12 = 0.0f;
600 cpFloat k21 = 0.0f, k22 = m_sum;
603 cpFloat a_i_inv = a->CP_PRIVATE(i_inv);
604 cpFloat r1xsq = r1.x * r1.x * a_i_inv;
605 cpFloat r1ysq = r1.y * r1.y * a_i_inv;
606 cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
607 k11 += r1ysq; k12 += r1nxy;
608 k21 += r1nxy; k22 += r1xsq;
611 cpFloat b_i_inv = b->CP_PRIVATE(i_inv);
612 cpFloat r2xsq = r2.x * r2.x * b_i_inv;
613 cpFloat r2ysq = r2.y * r2.y * b_i_inv;
614 cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
615 k11 += r2ysq; k12 += r2nxy;
616 k21 += r2nxy; k22 += r2xsq;
619 cpFloat det = k11*k22 - k12*k21;
620 cpAssertSoft(det != 0.0,
"Unsolvable constraint.");
624 k22*det_inv, -k12*det_inv,
625 -k21*det_inv, k11*det_inv
632 return 1.0f - cpfpow(errorBias, dt);
638 typedef struct cpContactBufferHeader cpContactBufferHeader;
639 typedef void (*cpSpaceArbiterApplyImpulseFunc)(
cpArbiter *arb);
665 cpSpatialIndex *staticShapes;
666 cpSpatialIndex *dynamicShapes;
671 cpContactBufferHeader *contactBuffersHead;
672 cpHashSet *cachedArbiters;
679 cpHashSet *collisionHandlers;
689 #define cpAssertSpaceUnlocked(space) \
690 cpAssertHard(!space->locked, \
691 "This operation cannot be done safely during a call to cpSpaceStep() or during a query. " \
692 "Put these calls into a post-step callback." \
701 void cpSpacePushFreshContactBuffer(
cpSpace *space);
703 void cpSpacePushContacts(
cpSpace *space,
int count);
717 void cpSpaceLock(
cpSpace *space);
723 const cpShape *a = arb->a, *b = arb->b;
724 const cpShape *shape_pair[] = {a, b};
726 cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
727 cpArrayDeleteObj(space->arbiters, arb);
736 void cpShapeUpdateFunc(
cpShape *shape,
void *unused);
745 return (node->a == body ? node->next_a : node->next_b);
748 #define CP_BODY_FOREACH_CONSTRAINT(bdy, var)\
749 for(cpConstraint *var = bdy->constraintList; var; var = cpConstraintNext(var, bdy))
754 return (node->body_a == body ? node->thread_a.next : node->thread_b.next);
757 #define CP_BODY_FOREACH_ARBITER(bdy, var)\
758 for(cpArbiter *var = bdy->arbiterList; var; var = cpArbiterNext(var, bdy))
760 #define CP_BODY_FOREACH_SHAPE(body, var)\
761 for(cpShape *var = body->shapeList; var; var = var->next)
763 #define CP_BODY_FOREACH_COMPONENT(root, var)\
764 for(cpBody *var = root; var; var = var->sleeping.next)