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.
user_profiles
Robert Adams 2013-05-17 21:17:54 -07:00
parent ece7b33a96
commit 9de3979f5b
7 changed files with 167 additions and 14 deletions

View File

@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world,
BSPhysicsShapeType.SHAPE_MESH); 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) public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls)
{ {
BulletWorldUnman worldu = world as BulletWorldUnman; BulletWorldUnman worldu = world as BulletWorldUnman;
@ -1425,6 +1435,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world,
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); 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] [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern IntPtr CreateHullShape2(IntPtr world, public static extern IntPtr CreateHullShape2(IntPtr world,
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);

View File

@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
ret = BSPhysicsShapeType.SHAPE_UNKNOWN; ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
break; break;
case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
ret = BSPhysicsShapeType.SHAPE_MESH; ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
break; break;
case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
ret = BSPhysicsShapeType.SHAPE_HULL; ret = BSPhysicsShapeType.SHAPE_HULL;
@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
ret = BSPhysicsShapeType.SHAPE_CONE; ret = BSPhysicsShapeType.SHAPE_CONE;
break; break;
case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
ret = BSPhysicsShapeType.SHAPE_UNKNOWN; ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
break; break;
case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
ret = BSPhysicsShapeType.SHAPE_CYLINDER; ret = BSPhysicsShapeType.SHAPE_CYLINDER;
@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
break; break;
///Used for GIMPACT Trimesh integration ///Used for GIMPACT Trimesh integration
case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
ret = BSPhysicsShapeType.SHAPE_MESH; ret = BSPhysicsShapeType.SHAPE_GIMPACT;
break; break;
///Multimaterial mesh ///Multimaterial mesh
case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); 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(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
{ {

View File

@ -71,6 +71,7 @@ public enum BSPhysicsShapeType
SHAPE_HEIGHTMAP = 23, SHAPE_HEIGHTMAP = 23,
SHAPE_AVATAR = 24, SHAPE_AVATAR = 24,
SHAPE_CONVEXHULL= 25, SHAPE_CONVEXHULL= 25,
SHAPE_GIMPACT = 26,
}; };
// The native shapes have predefined shape hash keys // The native shapes have predefined shape hash keys
@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world,
int indicesCount, int[] indices, int indicesCount, int[] indices,
int verticesCount, float[] vertices ); int verticesCount, float[] vertices );
public abstract BulletShape CreateGImpactShape(BulletWorld world,
int indicesCount, int[] indices,
int verticesCount, float[] vertices );
public abstract BulletShape CreateHullShape(BulletWorld world, public abstract BulletShape CreateHullShape(BulletWorld world,
int hullCount, float[] hulls); int hullCount, float[] hulls);

View File

@ -89,6 +89,7 @@ public static class BSParam
public static bool ShouldRemoveZeroWidthTriangles { get; private set; } public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
public static bool ShouldUseBulletHACD { get; set; } public static bool ShouldUseBulletHACD { get; set; }
public static bool ShouldUseSingleConvexHullForPrims { get; set; } public static bool ShouldUseSingleConvexHullForPrims { get; set; }
public static bool ShouldUseGImpactShapeForPrims { get; set; }
public static float TerrainImplementation { get; set; } public static float TerrainImplementation { get; set; }
public static int TerrainMeshMagnification { get; private set; } public static int TerrainMeshMagnification { get; private set; }
@ -369,6 +370,8 @@ public static class BSParam
false ), false ),
new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
true ), true ),
new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
false ),
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
5 ), 5 ),

View File

@ -328,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
BSParam.ShouldUseBulletHACD = false; BSParam.ShouldUseBulletHACD = false;
m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
BSParam.ShouldUseSingleConvexHullForPrims = false; BSParam.ShouldUseSingleConvexHullForPrims = false;
m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader);
BSParam.ShouldUseGImpactShapeForPrims = false;
m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader);
BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
break; break;

View File

@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable
BSShape potentialHull = null; BSShape potentialHull = null;
PrimitiveBaseShape pbs = prim.BaseShape; PrimitiveBaseShape pbs = prim.BaseShape;
// Use a simple, one section convex shape for prims that are probably convex (no cuts or twists)
if (BSParam.ShouldUseSingleConvexHullForPrims if (BSParam.ShouldUseSingleConvexHullForPrims
&& pbs != null && pbs != null
&& !pbs.SculptEntry && !pbs.SculptEntry
@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable
{ {
potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); 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); potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
} }
@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable
} }
else 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); 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 the current shape is not what is on the prim at the moment, time to change.
if (!prim.PhysShape.HasPhysicalShape if (!prim.PhysShape.HasPhysicalShape

View File

@ -422,8 +422,21 @@ public class BSShapeMesh : BSShape
outMesh = foundDesc; outMesh = foundDesc;
return ret; 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, private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 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(); BulletShape newShape = new BulletShape();
@ -482,8 +495,7 @@ public class BSShapeMesh : BSShape
if (realIndicesIndex != 0) if (realIndicesIndex != 0)
{ {
newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
} }
else else
{ {
@ -803,6 +815,7 @@ public class BSShapeCompound : BSShape
// Called at taint-time. // Called at taint-time.
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) 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; BSShapeMesh meshDesc;
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
{ {
@ -824,17 +837,25 @@ public class BSShapeCompound : BSShape
} }
else else
{ {
if (physicsScene.PE.IsCompound(pShape)) BSShapeGImpact gImpactDesc;
if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
{ {
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); gImpactDesc.Dereference(physicsScene);
recursiveCompound.Dereference(physicsScene);
} }
else else
{ {
if (physicsScene.PE.IsNativeShape(pShape)) if (physicsScene.PE.IsCompound(pShape))
{ {
BSShapeNative nativeShape = new BSShapeNative(pShape); BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
nativeShape.Dereference(physicsScene); recursiveCompound.Dereference(physicsScene);
}
else
{
if (physicsScene.PE.IsNativeShape(pShape))
{
BSShapeNative nativeShape = new BSShapeNative(pShape);
nativeShape.Dereference(physicsScene);
}
} }
} }
} }
@ -857,7 +878,7 @@ public class BSShapeConvexHull : BSShape
float lod; float lod;
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out 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); prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
BSShapeConvexHull retConvexHull = null; BSShapeConvexHull retConvexHull = null;
@ -937,6 +958,97 @@ public class BSShapeConvexHull : BSShape
return ret; return ret;
} }
} }
// ============================================================================================================
public class BSShapeGImpact : BSShape
{
private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
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 public class BSShapeAvatar : BSShape