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);
}
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;
@ -1425,6 +1435,11 @@ public static extern IntPtr CreateMeshShape2(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 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);

View File

@ -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(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
{

View File

@ -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);

View File

@ -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<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
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",
5 ),

View File

@ -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;

View File

@ -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

View File

@ -422,8 +422,21 @@ 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();
@ -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))
{
BSShapeNative nativeShape = new BSShapeNative(pShape);
nativeShape.Dereference(physicsScene);
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
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;
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<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