Exemple #1
0
    // Get a reference to a physical shape. Create if it doesn't exist
    public static BSShape GetShapeReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
    {
        BSShape ret = null;

        if (prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
        {
            // an avatar capsule is close to a native shape (it is not shared)
            ret = BSShapeNative.GetReference(physicsScene, prim, BSPhysicsShapeType.SHAPE_CAPSULE,
                                        FixedShapeKey.KEY_CAPSULE);
            physicsScene.DetailLog("{0},BSShape.GetShapeReference,avatarCapsule,shape={1}", prim.LocalID, ret);
        }

        // Compound shapes are handled special as they are rebuilt from scratch.
        // This isn't too great a hardship since most of the child shapes will already been created.
        if (ret == null  && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
        {
            // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
            ret = BSShapeCompound.GetReference(prim);
            physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, ret);
        }

        if (ret == null)
            ret = GetShapeReferenceNonSpecial(physicsScene, forceRebuild, prim);

        return ret;
    }
        private bool CreateGeom(bool forceRebuild, BSPhysObject prim, PhysicalDestructionCallback shapeCallback)
        {
            bool ret                 = false;
            bool haveShape           = false;
            bool nativeShapePossible = true;
            PrimitiveBaseShape pbs   = prim.BaseShape;

            // Kludge to create the capsule for the avatar.
            // TDOD: Remove/redo this when BSShapeAvatar is working!!
            BSCharacter theChar = prim as BSCharacter;

            if (theChar != null)
            {
                DereferenceExistingShape(prim, shapeCallback);
                switch (BSParam.AvatarShape)
                {
                case AvatarShapeCapsule:
                    prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
                                                                BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE);
                    ret       = true;
                    haveShape = true;
                    break;

                case AvatarShapeCube:
                    prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
                                                                BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_CAPSULE);
                    ret       = true;
                    haveShape = true;
                    break;

                case AvatarShapeOvoid:
                    // Saddly, Bullet doesn't scale spheres so this doesn't work as an avatar shape
                    prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
                                                                BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_CAPSULE);
                    ret       = true;
                    haveShape = true;
                    break;

                case AvatarShapeMesh:
                    break;

                default:
                    break;
                }
            }

            // If the prim attributes are simple, this could be a simple Bullet native shape
            // Native shapes work whether to object is static or physical.
            if (!haveShape &&
                nativeShapePossible &&
                pbs != null &&
                PrimHasNoCuts(pbs) &&
                (!pbs.SculptEntry || (pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim))
                )
            {
                // Get the scale of any existing shape so we can see if the new shape is same native type and same size.
                OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero;
                if (prim.PhysShape.HasPhysicalShape)
                {
                    scaleOfExistingShape = m_physicsScene.PE.GetLocalScaling(prim.PhysShape.physShapeInfo);
                }

                if (DDetail)
                {
                    DetailLog("{0},BSShapeCollection.CreateGeom,maybeNative,force={1},primScale={2},primSize={3},primShape={4}",
                              prim.LocalID, forceRebuild, prim.Scale, prim.Size, prim.PhysShape.physShapeInfo.shapeType);
                }

                // It doesn't look like Bullet scales native spheres so make sure the scales are all equal
                if ((pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1) &&
                    pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)
                {
                    haveShape = true;
                    if (forceRebuild ||
                        prim.PhysShape.ShapeType != BSPhysicsShapeType.SHAPE_SPHERE
                        )
                    {
                        DereferenceExistingShape(prim, shapeCallback);
                        prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
                                                                    BSPhysicsShapeType.SHAPE_SPHERE, FixedShapeKey.KEY_SPHERE);
                        ret = true;
                    }
                    if (DDetail)
                    {
                        DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}",
                                  prim.LocalID, forceRebuild, ret, prim.PhysShape);
                    }
                }
                // If we didn't make a sphere, maybe a box will work.
                if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
                {
                    haveShape = true;
                    if (forceRebuild ||
                        prim.Scale != scaleOfExistingShape ||
                        prim.PhysShape.ShapeType != BSPhysicsShapeType.SHAPE_BOX
                        )
                    {
                        DereferenceExistingShape(prim, shapeCallback);
                        prim.PhysShape = BSShapeNative.GetReference(m_physicsScene, prim,
                                                                    BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
                        ret = true;
                    }
                    if (DDetail)
                    {
                        DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},rebuilt={2},shape={3}",
                                  prim.LocalID, forceRebuild, ret, prim.PhysShape);
                    }
                }
            }

            // If a simple shape is not happening, create a mesh and possibly a hull.
            if (!haveShape && pbs != null)
            {
                ret = CreateGeomMeshOrHull(prim, shapeCallback);
            }

            return(ret);
        }
