// 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); }
// // Merge the information from 'unit' into 'this' // void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) { if (source == EShSourceNone) source = unit.source; if (source != unit.source) error(infoSink, "can't link compilation units from different source languages"); if (source == EShSourceHlsl && unit.entryPoint.size() > 0) { if (entryPoint.size() > 0) error(infoSink, "can't handle multiple entry points per stage"); else entryPoint = unit.entryPoint; } numMains += unit.numMains; numErrors += unit.numErrors; numPushConstants += unit.numPushConstants; callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); if (originUpperLeft != unit.originUpperLeft || pixelCenterInteger != unit.pixelCenterInteger) error(infoSink, "gl_FragCoord redeclarations must match across shaders\n"); if (! earlyFragmentTests) earlyFragmentTests = unit.earlyFragmentTests; if (depthLayout == EldNone) depthLayout = unit.depthLayout; else if (depthLayout != unit.depthLayout) error(infoSink, "Contradictory depth layouts"); blendEquations |= unit.blendEquations; if (inputPrimitive == ElgNone) inputPrimitive = unit.inputPrimitive; else if (inputPrimitive != unit.inputPrimitive) error(infoSink, "Contradictory input layout primitives"); if (outputPrimitive == ElgNone) outputPrimitive = unit.outputPrimitive; else if (outputPrimitive != unit.outputPrimitive) error(infoSink, "Contradictory output layout primitives"); if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; else if (vertices != unit.vertices) { if (language == EShLangGeometry) error(infoSink, "Contradictory layout max_vertices values"); else if (language == EShLangTessControl) error(infoSink, "Contradictory layout vertices values"); else assert(0); } if (vertexSpacing == EvsNone) vertexSpacing = unit.vertexSpacing; else if (vertexSpacing != unit.vertexSpacing) error(infoSink, "Contradictory input vertex spacing"); if (vertexOrder == EvoNone) vertexOrder = unit.vertexOrder; else if (vertexOrder != unit.vertexOrder) error(infoSink, "Contradictory triangle ordering"); if (unit.pointMode) pointMode = true; for (int i = 0; i < 3; ++i) { if (localSize[i] > 1) localSize[i] = unit.localSize[i]; else if (localSize[i] != unit.localSize[i]) error(infoSink, "Contradictory local size"); if (localSizeSpecId[i] != TQualifier::layoutNotSet) localSizeSpecId[i] = unit.localSizeSpecId[i]; else if (localSizeSpecId[i] != unit.localSizeSpecId[i]) error(infoSink, "Contradictory local size specialization ids"); } if (unit.xfbMode) xfbMode = true; for (size_t b = 0; b < xfbBuffers.size(); ++b) { if (xfbBuffers[b].stride == TQualifier::layoutXfbStrideEnd) xfbBuffers[b].stride = unit.xfbBuffers[b].stride; else if (xfbBuffers[b].stride != unit.xfbBuffers[b].stride) error(infoSink, "Contradictory xfb_stride"); xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride); if (unit.xfbBuffers[b].containsDouble) xfbBuffers[b].containsDouble = true; // TODO: 4.4 link: enhanced layouts: compare ranges } if (unit.treeRoot == 0) return; if (treeRoot == 0) { treeRoot = unit.treeRoot; version = unit.version; requestedExtensions = unit.requestedExtensions; return; } // Getting this far means we have two existing trees to merge... version = std::max(version, unit.version); requestedExtensions.insert(unit.requestedExtensions.begin(), unit.requestedExtensions.end()); // Get the top-level globals of each unit TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence(); TIntermSequence& unitGlobals = unit.treeRoot->getAsAggregate()->getSequence(); // Get the linker-object lists TIntermSequence& linkerObjects = findLinkerObjects(); TIntermSequence& unitLinkerObjects = unit.findLinkerObjects(); mergeBodies(infoSink, globals, unitGlobals); mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects); ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); }