1 /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 #include "chipmunk/chipmunk_private.h"
24 //MARK: Post Step Callback Functions
27 cpSpaceGetPostStepCallback(cpSpace *space, void *key)
29 cpArray *arr = space->postStepCallbacks;
30 for(int i=0; i<arr->num; i++){
31 cpPostStepCallback *callback = (cpPostStepCallback *)arr->arr[i];
32 if(callback && callback->key == key) return callback;
38 static void PostStepDoNothing(cpSpace *space, void *obj, void *data){}
41 cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data)
43 cpAssertWarn(space->locked,
44 "Adding a post-step callback when the space is not locked is unnecessary. "
45 "Post-step callbacks will not called until the end of the next call to cpSpaceStep() or the next query.");
47 if(!cpSpaceGetPostStepCallback(space, key)){
48 cpPostStepCallback *callback = (cpPostStepCallback *)cpcalloc(1, sizeof(cpPostStepCallback));
49 callback->func = (func ? func : PostStepDoNothing);
51 callback->data = data;
53 cpArrayPush(space->postStepCallbacks, callback);
60 //MARK: Locking Functions
63 cpSpaceLock(cpSpace *space)
69 cpSpaceUnlock(cpSpace *space, cpBool runPostStep)
72 cpAssertHard(space->locked >= 0, "Internal Error: Space lock underflow.");
74 if(space->locked == 0){
75 cpArray *waking = space->rousedBodies;
77 for(int i=0, count=waking->num; i<count; i++){
78 cpSpaceActivateBody(space, (cpBody *)waking->arr[i]);
79 waking->arr[i] = NULL;
84 if(space->locked == 0 && runPostStep && !space->skipPostStep){
85 space->skipPostStep = cpTrue;
87 cpArray *arr = space->postStepCallbacks;
88 for(int i=0; i<arr->num; i++){
89 cpPostStepCallback *callback = (cpPostStepCallback *)arr->arr[i];
90 cpPostStepFunc func = callback->func;
92 // Mark the func as NULL in case calling it calls cpSpaceRunPostStepCallbacks() again.
93 // TODO: need more tests around this case I think.
94 callback->func = NULL;
95 if(func) func(space, callback->key, callback->data);
102 space->skipPostStep = cpFalse;
107 //MARK: Contact Buffer Functions
109 struct cpContactBufferHeader {
111 cpContactBufferHeader *next;
112 unsigned int numContacts;
115 #define CP_CONTACTS_BUFFER_SIZE ((CP_BUFFER_BYTES - sizeof(cpContactBufferHeader))/sizeof(struct cpContact))
116 typedef struct cpContactBuffer {
117 cpContactBufferHeader header;
118 struct cpContact contacts[CP_CONTACTS_BUFFER_SIZE];
121 static cpContactBufferHeader *
122 cpSpaceAllocContactBuffer(cpSpace *space)
124 cpContactBuffer *buffer = (cpContactBuffer *)cpcalloc(1, sizeof(cpContactBuffer));
125 cpArrayPush(space->allocatedBuffers, buffer);
126 return (cpContactBufferHeader *)buffer;
129 static cpContactBufferHeader *
130 cpContactBufferHeaderInit(cpContactBufferHeader *header, cpTimestamp stamp, cpContactBufferHeader *splice)
132 header->stamp = stamp;
133 header->next = (splice ? splice->next : header);
134 header->numContacts = 0;
140 cpSpacePushFreshContactBuffer(cpSpace *space)
142 cpTimestamp stamp = space->stamp;
144 cpContactBufferHeader *head = space->contactBuffersHead;
147 // No buffers have been allocated, make one
148 space->contactBuffersHead = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, NULL);
149 } else if(stamp - head->next->stamp > space->collisionPersistence){
150 // The tail buffer is available, rotate the ring
151 cpContactBufferHeader *tail = head->next;
152 space->contactBuffersHead = cpContactBufferHeaderInit(tail, stamp, tail);
154 // Allocate a new buffer and push it into the ring
155 cpContactBufferHeader *buffer = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, head);
156 space->contactBuffersHead = head->next = buffer;
162 cpContactBufferGetArray(cpSpace *space)
164 if(space->contactBuffersHead->numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){
165 // contact buffer could overflow on the next collision, push a fresh one.
166 cpSpacePushFreshContactBuffer(space);
169 cpContactBufferHeader *head = space->contactBuffersHead;
170 return ((cpContactBuffer *)head)->contacts + head->numContacts;
174 cpSpacePushContacts(cpSpace *space, int count)
176 cpAssertHard(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal Error: Contact buffer overflow!");
177 space->contactBuffersHead->numContacts += count;
181 cpSpacePopContacts(cpSpace *space, int count){
182 space->contactBuffersHead->numContacts -= count;
185 //MARK: Collision Detection Functions
188 cpSpaceArbiterSetTrans(cpShape **shapes, cpSpace *space)
190 if(space->pooledArbiters->num == 0){
191 // arbiter pool is exhausted, make more
192 int count = CP_BUFFER_BYTES/sizeof(cpArbiter);
193 cpAssertHard(count, "Internal Error: Buffer size too small.");
195 cpArbiter *buffer = (cpArbiter *)cpcalloc(1, CP_BUFFER_BYTES);
196 cpArrayPush(space->allocatedBuffers, buffer);
198 for(int i=0; i<count; i++) cpArrayPush(space->pooledArbiters, buffer + i);
201 return cpArbiterInit((cpArbiter *)cpArrayPop(space->pooledArbiters), shapes[0], shapes[1]);
205 QueryRejectConstraint(cpBody *a, cpBody *b)
207 CP_BODY_FOREACH_CONSTRAINT(a, constraint){
209 !constraint->collideBodies && (
210 (constraint->a == a && constraint->b == b) ||
211 (constraint->a == b && constraint->b == a)
220 QueryReject(cpShape *a, cpShape *b)
223 // BBoxes must overlap
224 !cpBBIntersects(a->bb, b->bb)
225 // Don't collide shapes attached to the same body.
226 || a->body == b->body
227 // Don't collide shapes that are filtered.
228 || cpShapeFilterReject(a->filter, b->filter)
229 // Don't collide bodies if they have a constraint with collideBodies == cpFalse.
230 || QueryRejectConstraint(a->body, b->body)
234 // Callback from the spatial hash.
236 cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space)
238 // Reject any of the simple cases
239 if(QueryReject(a,b)) return id;
241 // Narrow-phase collision detection.
242 struct cpCollisionInfo info = cpCollide(a, b, id, cpContactBufferGetArray(space));
244 if(info.count == 0) return info.id; // Shapes are not colliding.
245 cpSpacePushContacts(space, info.count);
247 // Get an arbiter from space->arbiterSet for the two shapes.
248 // This is where the persistant contact magic comes from.
249 const cpShape *shape_pair[] = {info.a, info.b};
250 cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)info.a, (cpHashValue)info.b);
251 cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->cachedArbiters, arbHashID, shape_pair, (cpHashSetTransFunc)cpSpaceArbiterSetTrans, space);
252 cpArbiterUpdate(arb, &info, space);
254 cpCollisionHandler *handler = arb->handler;
256 // Call the begin function first if it's the first step
257 if(arb->state == CP_ARBITER_STATE_FIRST_COLLISION && !handler->beginFunc(arb, space, handler->userData)){
258 cpArbiterIgnore(arb); // permanently ignore the collision until separation
262 // Ignore the arbiter if it has been flagged
263 (arb->state != CP_ARBITER_STATE_IGNORE) &&
265 handler->preSolveFunc(arb, space, handler->userData) &&
266 // Check (again) in case the pre-solve() callback called cpArbiterIgnored().
267 arb->state != CP_ARBITER_STATE_IGNORE &&
268 // Process, but don't add collisions for sensors.
269 !(a->sensor || b->sensor) &&
270 // Don't process collisions between two infinite mass bodies.
271 // This includes collisions between two kinematic bodies, or a kinematic body and a static body.
272 !(a->body->m == INFINITY && b->body->m == INFINITY)
274 cpArrayPush(space->arbiters, arb);
276 cpSpacePopContacts(space, info.count);
278 arb->contacts = NULL;
281 // Normally arbiters are set as used after calling the post-solve callback.
282 // However, post-solve() callbacks are not called for sensors or arbiters rejected from pre-solve.
283 if(arb->state != CP_ARBITER_STATE_IGNORE) arb->state = CP_ARBITER_STATE_NORMAL;
286 // Time stamp the arbiter so we know it was used recently.
287 arb->stamp = space->stamp;
291 // Hashset filter func to throw away old arbiters.
293 cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space)
295 cpTimestamp ticks = space->stamp - arb->stamp;
297 cpBody *a = arb->body_a, *b = arb->body_b;
299 // TODO: should make an arbiter state for this so it doesn't require filtering arbiters for dangling body pointers on body removal.
300 // Preserve arbiters on sensors and rejected arbiters for sleeping objects.
301 // This prevents errant separate callbacks from happenening.
303 (cpBodyGetType(a) == CP_BODY_TYPE_STATIC || cpBodyIsSleeping(a)) &&
304 (cpBodyGetType(b) == CP_BODY_TYPE_STATIC || cpBodyIsSleeping(b))
309 // Arbiter was used last frame, but not this one
310 if(ticks >= 1 && arb->state != CP_ARBITER_STATE_CACHED){
311 arb->state = CP_ARBITER_STATE_CACHED;
312 cpCollisionHandler *handler = arb->handler;
313 handler->separateFunc(arb, space, handler->userData);
316 if(ticks >= space->collisionPersistence){
317 arb->contacts = NULL;
320 cpArrayPush(space->pooledArbiters, arb);
327 //MARK: All Important cpSpaceStep() Function
330 cpShapeUpdateFunc(cpShape *shape, void *unused)
332 cpShapeCacheBB(shape);
336 cpSpaceStep(cpSpace *space, cpFloat dt)
338 // don't step if the timestep is 0!
339 if(dt == 0.0f) return;
343 cpFloat prev_dt = space->curr_dt;
346 cpArray *bodies = space->dynamicBodies;
347 cpArray *constraints = space->constraints;
348 cpArray *arbiters = space->arbiters;
350 // Reset and empty the arbiter lists.
351 for(int i=0; i<arbiters->num; i++){
352 cpArbiter *arb = (cpArbiter *)arbiters->arr[i];
353 arb->state = CP_ARBITER_STATE_NORMAL;
355 // If both bodies are awake, unthread the arbiter from the contact graph.
356 if(!cpBodyIsSleeping(arb->body_a) && !cpBodyIsSleeping(arb->body_b)){
357 cpArbiterUnthread(arb);
362 cpSpaceLock(space); {
363 // Integrate positions
364 for(int i=0; i<bodies->num; i++){
365 cpBody *body = (cpBody *)bodies->arr[i];
366 body->position_func(body, dt);
369 // Find colliding pairs.
370 cpSpacePushFreshContactBuffer(space);
371 cpSpatialIndexEach(space->dynamicShapes, (cpSpatialIndexIteratorFunc)cpShapeUpdateFunc, NULL);
372 cpSpatialIndexReindexQuery(space->dynamicShapes, (cpSpatialIndexQueryFunc)cpSpaceCollideShapes, space);
373 } cpSpaceUnlock(space, cpFalse);
375 // Rebuild the contact graph (and detect sleeping components if sleeping is enabled)
376 cpSpaceProcessComponents(space, dt);
378 cpSpaceLock(space); {
379 // Clear out old cached arbiters and call separate callbacks
380 cpHashSetFilter(space->cachedArbiters, (cpHashSetFilterFunc)cpSpaceArbiterSetFilter, space);
382 // Prestep the arbiters and constraints.
383 cpFloat slop = space->collisionSlop;
384 cpFloat biasCoef = 1.0f - cpfpow(space->collisionBias, dt);
385 for(int i=0; i<arbiters->num; i++){
386 cpArbiterPreStep((cpArbiter *)arbiters->arr[i], dt, slop, biasCoef);
389 for(int i=0; i<constraints->num; i++){
390 cpConstraint *constraint = (cpConstraint *)constraints->arr[i];
392 cpConstraintPreSolveFunc preSolve = constraint->preSolve;
393 if(preSolve) preSolve(constraint, space);
395 constraint->klass->preStep(constraint, dt);
398 // Integrate velocities.
399 cpFloat damping = cpfpow(space->damping, dt);
400 cpVect gravity = space->gravity;
401 for(int i=0; i<bodies->num; i++){
402 cpBody *body = (cpBody *)bodies->arr[i];
403 body->velocity_func(body, gravity, damping, dt);
406 // Apply cached impulses
407 cpFloat dt_coef = (prev_dt == 0.0f ? 0.0f : dt/prev_dt);
408 for(int i=0; i<arbiters->num; i++){
409 cpArbiterApplyCachedImpulse((cpArbiter *)arbiters->arr[i], dt_coef);
412 for(int i=0; i<constraints->num; i++){
413 cpConstraint *constraint = (cpConstraint *)constraints->arr[i];
414 constraint->klass->applyCachedImpulse(constraint, dt_coef);
417 // Run the impulse solver.
418 for(int i=0; i<space->iterations; i++){
419 for(int j=0; j<arbiters->num; j++){
420 cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j]);
423 for(int j=0; j<constraints->num; j++){
424 cpConstraint *constraint = (cpConstraint *)constraints->arr[j];
425 constraint->klass->applyImpulse(constraint, dt);
429 // Run the constraint post-solve callbacks
430 for(int i=0; i<constraints->num; i++){
431 cpConstraint *constraint = (cpConstraint *)constraints->arr[i];
433 cpConstraintPostSolveFunc postSolve = constraint->postSolve;
434 if(postSolve) postSolve(constraint, space);
437 // run the post-solve callbacks
438 for(int i=0; i<arbiters->num; i++){
439 cpArbiter *arb = (cpArbiter *) arbiters->arr[i];
441 cpCollisionHandler *handler = arb->handler;
442 handler->postSolveFunc(arb, space, handler->userData);
444 } cpSpaceUnlock(space, cpTrue);