public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
 {
     m_physicsScene = physicsScene;
     m_controllingPrim = pObj;
     ActorName = actorName;
     Enabled = true;
 }
Esempio n. 2
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 have 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);
            }

            // Avatars have their own unique shape
            if (ret == null && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_AVATAR)
            {
                // Getting a reference to a compound shape gets you the compound shape with the root prim shape added
                ret = BSShapeAvatar.GetReference(prim);
                physicsScene.DetailLog("{0},BSShapeCollection.CreateGeom,avatarShape,shape={1}", prim.LocalID, ret);
            }

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

            return ret;
        }
 public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_velocityMotor = null;
     m_walkingUpStairs = 0;
     m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID);
 }
Esempio n. 4
0
 public BSActorMoveToTarget(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_targetMotor = null;
     m_physicsScene.DetailLog("{0},BSActorMoveToTarget,constructor", m_controllingPrim.LocalID);
 }
 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
     LockAxisConstraint = null;
 }
 public BSActorMoveToTarget(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_targetMotor = null;
     m_physicsScene.DetailLog("{0},BSActorMoveToTarget,constructor", m_controllingPrim.LocalID);
 }
        // Create a body object in Bullet.
        // Updates prim.BSBody with the information about the new body if one is created.
        // Returns 'true' if an object was actually created.
        // Called at taint-time.
        private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletWorld sim,
            BodyDestructionCallback bodyCallback)
        {
            bool ret = false;

            // the mesh, hull or native shape must have already been created in Bullet
            bool mustRebuild = !prim.PhysBody.HasPhysicalBody;

            // If there is an existing body, verify it's of an acceptable type.
            // If not a solid object, body is a GhostObject. Otherwise a RigidBody.
            if (!mustRebuild)
            {
                CollisionObjectTypes bodyType = (CollisionObjectTypes)PhysicsScene.PE.GetBodyType(prim.PhysBody);
                if (prim.IsSolid && bodyType != CollisionObjectTypes.CO_RIGID_BODY
                    || !prim.IsSolid && bodyType != CollisionObjectTypes.CO_GHOST_OBJECT)
                {
                    // If the collisionObject is not the correct type for solidness, rebuild what's there
                    mustRebuild = true;
                    if (DDetail)
                        DetailLog("{0},BSShapeCollection.CreateBody,forceRebuildBecauseChangingBodyType,bodyType={1}",
                            prim.LocalID, bodyType);
                }
            }

            if (mustRebuild || forceRebuild)
            {
                // Free any old body
                DereferenceBody(prim.PhysBody, bodyCallback);

                BulletBody aBody;
                if (prim.IsSolid)
                {
                    aBody = PhysicsScene.PE.CreateBodyFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition,
                        prim.RawOrientation);
                    if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,mesh,body={1}", prim.LocalID, aBody);
                }
                else
                {
                    aBody = PhysicsScene.PE.CreateGhostFromShape(sim, prim.PhysShape, prim.LocalID, prim.RawPosition,
                        prim.RawOrientation);
                    if (DDetail) DetailLog("{0},BSShapeCollection.CreateBody,ghost,body={1}", prim.LocalID, aBody);
                }

                ReferenceBody(aBody);

                prim.PhysBody = aBody;

                ret = true;
            }

            return ret;
        }
 public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim)
 {
     return GetBodyAndShape(forceRebuild, sim, prim, null, null);
 }
