// 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;
        }
Example #2
0
        // 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);
        }
    // 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;
    }