BulletSim: rearrange code for sensing whether shapes have been

constructed.
Add routine to check for failed and use that method rather than
    checking individual state.
bullet-2.82
Robert Adams 2014-07-26 16:03:43 -07:00
parent 327632dc66
commit 9c804466e5
3 changed files with 60 additions and 60 deletions

View File

@ -401,20 +401,21 @@ public sealed class BSLinksetCompound : BSLinkset
// The linkset must be in an intermediate state where all the children have not yet // 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 // been constructed. This sometimes happens on startup when everything is getting
// built and some shapes have to wait for assets to be read in. // 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 // 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. // 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.ForceBodyShapeRebuild(false); LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot);
DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,addChildWithNoShape,indx={1},cShape={2},offPos={3},offRot={4}", // Output an annoying warning. It should only happen once but if it keeps coming out,
LinksetRoot.LocalID, cPrim.LinksetChildIndex, childShape, offsetPos, offsetRot); // the user knows there is something wrong and will report it.
// Output an annoying warning. It should only happen once but if it keeps coming out, m_physicsScene.Logger.WarnFormat("{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader);
// the user knows there is something wrong and will report it. m_physicsScene.Logger.WarnFormat("{0} pName={1}, childIdx={2}, shape={3}",
m_physicsScene.Logger.WarnFormat("{0} Linkset rebuild warning. If this happens more than one or two times, please report in Mantis 7191", LogHeader); LogHeader, LinksetRoot.Name, cPrim.LinksetChildIndex, childShape);
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 return false; // 'false' says to move onto the next child in the list

View File

@ -159,6 +159,11 @@ public abstract class BSPhysObject : PhysicsActor
Unknown, Waiting, FailedAssetFetch, FailedMeshing, Fetched Unknown, Waiting, FailedAssetFetch, FailedMeshing, Fetched
} }
public PrimAssetCondition PrimAssetState { get; set; } 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. // The objects base shape information. Null if not a prim type shape.
public PrimitiveBaseShape BaseShape { get; protected set; } public PrimitiveBaseShape BaseShape { get; protected set; }

View File

@ -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 this mesh has an underlying asset and we have not failed getting it before, fetch the asset
if (prim.BaseShape.SculptEntry if (prim.BaseShape.SculptEntry
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedAssetFetch && !prim.AssetFailed()
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.FailedMeshing
&& prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
&& prim.BaseShape.SculptTexture != OMV.UUID.Zero && prim.BaseShape.SculptTexture != OMV.UUID.Zero
) )
@ -189,50 +188,46 @@ public abstract class BSShape
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
BSPhysObject xprim = prim; 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); // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID);
RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; bool assetFound = false;
if (assetProvider != null) string mismatchIDs = String.Empty; // DEBUG DEBUG
if (asset != null && yprim.BaseShape.SculptEntry)
{ {
BSPhysObject yprim = xprim; // probably not necessary, but, just in case. if (yprim.BaseShape.SculptTexture.ToString() == asset.ID)
assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
{ {
// physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,assetProviderCallback", xprim.LocalID); yprim.BaseShape.SculptData = asset.Data;
bool assetFound = false; // This will cause the prim to see that the filler shape is not the right
string mismatchIDs = String.Empty; // DEBUG DEBUG // one and try again to build the object.
if (asset != null && yprim.BaseShape.SculptEntry) // No race condition with the normal shape setting since the rebuild is at taint time.
{ yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
if (yprim.BaseShape.SculptTexture.ToString() == asset.ID) yprim.ForceBodyShapeRebuild(false /* inTaintTime */);
{ assetFound = true;
yprim.BaseShape.SculptData = asset.Data; }
// This will cause the prim to see that the filler shape is not the right else
// one and try again to build the object. {
// No race condition with the normal shape setting since the rebuild is at taint time. mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
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 );
});
} }
else if (!assetFound)
{ {
xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch; yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.FailedAssetFetch;
physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
LogHeader, physicsScene.Name);
} }
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 else
{ {
@ -395,9 +390,7 @@ public class BSShapeMesh : BSShape
// Check to see if mesh was created (might require an asset). // Check to see if mesh was created (might require an asset).
newShape = VerifyMeshCreated(physicsScene, newShape, prim); newShape = VerifyMeshCreated(physicsScene, newShape, prim);
if (!newShape.isNativeShape if (!newShape.isNativeShape || prim.AssetFailed() )
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
{ {
// If a mesh was what was created, remember the built shape for later sharing. // 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. // 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). // Check to see if hull was created (might require an asset).
newShape = VerifyMeshCreated(physicsScene, newShape, prim); newShape = VerifyMeshCreated(physicsScene, newShape, prim);
if (!newShape.isNativeShape if (!newShape.isNativeShape || prim.AssetFailed())
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
{ {
// If a mesh was what was created, remember the built shape for later sharing. // If a mesh was what was created, remember the built shape for later sharing.
Hulls.Add(newHullKey, retHull); Hulls.Add(newHullKey, retHull);
@ -994,6 +985,11 @@ public class BSShapeCompound : BSShape
BSShapeNative nativeShape = new BSShapeNative(pShape); BSShapeNative nativeShape = new BSShapeNative(pShape);
nativeShape.Dereference(physicsScene); 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). // Check to see if mesh was created (might require an asset).
newShape = VerifyMeshCreated(physicsScene, newShape, prim); newShape = VerifyMeshCreated(physicsScene, newShape, prim);
newShape.shapeKey = newMeshKey; newShape.shapeKey = newMeshKey;
if (!newShape.isNativeShape if (!newShape.isNativeShape || prim.AssetFailed())
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedMeshing
|| prim.PrimAssetState == BSPhysObject.PrimAssetCondition.FailedAssetFetch)
{ {
// If a mesh was what was created, remember the built shape for later sharing. // 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 // Also note that if meshing failed we put it in the mesh list as there is nothing