Esempio n. 9
0
 public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim,
     BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
 {
     // Native shapes are not shared and are always built anew.
     //return new BSShapeNative(physicsScene, prim, shapeType, shapeKey);
     return null;
 }
        // Builds a mesh shape in the physical world and updates prim.BSShape.
        // Dereferences previous shape in BSShape and adds a reference for this new shape.
        // Returns 'true' of a mesh was actually built. Otherwise .
        // Called at taint-time!
        private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            BulletShape newShape = new BulletShape();

            float lod;
            System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);

            // if this new shape is the same as last time, don't recreate the mesh
            if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_MESH)
                return false;

            if (DDetail)
                DetailLog("{0},BSShapeCollection.GetReferenceToMesh,create,oldKey={1},newKey={2},size={3},lod={4}",
                    prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod);

            // Since we're recreating new, get rid of the reference to the previous shape
            DereferenceShape(prim.PhysShape, shapeCallback);

            newShape = CreatePhysicalMesh(prim, newMeshKey, prim.BaseShape, prim.Size, lod);
            // Take evasive action if the mesh was not constructed.
            newShape = VerifyMeshCreated(newShape, prim);

            ReferenceShape(newShape);

            prim.PhysShape = newShape;

            return true; // 'true' means a new shape has been added to this prim
        }
 public BSActorSetForce(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_forceMotor = null;
     m_physicsScene.DetailLog("{0},BSActorSetForce,constructor", m_controllingPrim.LocalID);
 }
        // Creates a native shape and assignes it to prim.BSShape.
        // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape().
        private bool GetReferenceToNativeShape(BSPhysObject prim,
            BSPhysicsShapeType shapeType, FixedShapeKey shapeKey,
            ShapeDestructionCallback shapeCallback)
        {
            // release any previous shape
            DereferenceShape(prim.PhysShape, shapeCallback);

            BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey);

            // Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
            if (DDetail)
                DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
                    prim.LocalID, newShape, prim.Scale);

            // native shapes are scaled by Bullet
            prim.PhysShape = newShape;
            return true;
        }
        private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, BSPhysicsShapeType shapeType,
            FixedShapeKey shapeKey)
        {
            BulletShape newShape;
            // Need to make sure the passed shape information is for the native type.
            ShapeData nativeShapeData = new ShapeData();
            nativeShapeData.Type = shapeType;
            nativeShapeData.ID = prim.LocalID;
            nativeShapeData.Scale = prim.Scale;
            nativeShapeData.Size = prim.Scale; // unneeded, I think.
            nativeShapeData.MeshKey = (ulong)shapeKey;
            nativeShapeData.HullKey = (ulong)shapeKey;

            if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
            {
                newShape = PhysicsScene.PE.BuildCapsuleShape(PhysicsScene.World, 1f, 1f, prim.Scale);
                if (DDetail)
                    DetailLog("{0},BSShapeCollection.BuildPhysicalNativeShape,capsule,scale={1}", prim.LocalID,
                        prim.Scale);
            }
            else
            {
                // Native shapes are scaled in Bullet so set the scaling to the size
                newShape = PhysicsScene.PE.BuildNativeShape(PhysicsScene.World, nativeShapeData);
            }
            if (!newShape.HasPhysicalShape)
            {
                PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
                    LogHeader, prim.LocalID, shapeType);
            }
            newShape.shapeKey = (System.UInt64)shapeKey;
            newShape.isNativeShape = true;

            return newShape;
        }
 // return 'true' if the prim's shape was changed.
 public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
 {
     bool ret = false;
     // Note that if it's a native shape, the check for physical/non-physical is not
     //     made. Native shapes work in either case.
     if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects)
     {
         // Update prim.BSShape to reference a hull of this shape.
         ret = GetReferenceToHull(prim, shapeCallback);
         if (DDetail)
             DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}",
                 prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
     }
     else
     {
         ret = GetReferenceToMesh(prim, shapeCallback);
         if (DDetail)
             DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}",
                 prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X"));
     }
     return ret;
 }
        // Create a mesh, hull or native shape.
        // Return 'true' if the prim's shape was changed.
        public bool CreateGeomNonSpecial(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            bool ret = false;
            bool haveShape = false;
            bool nativeShapePossible = true;
            PrimitiveBaseShape pbs = prim.BaseShape;

            // If the prim attributes are simple, this could be a simple Bullet native shape
            if (!haveShape
                && nativeShapePossible
                && pbs != null
                && !pbs.SculptEntry
                && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)))
            {
                // 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 = PhysicsScene.PE.GetLocalScaling(prim.PhysShape);

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

                // 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.Scale != scaleOfExistingShape
                        || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_SPHERE
                        )
                    {
                        ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_SPHERE,
                            FixedShapeKey.KEY_SPHERE, shapeCallback);
                    }
                    if (DDetail)
                        DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},rebuilt={2},shape={3}",
                            prim.LocalID, forceRebuild, ret, prim.PhysShape);
                }
                if (!haveShape && pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
                {
                    haveShape = true;
                    if (forceRebuild
                        || prim.Scale != scaleOfExistingShape
                        || prim.PhysShape.type != BSPhysicsShapeType.SHAPE_BOX
                        )
                    {
                        ret = GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX,
                            FixedShapeKey.KEY_BOX, shapeCallback);
                    }
                    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;
        }
        // Create the geometry information in Bullet for later use.
        // The objects needs a hull if it's physical otherwise a mesh is enough.
        // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls,
        //     shared geometries will be used. If the parameters of the existing shape are the same
        //     as this request, the shape is not rebuilt.
        // Info in prim.BSShape is updated to the new shape.
        // Returns 'true' if the geometry was rebuilt.
        // Called at taint-time!
        private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            bool ret = false;
            bool haveShape = false;

            if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_CAPSULE)
            {
                // an avatar capsule is close to a native shape (it is not shared)
                GetReferenceToNativeShape(prim, BSPhysicsShapeType.SHAPE_CAPSULE, FixedShapeKey.KEY_CAPSULE,
                    shapeCallback);
                if (DDetail)
                    DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape);
                ret = true;
                haveShape = true;
            }

            // 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 have already been created.
            if (!haveShape && prim.PreferredPhysicalShape == BSPhysicsShapeType.SHAPE_COMPOUND)
            {
                ret = GetReferenceToCompoundShape(prim, shapeCallback);
                if (DDetail)
                    DetailLog("{0},BSShapeCollection.CreateGeom,compoundShape,shape={1}", prim.LocalID, prim.PhysShape);
                haveShape = true;
            }

            if (!haveShape)
            {
                ret = CreateGeomNonSpecial(forceRebuild, prim, shapeCallback);
            }

            return ret;
        }
 public override bool Collide(uint collidingWith, BSPhysObject collidee,
     OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
 {
     // prims in the same linkset cannot collide with each other
     BSPrimLinkable convCollidee = collidee as BSPrimLinkable;
     if (convCollidee != null && (this.Linkset.LinksetID == convCollidee.Linkset.LinksetID))
     {
     return false;
     }
     return base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth);
 }
