// TODO this function needs more commenting. static void processContactComponents(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(bodies->num/8); 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->private_a->body, arb->private_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); body->node.next = NULL; body->node.parent = NULL; body->node.rank = 0; } while((body = next) != root); } else { cpBody *body = root, *next; do { next = body->node.next; for(cpShape *shape = body->shapesList; shape; shape = shape->next){ removeShapeRaw(shape, space->activeShapes); addShapeRaw(shape, space->staticShapes); } } while((body = next) != root); cpArrayPush(space->sleepingComponents, root); } } space->bodies = newBodies; cpArrayFree(bodies); cpArrayFree(rogueBodies); cpArrayFree(components); }
cpFloat Body::kineticEnergy() { return cpBodyKineticEnergy(body); }