void cpSpaceDestroy(cpSpace *space) { cpSpaceHashFree(space->staticShapes); cpSpaceHashFree(space->activeShapes); cpArrayFree(space->bodies); cpArrayFree(space->sleepingComponents); cpArrayFree(space->constraints); cpHashSetFree(space->contactSet); cpArrayFree(space->arbiters); cpArrayFree(space->pooledArbiters); if(space->allocatedBuffers){ cpArrayEach(space->allocatedBuffers, freeWrap, NULL); cpArrayFree(space->allocatedBuffers); } if(space->postStepCallbacks){ cpHashSetEach(space->postStepCallbacks, freeWrap, NULL); cpHashSetFree(space->postStepCallbacks); } if(space->collFuncSet){ cpHashSetEach(space->collFuncSet, freeWrap, NULL); cpHashSetFree(space->collFuncSet); } }
// TODO this function needs more commenting. void cpSpaceProcessComponents(cpSpace *space, cpFloat dt) { cpArray *bodies = space->bodies; cpArray *newBodies = cpArrayNew(bodies->num); cpArray *rogueBodies = cpArrayNew(16); cpArray *arbiters = space->arbiters; cpArray *constraints = space->constraints; cpArray *components = cpArrayNew(space->sleepingComponents->num); cpFloat dv = space->idleSpeedThreshold; cpFloat dvsq = (dv ? dv*dv : cpvdot(space->gravity, space->gravity)*dt*dt); // update idling for(int i=0; i<bodies->num; i++){ cpBody *body = (cpBody*)bodies->arr[i]; cpFloat thresh = (dvsq ? body->m*dvsq : 0.0f); body->node.idleTime = (cpBodyKineticEnergy(body) > thresh ? 0.0f : body->node.idleTime + dt); } // iterate graph edges and build forests for(int i=0; i<arbiters->num; i++){ cpArbiter *arb = (cpArbiter*)arbiters->arr[i]; mergeBodies(space, components, rogueBodies, arb->a->body, arb->b->body); } for(int j=0; j<constraints->num; j++){ cpConstraint *constraint = (cpConstraint *)constraints->arr[j]; mergeBodies(space, components, rogueBodies, constraint->a, constraint->b); } // iterate bodies and add them to their components for(int i=0; i<bodies->num; i++) addToComponent((cpBody*)bodies->arr[i], components); for(int i=0; i<rogueBodies->num; i++) addToComponent((cpBody*)rogueBodies->arr[i], components); // iterate components, copy or deactivate for(int i=0; i<components->num; i++){ cpBody *root = (cpBody*)components->arr[i]; if(componentActive(root, space->sleepTimeThreshold)){ cpBody *body = root, *next; do { next = body->node.next; if(!cpBodyIsRogue(body)) cpArrayPush(newBodies, body); cpComponentNode node = {NULL, NULL, 0, body->node.idleTime}; body->node = node; } while((body = next) != root); } else { cpBody *body = root, *next; do { next = body->node.next; for(cpShape *shape = body->shapesList; shape; shape = shape->next){ cpSpaceHashRemove(space->activeShapes, shape, shape->hashid); cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb); } } while((body = next) != root); cpArrayPush(space->sleepingComponents, root); } } space->bodies = newBodies; cpArrayFree(bodies); cpArrayFree(rogueBodies); cpArrayFree(components); }