Esempio n. 18
0
 public static BSShape GetReference(BSPhysObject prim)
 {
     return new BSShapeNull();
 }
        private BulletShape CreatePhysicalMesh(BSPhysObject prim, System.UInt64 newMeshKey, PrimitiveBaseShape pbs,
            OMV.Vector3 size, float lod)
        {
            BulletShape newShape = new BulletShape();

            MeshDesc meshDesc;
            if (Meshes.TryGetValue(newMeshKey, out meshDesc))
            {
                // If the mesh has already been built just use it.
                newShape = meshDesc.shape.Clone();
            }
            else
            {
                IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
                    false // say it is not physical so a bounding box is not built
                    );

                if (meshData != null)
                {
                    int[] indices = meshData.getIndexListAsInt();
                    int realIndicesIndex = indices.Length;
                    float[] verticesAsFloats = meshData.getVertexListAsFloat();

                    if (BSParam.ShouldRemoveZeroWidthTriangles)
                    {
                        // Remove degenerate triangles. These are triangles with two of the vertices
                        //    are the same. This is complicated by the problem that vertices are not
                        //    made unique in sculpties so we have to compare the values in the vertex.
                        realIndicesIndex = 0;
                        for (int tri = 0; tri < indices.Length; tri += 3)
                        {
                            // Compute displacements into vertex array for each vertex of the triangle
                            int v1 = indices[tri + 0] * 3;
                            int v2 = indices[tri + 1] * 3;
                            int v3 = indices[tri + 2] * 3;
                            // Check to see if any two of the vertices are the same
                            if (!((verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0]
                                   && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1]
                                   && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2])
                                  || (verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0]
                                      && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1]
                                      && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2])
                                  || (verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0]
                                      && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1]
                                      && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]))
                                )
                            {
                                // None of the vertices of the triangles are the same. This is a good triangle;
                                indices[realIndicesIndex + 0] = indices[tri + 0];
                                indices[realIndicesIndex + 1] = indices[tri + 1];
                                indices[realIndicesIndex + 2] = indices[tri + 2];
                                realIndicesIndex += 3;
                            }
                        }
                    }
                    DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}",
                        BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3);

                    if (realIndicesIndex != 0)
                    {
                        newShape = PhysicsScene.PE.CreateMeshShape(PhysicsScene.World,
                            realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
                    }
                    else
                    {
                        PhysicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}",
                            LogHeader, prim.PhysObjectName, prim.RawPosition, PhysicsScene.Scene.RegionInfo.RegionName);
                    }
                }
            }
            newShape.shapeKey = newMeshKey;

            return newShape;
        }
        // Called to update/change the body and shape for an object.
        // First checks the shape and updates that if necessary then makes
        //    sure the body is of the right type.
        // Return 'true' if either the body or the shape changed.
        // 'shapeCallback' and 'bodyCallback' are, if non-null, functions called just before
        //    the current shape or body is destroyed. This allows the caller to remove any
        //    higher level dependencies on the shape or body. Mostly used for LinkSets to
        //    remove the physical constraints before the body is destroyed.
        // Called at taint-time!!
        public bool GetBodyAndShape(bool forceRebuild, BulletWorld sim, BSPhysObject prim,
            ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
        {
            PhysicsScene.AssertInTaintTime("BSShapeCollection.GetBodyAndShape");

            bool ret = false;

            // This lock could probably be pushed down lower but building shouldn't take long
            lock (m_collectionActivityLock)
            {
                // Do we have the correct geometry for this type of object?
                // Updates prim.BSShape with information/pointers to shape.
                // Returns 'true' of BSShape is changed to a new shape.
                bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback);
                // If we had to select a new shape geometry for the object,
                //    rebuild the body around it.
                // Updates prim.BSBody with information/pointers to requested body
                // Returns 'true' if BSBody was changed.
                bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, bodyCallback);
                ret = newGeom || newBody;
            }
            DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}",
                prim.LocalID, forceRebuild, ret, prim.PhysBody, prim.PhysShape);

            return ret;
        }
