Esempio n. 1
0
// 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);
}
Esempio n. 2
0
//
// 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());
}