public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, ODEPhysRepData pRepData, ILog plog) { m_worker = pWorker; m_log = plog; repData = pRepData; repData.meshState = MeshState.AssetFailed; if (provider == null) { return; } if (repData.assetID == null) { return; } UUID assetID = (UUID)repData.assetID; if (assetID == UUID.Zero) { return; } repData.meshState = MeshState.loadingAsset; provider(assetID, ODEassetReceived); }
// The creation of a mesh or hull can fail if an underlying asset is not available. // There are two cases: 1) the asset is not in the cache and it needs to be fetched; // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). // The first case causes the asset to be fetched. The second case requires // us to not loop forever. // Called after creating a physical mesh or hull. If the physical shape was created, // just return. private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) { // If the shape was successfully created, nothing more to do if (newShape.HasPhysicalShape) { return(newShape); } // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) { prim.LastAssetBuildFailed = true; BSPhysObject xprim = prim; DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", LogHeader, prim.LocalID, prim.LastAssetBuildFailed); 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) { if (!yprim.BaseShape.SculptEntry) { return; } if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) { return; } 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.ForceBodyShapeRebuild(false); }); } }); } else { if (prim.LastAssetBuildFailed) { PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); } } // While we figure out the real problem, stick a simple native shape on the object. BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); return(fillinShape); }
public void DoRepDataGetMesh(ODEPhysRepData repData) { if (!repData.pbs.SculptEntry) { return; } if (repData.meshState != MeshState.loadingAsset) { return; } if (repData.assetID == null || repData.assetID == UUID.Zero) { return; } if (repData.assetID != repData.pbs.SculptTexture) { return; } // check if it is in cache GetMesh(repData); if (repData.meshState != MeshState.needAsset) { CreateActorPhysRep(repData); m_scene.AddChange(repData.actor, changes.PhysRepData, repData); return; } RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod; if (assetProvider == null) { return; } ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log); }
protected void Initialise(RequestAssetDelegate m, float[] terrain, float waterHeight) { RequestAssetMethod = m; SetTerrain(terrain); SetWaterLevel(waterHeight); }
protected void Initialise(RequestAssetDelegate m, float[] terrain, float waterHeight) { RequestAssetMethod = m; SetTerrain(terrain); SetWaterLevel(waterHeight); }
public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, ODEPhysRepData pRepData, ILog plog) { m_worker = pWorker; m_log = plog; repData = pRepData; repData.meshState = MeshState.AssetFailed; if (provider == null) return; if (repData.assetID == null) return; UUID assetID = (UUID) repData.assetID; if (assetID == UUID.Zero) return; repData.meshState = MeshState.loadingAsset; provider(assetID, ODEassetReceived); }
// The creation of a mesh or hull can fail if an underlying asset is not available. // There are two cases: 1) the asset is not in the cache and it needs to be fetched; // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). // The first case causes the asset to be fetched. The second case requires // us to not loop forever. // Called after creating a physical mesh or hull. If the physical shape was created, // just return. public static BulletShape VerifyMeshCreated(BSScene physicsScene, BulletShape newShape, BSPhysObject prim) { // If the shape was successfully created, nothing more to do if (newShape.HasPhysicalShape) { return(newShape); } // VerifyMeshCreated is called after trying to create the mesh. If we think the asset had been // fetched but we end up here again, the meshing of the asset must have failed. // Prevent trying to keep fetching the mesh by declaring failure. if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) { prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; physicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,setFailed,objNam={1},tex={2}", prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture); } else { // 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.Failed && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting && prim.BaseShape.SculptTexture != OMV.UUID.Zero ) { physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAsset,objNam={1},tex={2}", prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture); // Multiple requestors will know we're waiting for this asset prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; BSPhysObject xprim = prim; Util.FireAndForget(delegate { // physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,inFireAndForget", xprim.LocalID); 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,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.Failed; } physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,fetchAssetCallback,found={1},isSculpt={2},ids={3}", yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs); }); } else { xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", LogHeader, physicsScene.Name); } }); } else { if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) { physicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,wasFailed,objNam={1},tex={2}", prim.LocalID, prim.PhysObjectName, prim.BaseShape.SculptTexture); } } } // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object. BSShape fillShape = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); physicsScene.DetailLog("{0},BSShape.VerifyMeshCreated,boxTempShape", prim.LocalID); return(fillShape.physShapeInfo); }