Beispiel #1
0
        // 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.AddrString,
                          child.LocalID, child.PhysBody.AddrString);

                // 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;
        }
Beispiel #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.AddrString,
                            child.LocalID, child.PhysBody.AddrString);

            // 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;
    }
Beispiel #4
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.
        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);
        }