///<summary>
/// Strips a member of its simulation island.
///</summary>
///<param name="member">Member to be stripped.</param>
public void RemoveSimulationIslandFromMember(SimulationIslandMember member)
{
//Becoming kinematic eliminates the member as a possible path.
//Splits must be attempted between its connected members.
//Don't need to split same-connection members. Splitting one non-null entry against a non null entry in each of the other connections will do the trick.
if (member.simulationIsland != null)
{
//Note that this is using the most immediate simulation island. This is because the immediate simulation island
//is the one who 'owns' the member; not the root parent. The root parent will own the member in the next frame
//after the deactivation candidacy loop runs.
SimulationIsland island = member.simulationIsland;
island.Remove(member);
if (island.memberCount == 0)
{
//Even though we appear to have connections, the island was only me!
//We can stop now.
//Note that we do NOT remove the island from the simulation islands list here.
//That would take an O(n) search. Instead, orphan it and let the TryToDeactivate loop find it.
return;
}
}
if (member.connections.Count > 0)
{
for (int i = 0; i < member.connections.Count; i++)
{
//Find a member with a non-null island to represent connection i.
SimulationIslandMember representativeA = null;
for (int j = 0; j < member.connections.Elements[i].entries.Count; j++)
{
if (member.connections.Elements[i].entries.Elements[j].Member.SimulationIsland != null)
{
representativeA = member.connections.Elements[i].entries.Elements[j].Member;
break;
}
}
if (representativeA == null)
{
//There was no representative! That means it was a connection in which
//no member had a simulation island. Consider removing a dynamic box from the space
//while it sits on a kinematic box. Neither object has a simulation island.
//In this case, simply try the next connection.
continue;
}
//Activate the representative. This must be performed even if no split occurs; connected objects must be activated!
representativeA.Activate();
//Split the representative against representatives from other connections.
for (int j = i + 1; j < member.connections.Count; j++)
{
//Find a representative for another connection.
SimulationIslandMember representativeB = null;
for (int k = 0; k < member.connections.Elements[j].entries.Count; k++)
{
if (member.connections.Elements[j].entries.Elements[k].Member.SimulationIsland != null)
{
representativeB = member.connections.Elements[j].entries.Elements[k].Member;
break;
}
}
if (representativeB == null)
{
//There was no representative! Same idea as above.
//Try the next connection.
continue;
}
//Activate the representative. This must be performed even if no split occurs; connected objects must be activated!
representativeB.Activate();
//Try to split the representatives.
//Don't bother doing any deferring; this is a rare activity
//and it's best just to do it up front.
TryToSplit(representativeA, representativeB);
}
}
}
}