| 218 | } |
| 219 | |
| 220 | void |
| 221 | cpSpaceProcessComponents(cpSpace *space, cpFloat dt) |
| 222 | { |
| 223 | cpBool sleep = (space->sleepTimeThreshold != INFINITY); |
| 224 | cpArray *bodies = space->dynamicBodies; |
| 225 | |
| 226 | #ifndef NDEBUG |
| 227 | for(int i=0; i<bodies->num; i++){ |
| 228 | cpBody *body = (cpBody*)bodies->arr[i]; |
| 229 | |
| 230 | cpAssertSoft(body->sleeping.next == NULL, "Internal Error: Dangling next pointer detected in contact graph."); |
| 231 | cpAssertSoft(body->sleeping.root == NULL, "Internal Error: Dangling root pointer detected in contact graph."); |
| 232 | } |
| 233 | #endif |
| 234 | |
| 235 | // Calculate the kinetic energy of all the bodies. |
| 236 | if(sleep){ |
| 237 | cpFloat dv = space->idleSpeedThreshold; |
| 238 | cpFloat dvsq = (dv ? dv*dv : cpvlengthsq(space->gravity)*dt*dt); |
| 239 | |
| 240 | // update idling and reset component nodes |
| 241 | for(int i=0; i<bodies->num; i++){ |
| 242 | cpBody *body = (cpBody*)bodies->arr[i]; |
| 243 | |
| 244 | // TODO should make a separate array for kinematic bodies. |
| 245 | if(cpBodyGetType(body) != CP_BODY_TYPE_DYNAMIC) continue; |
| 246 | |
| 247 | // Need to deal with infinite mass objects |
| 248 | cpFloat keThreshold = (dvsq ? body->m*dvsq : 0.0f); |
| 249 | body->sleeping.idleTime = (cpBodyKineticEnergy(body) > keThreshold ? 0.0f : body->sleeping.idleTime + dt); |
| 250 | } |
| 251 | } |
| 252 | |
| 253 | // Awaken any sleeping bodies found and then push arbiters to the bodies' lists. |
| 254 | cpArray *arbiters = space->arbiters; |
| 255 | for(int i=0, count=arbiters->num; i<count; i++){ |
| 256 | cpArbiter *arb = (cpArbiter*)arbiters->arr[i]; |
| 257 | cpBody *a = arb->body_a, *b = arb->body_b; |
| 258 | |
| 259 | if(sleep){ |
| 260 | // TODO checking cpBodyIsSleepin() redundant? |
| 261 | if(cpBodyGetType(b) == CP_BODY_TYPE_KINEMATIC || cpBodyIsSleeping(a)) cpBodyActivate(a); |
| 262 | if(cpBodyGetType(a) == CP_BODY_TYPE_KINEMATIC || cpBodyIsSleeping(b)) cpBodyActivate(b); |
| 263 | } |
| 264 | |
| 265 | cpBodyPushArbiter(a, arb); |
| 266 | cpBodyPushArbiter(b, arb); |
| 267 | } |
| 268 | |
| 269 | if(sleep){ |
| 270 | // Bodies should be held active if connected by a joint to a kinematic. |
| 271 | cpArray *constraints = space->constraints; |
| 272 | for(int i=0; i<constraints->num; i++){ |
| 273 | cpConstraint *constraint = (cpConstraint *)constraints->arr[i]; |
| 274 | cpBody *a = constraint->a, *b = constraint->b; |
| 275 | |
| 276 | if(cpBodyGetType(b) == CP_BODY_TYPE_KINEMATIC) cpBodyActivate(a); |
| 277 | if(cpBodyGetType(a) == CP_BODY_TYPE_KINEMATIC) cpBodyActivate(b); |
no test coverage detected