From 5bdfd55ace4b673d8aaa3f25fd4bb675b1b28263 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 2 Aug 2013 10:32:43 -0700 Subject: BulletSim: When converting linkset types, don't try to change the list of linkset children while iterating through the list. --- .../Region/Physics/BulletSPlugin/BSPrimLinkable.cs | 29 +++++++++++++++------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs index c565998..7179a6d 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrimLinkable.cs @@ -240,26 +240,37 @@ public class BSPrimLinkable : BSPrimDisplaced bool ret = false; 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); + this.Linkset = newLinkset; + // Pick up any physical dependencies this linkset might have in the physics engine. oldLinkset.RemoveDependencies(this); - // Copy the linkset children from the old linkset to the new (will be a new instance from the factory) - oldLinkset.ForEachLinkInfo((li) => + // Create a list of the children (mainly because can't interate through a list that's changing) + List children = new List(); + oldLinkset.ForEachMember((child) => { - oldLinkset.RemoveMeFromLinkset(li.member); - newLinkset.AddMeToLinkset(li.member); - li.member.Linkset = newLinkset; - return false; + if (!oldLinkset.IsRoot(child)) + children.Add(child); + return false; // 'false' says to continue to next member }); - 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 newLinkset.Refresh(this); - this.ForceBodyShapeRebuild(true); + this.ForceBodyShapeRebuild(true /* inTaintTime */); } return ret; } -- cgit v1.1