Ejemplo n.º 1
0
void Sc::ShapeSim::getFilterInfo(PxFilterObjectAttributes& filterAttr, PxFilterData& filterData) const
{
	filterAttr = 0;
	const PxShapeFlags flags = mCore.getFlags();

	if (hasTriggerFlags(flags))
		filterAttr |= PxFilterObjectFlag::eTRIGGER;

	BodySim* b = getBodySim();
	if (b)
	{
		if (!b->isArticulationLink())
		{
			if (b->isKinematic())
				filterAttr |= PxFilterObjectFlag::eKINEMATIC;

			setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eRIGID_DYNAMIC);
		}
		else
			setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eARTICULATION);
	}
	else
	{
		setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eRIGID_STATIC);
	}

	filterData = mCore.getSimulationFilterData();
}
void Sc::ConstraintProjectionTree::rankConstraint(ConstraintSim& c, BodyRank& br, PxU32& dominanceTracking, PxU32& constraintsToProjectCount)
{
	PxU32 projectToBody, projectToOtherBody;
	BodySim* otherB;
	getConstraintStatus(c, br.startingNode->body, otherB, projectToBody, projectToOtherBody);

	if (isFixedBody(otherB))	// joint to fixed anchor
	{
		PxU32 rank;
		if (projectToOtherBody)
		{
			dominanceTracking = 0;  // makes sure that the flags below will never get raised again for the body
			br.rank &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic);
			rank = BodyRank::sOneWayProjection;  //we should prefer picking projected constraints as the root over non-projected ones.
			constraintsToProjectCount++;
		}
		else
			rank = 0;

		if (!otherB)
			rank |= BodyRank::sAttachedToStatic;
		else
		{
			PX_ASSERT(otherB->isKinematic());
			rank |= BodyRank::sAttachedToKinematic;
		}

		// the highest ranked fixed anchor constraint should get tracked
		if ((!br.constraintToFixedAnchor) || (rank > br.rank))
			br.constraintToFixedAnchor = &c;

		br.rank |= rank;
	}
	else
	{
		if (projectToBody && projectToOtherBody)
		{
			dominanceTracking &= ~BodyRank::sAllDominantDynamic;  // makes sure that from now on this will never get raised again for the body
			br.rank &= ~BodyRank::sAllDominantDynamic;
			constraintsToProjectCount++;
		}
		else if (projectToOtherBody)
		{
			dominanceTracking &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic);  // makes sure that from now on these will never get raised again for the body
			br.rank &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic);
			constraintsToProjectCount++;
		}
		else if (projectToBody)
		{
			br.rank |= BodyRank::sOneWayProjection | (dominanceTracking & (BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic));
			constraintsToProjectCount++;
		}

		br.rank += BodyRank::sAttachedToDynamic;
	}
}
void Sc::ArticulationSim::addBody(BodySim& body, 
								  BodySim* parent, 
								  ArticulationJointSim* joint)
{
	mBodies.pushBack(&body);
	mJoints.pushBack(joint);
	mAcceleration.pushBack(Cm::SpatialVector(PxVec3(0.f), PxVec3(0.f)));

	PxU32 index = mLinks.size();

	PX_ASSERT((((index==0) && (joint == 0)) && (parent == 0)) ||
			  (((index!=0) && joint) && (parent && (parent->getArticulation() == this))));

	ArticulationLink &link = mLinks.insert();
	link.body = &body.getLowLevelBody();
	link.bodyCore = &body.getBodyCore().getCore();
	link.children = 0;
	bool shouldSleep;
	bool currentlyAsleep;
	bool bodyReadyForSleep = body.checkSleepReadinessBesidesWakeCounter();
	PxReal wakeCounter = getCore().getWakeCounter();

	if(parent)
	{
		currentlyAsleep = !mBodies[0]->isActive();
		shouldSleep = currentlyAsleep && bodyReadyForSleep;

		PxU32 parentIndex = findBodyIndex(*parent);
		link.parent = parentIndex;
		link.pathToRoot = mLinks[parentIndex].pathToRoot | ArticulationBitField(1)<<index;
		link.inboundJoint = &joint->getCore().getCore();
		mLinks[parentIndex].children |= ArticulationBitField(1)<<index;
	}
	else
	{
		currentlyAsleep = (wakeCounter == 0.0f);
		shouldSleep = currentlyAsleep && bodyReadyForSleep;

		link.parent = DY_ARTICULATION_LINK_NONE;
		link.pathToRoot = 1;
		link.inboundJoint = NULL;
	}

	if (currentlyAsleep && (!shouldSleep))
	{
		for(PxU32 i=0; i < (mBodies.size() - 1); i++)
			mBodies[i]->internalWakeUpArticulationLink(wakeCounter);
	}

	body.setArticulation(this, wakeCounter, shouldSleep, index);

	mUpdateSolverData = true;

}
PxU32 Sc::ConstraintProjectionTree::projectionTreeBuildStep(ConstraintGroupNode& node, ConstraintSim* cToParent, ConstraintGroupNode** nodeQueue)
{
	PX_ASSERT(node.readFlag(ConstraintGroupNode::eDISCOVERED));

	PxU32 nodeQueueFillCount = 0;

	//go through all constraints attached to the body.
	BodySim* body = node.body;
	PxU32 size = body->getActorInteractionCount();
	Sc::Interaction** interactions = body->getActorInteractions();
	while(size--)
	{
		Interaction* interaction = *interactions++;
		if (interaction->getType() == InteractionType::eCONSTRAINTSHADER)
		{
			ConstraintSim* c = static_cast<ConstraintInteraction*>(interaction)->getConstraint();

			if (c != cToParent)	//don't go back along the edge we came from (not really necessary I guess since the ConstraintGroupNode::eDISCOVERED marker should solve this)
			{
				PxU32 projectToBody, projectToOtherBody;
				BodySim* neighbor;
				getConstraintStatus(*c, body, neighbor, projectToBody, projectToOtherBody);

				if(!isFixedBody(neighbor) && (!projectToOtherBody || projectToBody))	//just ignore the eventual constraint with environment over here. Body might be attached to multiple fixed anchors.
																						//Also make sure to ignore one-way projection that goes the opposite way.
				{
					ConstraintGroupNode* neighborNode = neighbor->getConstraintGroup();
					PX_ASSERT(neighborNode);

					if (!neighborNode->readFlag(ConstraintGroupNode::eDISCOVERED))
					{
						*nodeQueue = neighborNode;

						neighborNode->initProjectionData(&node, c);
						neighborNode->raiseFlag(ConstraintGroupNode::eDISCOVERED);	//flag body nodes that we process so we can detect loops

						nodeQueueFillCount++;
						nodeQueue++;
					}
				}
			}
		}
	}

	return nodeQueueFillCount;
}
Ejemplo n.º 5
0
bool Sc::ShapeSim::destroyLowLevelVolume()
{
	//Need to test that shape has entry in bp.  The shape might not have a bp
	//entry because it has its simulation flag set to false.
	const PxcBpHandle actorHandle = getAABBMgrId().mActorHandle;
	if(PX_INVALID_BP_HANDLE!=actorHandle)
	{
		getInteractionScene().getLowLevelContext()->unMarkShape(actorHandle);
	}
	bool removingLastShape=Element::destroyLowLevelVolume();
	if(removingLastShape)
	{
		BodySim* b = getBodySim();
		if(b)
			b->getLowLevelBody().resetAABBMgrId();
	}
	return removingLastShape;
}
void Sc::ArticulationSim::removeBody(BodySim &body)
{
	PX_ASSERT(body.getArticulation() == this);
	PxU32 index = findBodyIndex(body);
	body.setArticulation(NULL, 0.0f, true, 0);

	ArticulationLink &link0 = mLinks[index];

	PX_ASSERT(link0.children == 0);
	PX_UNUSED(link0);

	// copy all the later links down by one
	for(PxU32 i=index+1;i<mLinks.size();i++)
	{
		mLinks[i-1] = mLinks[i];
		mBodies[i-1] = mBodies[i];
		mJoints[i-1] = mJoints[i];
		//setIslandHandle(*mBodies[i-1], i-1);
	}

	// adjust parent/child indices
	ArticulationBitField fixedIndices = (ArticulationBitField(1)<<index)-1;
	ArticulationBitField shiftIndices = ~(fixedIndices|(ArticulationBitField(1)<<index));

	for(PxU32 i=0;i<mLinks.size();i++)
	{
		ArticulationLink &link = mLinks[i];

		if(link.parent != DY_ARTICULATION_LINK_NONE && link.parent>index)
			link.pathToRoot = (link.pathToRoot&fixedIndices) | (link.pathToRoot&shiftIndices)>>1;
		link.children = (link.children&fixedIndices) | (link.children&shiftIndices)>>1;
	}

	mLinks.popBack();

	mUpdateSolverData = true;
}