// Remove the specified child from the linkset. // Safe to call even if the child is not really in the linkset. protected override void RemoveChildFromLinkset(BSPhysObject child) { if (m_children.Remove(child)) { DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString(), child.LocalID, child.PhysBody.ptr.ToString()); // Cause the child's body to be rebuilt and thus restored to normal operation RecomputeChildWorldPosition(child, false); child.ForceBodyShapeRebuild(false); if (!HasAnyChildren) { // The linkset is now empty. The root needs rebuilding. LinksetRoot.ForceBodyShapeRebuild(false); } else { // Rebuild the compound shape with the child removed ScheduleRebuild(child); } } return; }
// 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); }