Exemple #3
0
 // Sometimes we have a pointer to a collision shape but don't know what type it is.
 // Figure out type and call the correct dereference routine.
 // Called at taint-time.
 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
 {
     // TODO: figure a better way to go through all the shape types and find a possible instance.
     physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,shape={1}",
                                         BSScene.DetailLogZero, pShape);
     BSShapeMesh meshDesc;
     if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
     {
         meshDesc.Dereference(physicsScene);
         // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundMesh,shape={1}", BSScene.DetailLogZero, pShape);
     }
     else
     {
         BSShapeHull hullDesc;
         if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc))
         {
             hullDesc.Dereference(physicsScene);
             // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundHull,shape={1}", BSScene.DetailLogZero, pShape);
         }
         else
         {
             BSShapeConvexHull chullDesc;
             if (BSShapeConvexHull.TryGetConvexHullByPtr(pShape, out chullDesc))
             {
                 chullDesc.Dereference(physicsScene);
                 // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundConvexHull,shape={1}", BSScene.DetailLogZero, pShape);
             }
             else
             {
                 BSShapeGImpact gImpactDesc;
                 if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
                 {
                     gImpactDesc.Dereference(physicsScene);
                     // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,foundgImpact,shape={1}", BSScene.DetailLogZero, pShape);
                 }
                 else
                 {
                     // Didn't find it in the lists of specific types. It could be compound.
                     BSShapeCompound compoundDesc;
                     if (BSShapeCompound.TryGetCompoundByPtr(pShape, out compoundDesc))
                     {
                         compoundDesc.Dereference(physicsScene);
                         // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,recursiveCompoundShape,shape={1}", BSScene.DetailLogZero, pShape);
                     }
                     else
                     {
                         // If none of the above, maybe it is a simple native shape.
                         if (physicsScene.PE.IsNativeShape(pShape))
                         {
                             // physicsScene.DetailLog("{0},BSShapeCompound.DereferenceAnonCollisionShape,assumingNative,shape={1}", BSScene.DetailLogZero, pShape);
                             BSShapeNative nativeShape = new BSShapeNative(pShape);
                             nativeShape.Dereference(physicsScene);
                         }
                     }
                 }
             }
         }
     }
 }
Exemple #4
0
 public override BSShape GetReference(BSScene pPhysicsScene, BSPhysObject pPrim)
 {
     // Native shapes are not shared so we return a new shape.
     BSShape ret = null;
     lock (physShapeInfo)
     {
         ret = new BSShapeNative(CreatePhysicalNativeShape(pPhysicsScene, pPrim,
                                     physShapeInfo.shapeType, (FixedShapeKey)physShapeInfo.shapeKey));
     }
     return ret;
 }
Exemple #5
0
 // Sometimes we have a pointer to a collision shape but don't know what type it is.
 // Figure out type and call the correct dereference routine.
 // Called at taint-time.
 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
 {
     BSShapeMesh meshDesc;
     if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
     {
         meshDesc.Dereference(physicsScene);
     }
     else
     {
         BSShapeHull hullDesc;
         if (BSShapeHull.TryGetHullByPtr(pShape, out hullDesc))
         {
             hullDesc.Dereference(physicsScene);
         }
         else
         {
             BSShapeConvexHull chullDesc;
             if (BSShapeConvexHull.TryGetHullByPtr(pShape, out chullDesc))
             {
                 chullDesc.Dereference(physicsScene);
             }
             else
             {
                 if (physicsScene.PE.IsCompound(pShape))
                 {
                     BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
                     recursiveCompound.Dereference(physicsScene);
                 }
                 else
                 {
                     if (physicsScene.PE.IsNativeShape(pShape))
                     {
                         BSShapeNative nativeShape = new BSShapeNative(pShape);
                         nativeShape.Dereference(physicsScene);
                     }
                 }
             }
         }
     }
 }
Exemple #6
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);
        }