private SimulationIsland Merge(SimulationIsland s1, SimulationIsland s2)
{
//Pull the smaller island into the larger island and set all members
//of the smaller island to refer to the new island.
//The simulation islands can be null; a connection can be a kinematic entity, which has no simulation island.
//'Merging' a null island with an island simply gets back the island.
if (s1 == null)
{
//Should still activate the island, though.
s2.Activate();
return(s2);
}
if (s2 == null)
{
//Should still activate the island, though.
s1.Activate();
return(s1);
}
//Swap if needed so s1 is the bigger island
if (s1.memberCount < s2.memberCount)
{
var biggerIsland = s2;
s2 = s1;
s1 = biggerIsland;
}
s1.Activate();
s2.immediateParent = s1;
//This is a bit like a 'union by rank.'
//But don't get confused- simulation islands are not a union find structure.
//This parenting simply avoids the need for maintaining a list of members in each simulation island.
//In the subsequent frame, the deactivation candidacy update will go through the parents and eat away
//at the child simulation island. Then, in a later TryToDeactivate phase, the then-empty simulation island
//will be removed.
//The larger one survives.
return(s1);
}