Esempio n. 21
0
 public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
 {
     return null;
 }
        // See that hull shape exists in the physical world and update prim.BSShape.
        // We could be creating the hull because scale changed or whatever.
        // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance.
        private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            BulletShape newShape;

            float lod;
            System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod);

            // if the hull hasn't changed, don't rebuild it
            if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == BSPhysicsShapeType.SHAPE_HULL)
                return false;

            if (DDetail)
                DetailLog("{0},BSShapeCollection.GetReferenceToHull,create,oldKey={1},newKey={2}",
                    prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newHullKey.ToString("X"));

            // Remove usage of the previous shape.
            DereferenceShape(prim.PhysShape, shapeCallback);

            newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
            // It might not have been created if we're waiting for an asset.
            newShape = VerifyMeshCreated(newShape, prim);

            ReferenceShape(newShape);

            prim.PhysShape = newShape;
            return true; // 'true' means a new shape has been added to this prim
        }
Esempio n. 23
0
        private BSShapeNative(BSScene physicsScene, BSPhysObject prim,
            BSPhysicsShapeType shapeType, FixedShapeKey shapeKey)
        {
            ShapeData nativeShapeData = new ShapeData();
            nativeShapeData.Type = shapeType;
            nativeShapeData.ID = prim.LocalID;
            nativeShapeData.Scale = prim.Scale;
            nativeShapeData.Size = prim.Scale;
            nativeShapeData.MeshKey = (ulong)shapeKey;
            nativeShapeData.HullKey = (ulong)shapeKey;

            /*
            if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE)
            {
            ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale);
            physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale);
            }
            else
            {
            ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData);
            }
            if (ptr == IntPtr.Zero)
            {
            physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
                                    LogHeader, prim.LocalID, shapeType);
            }
            type = shapeType;
            key = (UInt64)shapeKey;
             */
        }
        // Compound shapes are always built from scratch.
        // This shouldn't be to bad since most of the parts will be meshes that had been built previously.
        private bool GetReferenceToCompoundShape(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
        {
            // Remove reference to the old shape
            // Don't need to do this as the shape is freed when the new root shape is created below.
            // DereferenceShape(prim.PhysShape, true, shapeCallback);

            BulletShape cShape = PhysicsScene.PE.CreateCompoundShape(PhysicsScene.World, false);

            // Create the shape for the root prim and add it to the compound shape. Cannot be a native shape.
            CreateGeomMeshOrHull(prim, shapeCallback);
            PhysicsScene.PE.AddChildShapeToCompoundShape(cShape, prim.PhysShape, OMV.Vector3.Zero,
                OMV.Quaternion.Identity);
            if (DDetail)
                DetailLog("{0},BSShapeCollection.GetReferenceToCompoundShape,addRootPrim,compShape={1},rootShape={2}",
                    prim.LocalID, cShape, prim.PhysShape);

            prim.PhysShape = cShape;

            return true;
        }
        // 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;

            // 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);
            }
            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
                    )
                {
                    DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID);
                    // Multiple requestors will know we're waiting for this asset
                    prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;

                    BSPhysObject xprim = prim;
                    Util.FireAndForget(delegate
                    {
                        BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
                        PhysicsScene.Scene.AssetService.Get(yprim.BaseShape.SculptTexture.ToString(), null,
                            delegate(string id, Object sender, AssetBase asset)
                            {
                                bool assetFound = false;
                                string mismatchIDs = String.Empty; // DEBUG DEBUG
                                if (asset != null && yprim.BaseShape.SculptEntry)
                                {
                                    if (yprim.BaseShape.SculptTexture == 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.ForceBodyShapeRebuild(false /* inTaintTime */);
                                        assetFound = true;
                                    }
                                    else
                                    {
                                        mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
                                    }
                                }
                                if (assetFound)
                                    yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
                                else
                                    yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
                                DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
                                    yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs);
                            });
                    });
                }
                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);
                    }
                }
            }

            // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object.
            BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX);
            DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID);

            return fillinShape;
        }
