diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 5a9e9ffc1f..6586099280 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs @@ -401,20 +401,21 @@ public sealed class BSLinksetCompound : BSLinkset // The linkset must be in an intermediate state where all the children have not yet // been constructed. This sometimes happens on startup when everything is getting // built and some shapes have to wait for assets to be read in. - // Just skip this child for the moment and cause the shape to be rebuilt next tick. + // Just skip this linkset for the moment and cause the shape to be rebuilt next tick. // One problem might be that the shape is broken somehow and it never becomes completely // available. This might cause the rebuild to happen over and over. - if (LinksetRebuildFailureLoopPrevention-- > 0) - { - LinksetRoot.ForceBodyShapeRebuild(false); - DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChildWithNoShape,indx={1},cShape={2},offPos={3},offRot={4}", - LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot); - // Output an annoying warning. It should only happen once but if it keeps coming out, - // the user knows there is something wrong and will report it. - m_physicsScene.Logger.WarnFormat("{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader); - m_physicsScene.Logger.WarnFormat("{0} pName={1}, childIdx={2}, shape={3}", - LogHeader, LinksetRoot.Name, cPrim.LinksetChildIndex, childShape); - } + LinksetRoot.ForceBodyShapeRebuild(false); + DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChildWithNoShape,indx={1},cShape={2},offPos={3},offRot={4}", + LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot); + // Output an annoying warning. It should only happen once but if it keeps coming out, + // the user knows there is something wrong and will report it. + m_physicsScene.Logger.WarnFormat("{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader); + m_physicsScene.Logger.WarnFormat("{0} pName={1}, childIdx={2}, shape={3}", + LogHeader, LinksetRoot.Name, cPrim.LinksetChildIndex, childShape); + + // This causes the loop to bail on building the rest of this linkset. + // The rebuild operation should fix it up or declare the object unbuildable. + return true; } return false; // 'false' says to move onto the next child in the list diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 7a4655071d..75ffeb4830 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs @@ -159,6 +159,11 @@ public abstract class BSPhysObject : PhysicsActor Unknown, Waiting, FailedAssetFetch, FailedMeshing, Fetched } public PrimAssetCondition PrimAssetState { get; set; } + public virtual bool AssetFailed() + { + return ( (this.PrimAssetState == PrimAssetCondition.FailedAssetFetch) + || (this.PrimAssetState == PrimAssetCondition.FailedMeshing) ); + } // The objects base shape information. Null if not a prim type shape. public PrimitiveBaseShape BaseShape { get; protected set; } diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index b344ba1f72..09f5bc44ba 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -177,8 +177,7 @@ public abstract class BSShape { // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset if (prim.BaseShape.SculptEntry - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedAssetFetch - && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedMeshing + && !prim.AssetFailed() && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting && prim.BaseShape.SculptTexture != OMV.UUID.Zero ) @@ -189,50 +188,46 @@ public abstract class BSShape prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; BSPhysObject xprim = prim; - Util.FireAndForget(delegate + RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; + if (assetProvider != null) + { + BSPhysObject yprim = xprim; // probably not necessary, but, just in case. + assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) { - // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID); - RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; - if (assetProvider != null) + // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); + bool assetFound = false; + string mismatchIDs = String.Empty; // DEBUG DEBUG + if (asset != null && yprim.BaseShape.SculptEntry) { - BSPhysObject yprim = xprim; // probably not necessary, but, just in case. - assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) + if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) { - // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); - bool assetFound = false; - string mismatchIDs = String.Empty; // DEBUG DEBUG - if (asset != null && yprim.BaseShape.SculptEntry) - { - if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) - { - yprim.BaseShape.SculptData = asset.Data; - // This will cause the prim to see that the filler shape is not the right - // one and try again to build the object. - // No race condition with the normal shape setting since the rebuild is at taint time. - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; - yprim.ForceBodyShapeRebuild(false /* inTaintTime */); - assetFound = true; - } - else - { - mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; - } - } - if (!assetFound) - { - yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; - } - physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}", - yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); - }); + yprim.BaseShape.SculptData = asset.Data; + // This will cause the prim to see that the filler shape is not the right + // one and try again to build the object. + // No race condition with the normal shape setting since the rebuild is at taint time. + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; + yprim.ForceBodyShapeRebuild(false /* inTaintTime */); + assetFound = true; + } + else + { + mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; + } } - else + if (!assetFound) { - xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; - physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", - LogHeader, physicsScene.Name); + yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; } + physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}", + yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); }); + } + else + { + xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; + physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", + LogHeader, physicsScene.Name); + } } else { @@ -395,9 +390,7 @@ public class BSShapeMesh : BSShape // Check to see if mesh was created (might require an asset). newShape = VerifyMeshCreated(physicsScene, newShape, prim); - if (!newShape.isNativeShape - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch) + if (!newShape.isNativeShape || prim.AssetFailed() ) { // If a mesh was what was created, remember the built shape for later sharing. // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. @@ -584,9 +577,7 @@ public class BSShapeHull : BSShape // Check to see if hull was created (might require an asset). newShape = VerifyMeshCreated(physicsScene, newShape, prim); - if (!newShape.isNativeShape - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch) + if (!newShape.isNativeShape || prim.AssetFailed()) { // If a mesh was what was created, remember the built shape for later sharing. Hulls.Add(newHullKey, retHull); @@ -994,6 +985,11 @@ public class BSShapeCompound : BSShape BSShapeNative nativeShape = new BSShapeNative(pShape); nativeShape.Dereference(physicsScene); } + else + { + physicsScene.Logger.WarnFormat("{0} DereferenceAnonCollisionShape. Did not find shape. {1}", + LogHeader, pShape); + } } } } @@ -1137,9 +1133,7 @@ public class BSShapeGImpact : BSShape // Check to see if mesh was created (might require an asset). newShape = VerifyMeshCreated(physicsScene, newShape, prim); newShape.shapeKey = newMeshKey; - if (!newShape.isNativeShape - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing - || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch) + if (!newShape.isNativeShape || prim.AssetFailed()) { // If a mesh was what was created, remember the built shape for later sharing. // Also note that if meshing failed we put it in the mesh list as there is nothing