BulletSim: When converting linkset types, don't try to change the list

of linkset children while iterating through the list.
TeleportWork
Robert Adams 2013-08-02 10:32:43 -07:00
parent 24df15dab7
commit 5bdfd55ace
1 changed files with 20 additions and 9 deletions

View File

@ -240,26 +240,37 @@ public class BSPrimLinkable : BSPrimDisplaced
bool ret = false; bool ret = false;
if (LinksetType != newType) if (LinksetType != newType)
{ {
BSLinkset oldLinkset = Linkset; // Set the implementation type first so the call to BSLinkset.Factory gets the new type.
this.LinksetType = newType;
BSLinkset oldLinkset = this.Linkset;
BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this); BSLinkset newLinkset = BSLinkset.Factory(PhysScene, this);
this.Linkset = newLinkset;
// Pick up any physical dependencies this linkset might have in the physics engine. // Pick up any physical dependencies this linkset might have in the physics engine.
oldLinkset.RemoveDependencies(this); oldLinkset.RemoveDependencies(this);
// Copy the linkset children from the old linkset to the new (will be a new instance from the factory) // Create a list of the children (mainly because can't interate through a list that's changing)
oldLinkset.ForEachLinkInfo((li) => List<BSPrimLinkable> children = new List<BSPrimLinkable>();
oldLinkset.ForEachMember((child) =>
{ {
oldLinkset.RemoveMeFromLinkset(li.member); if (!oldLinkset.IsRoot(child))
newLinkset.AddMeToLinkset(li.member); children.Add(child);
li.member.Linkset = newLinkset; return false; // 'false' says to continue to next member
return false;
}); });
this.Linkset = newLinkset; // Remove the children from the old linkset and add to the new (will be a new instance from the factory)
foreach (BSPrimLinkable child in children)
{
oldLinkset.RemoveMeFromLinkset(child);
newLinkset.AddMeToLinkset(child);
child.Linkset = newLinkset;
}
// Force the shape and linkset to get reconstructed // Force the shape and linkset to get reconstructed
newLinkset.Refresh(this); newLinkset.Refresh(this);
this.ForceBodyShapeRebuild(true); this.ForceBodyShapeRebuild(true /* inTaintTime */);
} }
return ret; return ret;
} }