Esempio n. 26
0
 public BSActorSetForce(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_forceMotor = null;
     m_physicsScene.DetailLog("{0},BSActorSetForce,constructor", m_controllingPrim.LocalID);
 }
        // The simulation step is telling this object about a collision.
        // Return 'true' if a collision was processed and should be sent up.
        // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
        // Called at taint time from within the Step() function
        public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
            OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
        {
            bool ret = false;
            bool p2col = true;

            // We only need to test p2 for 'jump crouch purposes'
            if (this.TypeName == "BSCharacter" && collidee is BSPrim)
            {
            // Testing if the collision is at the feet of the avatar
            if ((this.Position.Z - contactPoint.Z) < (this.Size.Z * 0.5f))
                p2col = false;
            }

            // The following lines make IsColliding(), CollidingGround() and CollidingObj work
            if (p2col)
            CollidingStep = PhysicsScene.SimulationStep;
            TrueCollidingStep = PhysicsScene.SimulationStep;

            CollisionAccumulation++;

            // For movement tests, remember if we are colliding with an object that is moving.
            ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;

            // If someone has subscribed for collision events log the collision so it will be reported up
            if (SubscribedEvents()) {
            CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth, (ActorTypes)PhysicsActorType));
            DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
                            LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);

            ret = true;
            }
            return ret;
        }
Esempio n. 28
0
 public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
     : base(physicsScene, pObj, actorName)
 {
     m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
     LockAxisConstraint = null;
 }