From 9de3979f5b91ae4bf9b05b89ec59999c43514f90 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 17 May 2013 21:17:54 -0700 Subject: BulletSim: add gImpact shape type. Add logic to use gImpact shape for prims that have cuts or holes. Default logic to 'off' as it needs debugging. --- OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 15 +++ OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 11 +- .../Region/Physics/BulletSPlugin/BSApiTemplate.cs | 5 + OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 3 + OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 2 + .../Physics/BulletSPlugin/BSShapeCollection.cs | 15 ++- OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 130 +++++++++++++++++++-- 7 files changed, 167 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 231f0f8..12a0c17 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs @@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world, BSPhysicsShapeType.SHAPE_MESH); } +public override BulletShape CreateGImpactShape(BulletWorld world, + int indicesCount, int[] indices, + int verticesCount, float[] vertices) +{ + BulletWorldUnman worldu = world as BulletWorldUnman; + return new BulletShapeUnman( + BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices), + BSPhysicsShapeType.SHAPE_GIMPACT); +} + public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) { BulletWorldUnman worldu = world as BulletWorldUnman; @@ -1426,6 +1436,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world, int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] +public static extern IntPtr CreateGImpactShape2(IntPtr world, + int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, + int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); + +[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] public static extern IntPtr CreateHullShape2(IntPtr world, int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 59780ae..6db5f5e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs @@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint ret = BSPhysicsShapeType.SHAPE_UNKNOWN; break; case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: - ret = BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; break; case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: ret = BSPhysicsShapeType.SHAPE_HULL; @@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint ret = BSPhysicsShapeType.SHAPE_CONE; break; case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: - ret = BSPhysicsShapeType.SHAPE_UNKNOWN; + ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; break; case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: ret = BSPhysicsShapeType.SHAPE_CYLINDER; @@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint break; ///Used for GIMPACT Trimesh integration case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: - ret = BSPhysicsShapeType.SHAPE_MESH; + ret = BSPhysicsShapeType.SHAPE_GIMPACT; break; ///Multimaterial mesh case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: @@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); } + public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) + { + // TODO: + return null; + } public static void DumpRaw(ObjectArrayindices, ObjectArray vertices, int pIndicesCount,int pVerticesCount ) { diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 3378c93..6cdc112 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs @@ -71,6 +71,7 @@ public enum BSPhysicsShapeType SHAPE_HEIGHTMAP = 23, SHAPE_AVATAR = 24, SHAPE_CONVEXHULL= 25, + SHAPE_GIMPACT = 26, }; // The native shapes have predefined shape hash keys @@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); +public abstract BulletShape CreateGImpactShape(BulletWorld world, + int indicesCount, int[] indices, + int verticesCount, float[] vertices ); + public abstract BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls); diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index d33292f..9a9e527 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs @@ -89,6 +89,7 @@ public static class BSParam public static bool ShouldRemoveZeroWidthTriangles { get; private set; } public static bool ShouldUseBulletHACD { get; set; } public static bool ShouldUseSingleConvexHullForPrims { get; set; } + public static bool ShouldUseGImpactShapeForPrims { get; set; } public static float TerrainImplementation { get; set; } public static int TerrainMeshMagnification { get; private set; } @@ -369,6 +370,8 @@ public static class BSParam false ), new ParameterDefn("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", true ), + new ParameterDefn("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", + false ), new ParameterDefn("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", 5 ), diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 9ed2d06..39f5b0a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs @@ -328,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters BSParam.ShouldUseBulletHACD = false; m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); BSParam.ShouldUseSingleConvexHullForPrims = false; + m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader); + BSParam.ShouldUseGImpactShapeForPrims = false; m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; break; diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 64aaa15..32bbc8f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs @@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable BSShape potentialHull = null; PrimitiveBaseShape pbs = prim.BaseShape; + // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists) if (BSParam.ShouldUseSingleConvexHullForPrims && pbs != null && !pbs.SculptEntry @@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable { potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); } - else + // Use the GImpact shape if it is a prim that has some concaveness + if (potentialHull == null + && BSParam.ShouldUseGImpactShapeForPrims + && pbs != null + && !pbs.SculptEntry + ) + { + potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim); + } + // If not any of the simple cases, just make a hull + if (potentialHull == null) { potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); } @@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable } else { - // Update prim.BSShape to reference a mesh of this shape. + // Non-physical objects should be just meshes. BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); // If the current shape is not what is on the prim at the moment, time to change. if (!prim.PhysShape.HasPhysicalShape diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 72d039b..0152233 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs @@ -422,9 +422,22 @@ public class BSShapeMesh : BSShape outMesh = foundDesc; return ret; } + + public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) { + return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, + (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); + } + + // Code that uses the mesher to create the index/vertices info for a trimesh shape. + // This is used by the passed 'makeShape' call to create the Bullet mesh shape. + // The actual build call is passed so this logic can be used by several of the shapes that use a + // simple mesh as their base shape. + public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, + PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) + { BulletShape newShape = new BulletShape(); IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, @@ -482,8 +495,7 @@ public class BSShapeMesh : BSShape if (realIndicesIndex != 0) { - newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, - realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); + newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); } else { @@ -803,6 +815,7 @@ public class BSShapeCompound : BSShape // 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. BSShapeMesh meshDesc; if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) { @@ -824,17 +837,25 @@ public class BSShapeCompound : BSShape } else { - if (physicsScene.PE.IsCompound(pShape)) + BSShapeGImpact gImpactDesc; + if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) { - BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); - recursiveCompound.Dereference(physicsScene); + gImpactDesc.Dereference(physicsScene); } else { - if (physicsScene.PE.IsNativeShape(pShape)) + if (physicsScene.PE.IsCompound(pShape)) + { + BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); + recursiveCompound.Dereference(physicsScene); + } + else { - BSShapeNative nativeShape = new BSShapeNative(pShape); - nativeShape.Dereference(physicsScene); + if (physicsScene.PE.IsNativeShape(pShape)) + { + BSShapeNative nativeShape = new BSShapeNative(pShape); + nativeShape.Dereference(physicsScene); + } } } } @@ -857,7 +878,7 @@ public class BSShapeConvexHull : BSShape float lod; System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); - physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", + physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); BSShapeConvexHull retConvexHull = null; @@ -937,6 +958,97 @@ public class BSShapeConvexHull : BSShape return ret; } } +// ============================================================================================================ +public class BSShapeGImpact : BSShape +{ + private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; + public static Dictionary GImpacts = new Dictionary(); + + public BSShapeGImpact(BulletShape pShape) : base(pShape) + { + } + public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) + { + float lod; + System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); + + physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", + prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); + + BSShapeGImpact retGImpact = null; + lock (GImpacts) + { + if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) + { + // The mesh has already been created. Return a new reference to same. + retGImpact.IncrementReference(); + } + else + { + retGImpact = new BSShapeGImpact(new BulletShape()); + BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); + + // Check to see if mesh was created (might require an asset). + newShape = VerifyMeshCreated(physicsScene, newShape, prim); + if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) + { + // If a mesh was what was created, remember the built shape for later sharing. + // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. + GImpacts.Add(newMeshKey, retGImpact); + } + + retGImpact.physShapeInfo = newShape; + } + } + return retGImpact; + } + + private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, + PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) + { + return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, + (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); + } + + public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) + { + // Calling this reference means we want another handle to an existing shape + // (usually linksets) so return this copy. + IncrementReference(); + return this; + } + // Dereferencing a compound shape releases the hold on all the child shapes. + public override void Dereference(BSScene physicsScene) + { + lock (GImpacts) + { + this.DecrementReference(); + physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); + // TODO: schedule aging and destruction of unused meshes. + } + } + // Loop through all the known hulls and return the description based on the physical address. + public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) + { + bool ret = false; + BSShapeGImpact foundDesc = null; + lock (GImpacts) + { + foreach (BSShapeGImpact sh in GImpacts.Values) + { + if (sh.physShapeInfo.ReferenceSame(pShape)) + { + foundDesc = sh; + ret = true; + break; + } + + } + } + outHull = foundDesc; + return ret; + } +} // ============================================================================================================ public class BSShapeAvatar : BSShape -- cgit v1.1