///<summary>
/// Adds a simulation island to a member.
///</summary>
///<param name="member">Member to gain a simulation island.</param>
///<exception cref="Exception">Thrown if the member already has a simulation island.</exception>
public void AddSimulationIslandToMember(SimulationIslandMember member)
{
if (member.SimulationIsland != null)
{
throw new ArgumentException("Cannot initialize member's simulation island; it already has one.");
}
if (member.connections.Count > 0)
{
SimulationIsland island = null;
//Find a simulation starting island to live in.
for (int i = 0; i < member.connections.Count; i++)
{
for (int j = 0; j < member.connections.Elements[i].entries.Count; j++)
{
island = member.connections.Elements[i].entries.Elements[j].Member.SimulationIsland;
if (island != null)
{
island.Add(member);
break;
}
}
if (island != null)
{
break;
}
}
if (member.SimulationIsland == null)
{
//No non-null entries in any connections. That's weird.
//Maybe it's connected to a bunch of kinematics, or maybe it's a vehicle-like situation
//where the body is associated with a 'vehicle' connection which sometimes contains only the body.
//No friends to merge with.
SimulationIsland newIsland = islandPool.Take();
simulationIslands.Add(newIsland);
newIsland.Add(member);
return;
}
//Becoming dynamic adds a new path.
//Merges must be attempted between its connected members.
for (int i = 0; i < member.connections.Count; i++)
{
for (int j = 0; j < member.connections.Elements[i].entries.Count; j++)
{
if (member.connections.Elements[i].entries.Elements[j].Member == member)
{
continue; //Don't bother trying to compare against ourselves. That would cause an erroneous early-out sometimes.
}
SimulationIsland opposingIsland = member.connections.Elements[i].entries.Elements[j].Member.SimulationIsland;
if (opposingIsland != null)
{
if (island != opposingIsland)
{
island = Merge(island, opposingIsland);
}
//All non-null simulation islands in a single connection are guaranteed to be the same island due to previous merges.
//Once we find one, we can stop.
break;
}
}
}
}
else
{
//No friends to merge with.
SimulationIsland newIsland = islandPool.Take();
simulationIslands.Add(newIsland);
newIsland.Add(member);
}
}