aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs15
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs11
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs5
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs11
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs6
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs15
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs185
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt14
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs131
10 files changed, 352 insertions, 49 deletions
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,
251 BSPhysicsShapeType.SHAPE_MESH); 251 BSPhysicsShapeType.SHAPE_MESH);
252} 252}
253 253
254public override BulletShape CreateGImpactShape(BulletWorld world,
255 int indicesCount, int[] indices,
256 int verticesCount, float[] vertices)
257{
258 BulletWorldUnman worldu = world as BulletWorldUnman;
259 return new BulletShapeUnman(
260 BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices),
261 BSPhysicsShapeType.SHAPE_GIMPACT);
262}
263
254public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) 264public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls)
255{ 265{
256 BulletWorldUnman worldu = world as BulletWorldUnman; 266 BulletWorldUnman worldu = world as BulletWorldUnman;
@@ -1426,6 +1436,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world,
1426 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); 1436 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
1427 1437
1428[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] 1438[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1439public static extern IntPtr CreateGImpactShape2(IntPtr world,
1440 int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
1441 int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
1442
1443[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
1429public static extern IntPtr CreateHullShape2(IntPtr world, 1444public static extern IntPtr CreateHullShape2(IntPtr world,
1430 int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); 1445 int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
1431 1446
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
1475 ret = BSPhysicsShapeType.SHAPE_UNKNOWN; 1475 ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
1476 break; 1476 break;
1477 case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: 1477 case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
1478 ret = BSPhysicsShapeType.SHAPE_MESH; 1478 ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
1479 break; 1479 break;
1480 case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: 1480 case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
1481 ret = BSPhysicsShapeType.SHAPE_HULL; 1481 ret = BSPhysicsShapeType.SHAPE_HULL;
@@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1503 ret = BSPhysicsShapeType.SHAPE_CONE; 1503 ret = BSPhysicsShapeType.SHAPE_CONE;
1504 break; 1504 break;
1505 case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: 1505 case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
1506 ret = BSPhysicsShapeType.SHAPE_UNKNOWN; 1506 ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
1507 break; 1507 break;
1508 case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: 1508 case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
1509 ret = BSPhysicsShapeType.SHAPE_CYLINDER; 1509 ret = BSPhysicsShapeType.SHAPE_CYLINDER;
@@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
1547 break; 1547 break;
1548 ///Used for GIMPACT Trimesh integration 1548 ///Used for GIMPACT Trimesh integration
1549 case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: 1549 case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
1550 ret = BSPhysicsShapeType.SHAPE_MESH; 1550 ret = BSPhysicsShapeType.SHAPE_GIMPACT;
1551 break; 1551 break;
1552 ///Multimaterial mesh 1552 ///Multimaterial mesh
1553 case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: 1553 case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
@@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
1820 return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); 1820 return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH);
1821 1821
1822 } 1822 }
1823 public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
1824 {
1825 // TODO:
1826 return null;
1827 }
1823 public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) 1828 public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
1824 { 1829 {
1825 1830
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
71 SHAPE_HEIGHTMAP = 23, 71 SHAPE_HEIGHTMAP = 23,
72 SHAPE_AVATAR = 24, 72 SHAPE_AVATAR = 24,
73 SHAPE_CONVEXHULL= 25, 73 SHAPE_CONVEXHULL= 25,
74 SHAPE_GIMPACT = 26,
74}; 75};
75 76
76// The native shapes have predefined shape hash keys 77// The native shapes have predefined shape hash keys
@@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world,
321 int indicesCount, int[] indices, 322 int indicesCount, int[] indices,
322 int verticesCount, float[] vertices ); 323 int verticesCount, float[] vertices );
323 324
325public abstract BulletShape CreateGImpactShape(BulletWorld world,
326 int indicesCount, int[] indices,
327 int verticesCount, float[] vertices );
328
324public abstract BulletShape CreateHullShape(BulletWorld world, 329public abstract BulletShape CreateHullShape(BulletWorld world,
325 int hullCount, float[] hulls); 330 int hullCount, float[] hulls);
326 331
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index ff5b6ab..48f842e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject
483 { 483 {
484 // Bullet assumes we know what we are doing when forcing orientation 484 // Bullet assumes we know what we are doing when forcing orientation
485 // so it lets us go against all the rules and just compensates for them later. 485 // so it lets us go against all the rules and just compensates for them later.
486 // This keeps us from flipping the capsule over which the veiwer does not understand. 486 // This forces rotation to be only around the Z axis and doesn't change any of the other axis.
487 ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0); 487 // This keeps us from flipping the capsule over which the veiwer does not understand.
488 float oRoll, oPitch, oYaw;
489 _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
490 OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
491 // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
492 // LocalID, _orientation, OMV.Vector3.UnitX * _orientation,
493 // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
494 ForceOrientation = trimmedOrientation;
488 }); 495 });
489 } 496 }
490 } 497 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index d33292f..5cff668 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -89,6 +89,8 @@ public static class BSParam
89 public static bool ShouldRemoveZeroWidthTriangles { get; private set; } 89 public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
90 public static bool ShouldUseBulletHACD { get; set; } 90 public static bool ShouldUseBulletHACD { get; set; }
91 public static bool ShouldUseSingleConvexHullForPrims { get; set; } 91 public static bool ShouldUseSingleConvexHullForPrims { get; set; }
92 public static bool ShouldUseGImpactShapeForPrims { get; set; }
93 public static bool ShouldUseAssetHulls { get; set; }
92 94
93 public static float TerrainImplementation { get; set; } 95 public static float TerrainImplementation { get; set; }
94 public static int TerrainMeshMagnification { get; private set; } 96 public static int TerrainMeshMagnification { get; private set; }
@@ -369,6 +371,10 @@ public static class BSParam
369 false ), 371 false ),
370 new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", 372 new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
371 true ), 373 true ),
374 new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
375 false ),
376 new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info",
377 false ),
372 378
373 new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", 379 new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
374 5 ), 380 5 ),
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 3f407ce..39f5b0a 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
268 // Do any replacements in the parameters 268 // Do any replacements in the parameters
269 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); 269 m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
270 } 270 }
271 else
272 {
273 BulletEngineName = "BulletUnmanaged";
274 m_physicsLoggingEnabled = false;
275 VehicleLoggingEnabled = false;
276 }
271 277
272 // The material characteristics. 278 // The material characteristics.
273 BSMaterials.InitializeFromDefaults(Params); 279 BSMaterials.InitializeFromDefaults(Params);
@@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
322 BSParam.ShouldUseBulletHACD = false; 328 BSParam.ShouldUseBulletHACD = false;
323 m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); 329 m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
324 BSParam.ShouldUseSingleConvexHullForPrims = false; 330 BSParam.ShouldUseSingleConvexHullForPrims = false;
331 m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader);
332 BSParam.ShouldUseGImpactShapeForPrims = false;
325 m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); 333 m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader);
326 BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; 334 BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
327 break; 335 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
230 BSShape potentialHull = null; 230 BSShape potentialHull = null;
231 231
232 PrimitiveBaseShape pbs = prim.BaseShape; 232 PrimitiveBaseShape pbs = prim.BaseShape;
233 // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists)
233 if (BSParam.ShouldUseSingleConvexHullForPrims 234 if (BSParam.ShouldUseSingleConvexHullForPrims
234 && pbs != null 235 && pbs != null
235 && !pbs.SculptEntry 236 && !pbs.SculptEntry
@@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable
238 { 239 {
239 potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); 240 potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim);
240 } 241 }
241 else 242 // Use the GImpact shape if it is a prim that has some concaveness
243 if (potentialHull == null
244 && BSParam.ShouldUseGImpactShapeForPrims
245 && pbs != null
246 && !pbs.SculptEntry
247 )
248 {
249 potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim);
250 }
251 // If not any of the simple cases, just make a hull
252 if (potentialHull == null)
242 { 253 {
243 potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); 254 potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
244 } 255 }
@@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable
261 } 272 }
262 else 273 else
263 { 274 {
264 // Update prim.BSShape to reference a mesh of this shape. 275 // Non-physical objects should be just meshes.
265 BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); 276 BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
266 // If the current shape is not what is on the prim at the moment, time to change. 277 // If the current shape is not what is on the prim at the moment, time to change.
267 if (!prim.PhysShape.HasPhysicalShape 278 if (!prim.PhysShape.HasPhysicalShape
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index 6b09468..fca4258 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -31,6 +31,7 @@ using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using OpenSim.Region.Physics.Meshing;
34using OpenSim.Region.Physics.ConvexDecompositionDotNet; 35using OpenSim.Region.Physics.ConvexDecompositionDotNet;
35 36
36using OMV = OpenMetaverse; 37using OMV = OpenMetaverse;
@@ -422,9 +423,22 @@ public class BSShapeMesh : BSShape
422 outMesh = foundDesc; 423 outMesh = foundDesc;
423 return ret; 424 return ret;
424 } 425 }
426
427 public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices );
425 private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, 428 private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
426 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 429 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
427 { 430 {
431 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
432 (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) );
433 }
434
435 // Code that uses the mesher to create the index/vertices info for a trimesh shape.
436 // This is used by the passed 'makeShape' call to create the Bullet mesh shape.
437 // The actual build call is passed so this logic can be used by several of the shapes that use a
438 // simple mesh as their base shape.
439 public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
440 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape)
441 {
428 BulletShape newShape = new BulletShape(); 442 BulletShape newShape = new BulletShape();
429 443
430 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, 444 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
@@ -484,8 +498,7 @@ public class BSShapeMesh : BSShape
484 498
485 if (realIndicesIndex != 0) 499 if (realIndicesIndex != 0)
486 { 500 {
487 newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, 501 newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
488 realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
489 } 502 }
490 else 503 else
491 { 504 {
@@ -563,9 +576,56 @@ public class BSShapeHull : BSShape
563 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 576 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
564 { 577 {
565 BulletShape newShape = new BulletShape(); 578 BulletShape newShape = new BulletShape();
566 IntPtr hullPtr = IntPtr.Zero; 579 newShape.shapeKey = newHullKey;
580
581 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
582 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
567 583
568 if (BSParam.ShouldUseBulletHACD) 584 // If there is hull data in the mesh asset, build the hull from that
585 if (meshData != null && BSParam.ShouldUseAssetHulls)
586 {
587 Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
588 if (realMesher != null)
589 {
590 List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size);
591 if (allHulls != null)
592 {
593 int hullCount = allHulls.Count;
594 int totalVertices = 1; // include one for the count of the hulls
595 // Using the structure described for HACD hulls, create the memory sturcture
596 // to pass the hull data to the creater.
597 foreach (List<OMV.Vector3> hullVerts in allHulls)
598 {
599 totalVertices += 4; // add four for the vertex count and centroid
600 totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
601 }
602 float[] convHulls = new float[totalVertices];
603
604 convHulls[0] = (float)hullCount;
605 int jj = 1;
606 foreach (List<OMV.Vector3> hullVerts in allHulls)
607 {
608 convHulls[jj + 0] = hullVerts.Count;
609 convHulls[jj + 1] = 0f; // centroid x,y,z
610 convHulls[jj + 2] = 0f;
611 convHulls[jj + 3] = 0f;
612 jj += 4;
613 foreach (OMV.Vector3 oneVert in hullVerts)
614 {
615 convHulls[jj + 0] = oneVert.X;
616 convHulls[jj + 1] = oneVert.Y;
617 convHulls[jj + 2] = oneVert.Z;
618 jj += 3;
619 }
620 }
621
622 // create the hull data structure in Bullet
623 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
624 }
625 }
626 }
627 // If no hull specified in the asset and we should use Bullet's HACD approximation...
628 if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
569 { 629 {
570 // Build the hull shape from an existing mesh shape. 630 // Build the hull shape from an existing mesh shape.
571 // The mesh should have already been created in Bullet. 631 // The mesh should have already been created in Bullet.
@@ -594,11 +654,10 @@ public class BSShapeHull : BSShape
594 } 654 }
595 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 655 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
596 } 656 }
657 // If no hull specified, use our HACD hull approximation.
597 if (!newShape.HasPhysicalShape) 658 if (!newShape.HasPhysicalShape)
598 { 659 {
599 // Build a new hull in the physical world using the C# HACD algorigthm. 660 // Build a new hull in the physical world using the C# HACD algorigthm.
600 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
601 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
602 if (meshData != null) 661 if (meshData != null)
603 { 662 {
604 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) 663 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
@@ -805,6 +864,7 @@ public class BSShapeCompound : BSShape
805 // Called at taint-time. 864 // Called at taint-time.
806 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) 865 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
807 { 866 {
867 // TODO: figure a better way to go through all the shape types and find a possible instance.
808 BSShapeMesh meshDesc; 868 BSShapeMesh meshDesc;
809 if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) 869 if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
810 { 870 {
@@ -826,17 +886,25 @@ public class BSShapeCompound : BSShape
826 } 886 }
827 else 887 else
828 { 888 {
829 if (physicsScene.PE.IsCompound(pShape)) 889 BSShapeGImpact gImpactDesc;
890 if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
830 { 891 {
831 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); 892 gImpactDesc.Dereference(physicsScene);
832 recursiveCompound.Dereference(physicsScene);
833 } 893 }
834 else 894 else
835 { 895 {
836 if (physicsScene.PE.IsNativeShape(pShape)) 896 if (physicsScene.PE.IsCompound(pShape))
837 { 897 {
838 BSShapeNative nativeShape = new BSShapeNative(pShape); 898 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
839 nativeShape.Dereference(physicsScene); 899 recursiveCompound.Dereference(physicsScene);
900 }
901 else
902 {
903 if (physicsScene.PE.IsNativeShape(pShape))
904 {
905 BSShapeNative nativeShape = new BSShapeNative(pShape);
906 nativeShape.Dereference(physicsScene);
907 }
840 } 908 }
841 } 909 }
842 } 910 }
@@ -859,7 +927,7 @@ public class BSShapeConvexHull : BSShape
859 float lod; 927 float lod;
860 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 928 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
861 929
862 physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", 930 physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}",
863 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); 931 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
864 932
865 BSShapeConvexHull retConvexHull = null; 933 BSShapeConvexHull retConvexHull = null;
@@ -939,6 +1007,97 @@ public class BSShapeConvexHull : BSShape
939 return ret; 1007 return ret;
940 } 1008 }
941} 1009}
1010// ============================================================================================================
1011public class BSShapeGImpact : BSShape
1012{
1013 private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
1014 public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
1015
1016 public BSShapeGImpact(BulletShape pShape) : base(pShape)
1017 {
1018 }
1019 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
1020 {
1021 float lod;
1022 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
1023
1024 physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}",
1025 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
1026
1027 BSShapeGImpact retGImpact = null;
1028 lock (GImpacts)
1029 {
1030 if (GImpacts.TryGetValue(newMeshKey, out retGImpact))
1031 {
1032 // The mesh has already been created. Return a new reference to same.
1033 retGImpact.IncrementReference();
1034 }
1035 else
1036 {
1037 retGImpact = new BSShapeGImpact(new BulletShape());
1038 BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
1039
1040 // Check to see if mesh was created (might require an asset).
1041 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
1042 if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
1043 {
1044 // If a mesh was what was created, remember the built shape for later sharing.
1045 // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh.
1046 GImpacts.Add(newMeshKey, retGImpact);
1047 }
1048
1049 retGImpact.physShapeInfo = newShape;
1050 }
1051 }
1052 return retGImpact;
1053 }
1054
1055 private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
1056 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
1057 {
1058 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
1059 (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) );
1060 }
1061
1062 public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
1063 {
1064 // Calling this reference means we want another handle to an existing shape
1065 // (usually linksets) so return this copy.
1066 IncrementReference();
1067 return this;
1068 }
1069 // Dereferencing a compound shape releases the hold on all the child shapes.
1070 public override void Dereference(BSScene physicsScene)
1071 {
1072 lock (GImpacts)
1073 {
1074 this.DecrementReference();
1075 physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this);
1076 // TODO: schedule aging and destruction of unused meshes.
1077 }
1078 }
1079 // Loop through all the known hulls and return the description based on the physical address.
1080 public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull)
1081 {
1082 bool ret = false;
1083 BSShapeGImpact foundDesc = null;
1084 lock (GImpacts)
1085 {
1086 foreach (BSShapeGImpact sh in GImpacts.Values)
1087 {
1088 if (sh.physShapeInfo.ReferenceSame(pShape))
1089 {
1090 foundDesc = sh;
1091 ret = true;
1092 break;
1093 }
1094
1095 }
1096 }
1097 outHull = foundDesc;
1098 return ret;
1099 }
1100}
942 1101
943// ============================================================================================================ 1102// ============================================================================================================
944public class BSShapeAvatar : BSShape 1103public class BSShapeAvatar : BSShape
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
index 5792ae6..df1da63 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
+++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt
@@ -1,16 +1,12 @@
1PROBLEMS TO LOOK INTO 1CURRENT PROBLEMS TO FIX AND/OR LOOK AT
2================================================= 2=================================================
3Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly. 3Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
4 the wheel to appear to jump back. Looks like sending position from previous update.
5Vehicle ride, get up, ride again. Second time vehicle does not act correctly.
4 Have to rez new vehicle and delete the old to fix situation. 6 Have to rez new vehicle and delete the old to fix situation.
5Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd 7Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd
6 position state where it will not settle onto ground properly, etc 8 position state where it will not settle onto ground properly, etc
7Two of Nebadon vehicles in a sim max the CPU. This is new. 9Two of Nebadon vehicles in a sim max the CPU. This is new.
8A sitting, active vehicle bobs up and down a small amount.
9
10CURRENT PRIORITIES
11=================================================
12Use the HACD convex hull routine in Bullet rather than the C# version.
13 Speed up hullifying large meshes.
14Enable vehicle border crossings (at least as poorly as ODE) 10Enable vehicle border crossings (at least as poorly as ODE)
15 Terrain skirts 11 Terrain skirts
16 Avatar created in previous region and not new region when crossing border 12 Avatar created in previous region and not new region when crossing border
@@ -361,4 +357,6 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
361Nebadon vehicles turning funny in arena (DONE) 357Nebadon vehicles turning funny in arena (DONE)
362Lock axis (DONE 20130401) 358Lock axis (DONE 20130401)
363Terrain detail: double terrain mesh detail (DONE) 359Terrain detail: double terrain mesh detail (DONE)
360Use the HACD convex hull routine in Bullet rather than the C# version.
361 Speed up hullifying large meshes. (DONE)
364 362
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 42929ec..db5d962 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Meshing
79 79
80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
81 81
82 private List<List<Vector3>> mConvexHulls = null;
83
82 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 84 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
83 85
84 public Meshmerizer(IConfigSource config) 86 public Meshmerizer(IConfigSource config)
@@ -363,6 +365,57 @@ namespace OpenSim.Region.Physics.Meshing
363 else if (map.ContainsKey("high_lod")) 365 else if (map.ContainsKey("high_lod"))
364 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) 366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
365 367
368 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it
370 try
371 {
372 OSDMap convexBlock = (OSDMap)map["physics_convex"];
373 if (convexBlock.ContainsKey("HullList"))
374 {
375 byte[] hullList = convexBlock["HullList"].AsBinary();
376 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
377 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
378 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
379 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
380
381 // decompress and decode hull points
382 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
383
384 List<List<Vector3>> hulls = new List<List<Vector3>>();
385 int posNdx = 0;
386
387 foreach (byte cnt in hullList)
388 {
389 int count = cnt == 0 ? 256 : cnt;
390 List<Vector3> hull = new List<Vector3>();
391
392 for (int i = 0; i < count; i++)
393 {
394 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
395 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
396 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
397
398 Vector3 pos = new Vector3(
399 Utils.UInt16ToFloat(uX, min.X, max.X),
400 Utils.UInt16ToFloat(uY, min.Y, max.Y),
401 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
402 );
403
404 hull.Add(pos);
405 }
406
407 hulls.Add(hull);
408 }
409
410 mConvexHulls = hulls;
411 }
412 }
413 catch (Exception e)
414 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message);
416 }
417 }
418
366 if (physicsParms == null) 419 if (physicsParms == null)
367 { 420 {
368 m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); 421 m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
@@ -381,27 +434,7 @@ namespace OpenSim.Region.Physics.Meshing
381// byte[] decompressed = new byte[physSize * 5]; 434// byte[] decompressed = new byte[physSize * 5];
382 try 435 try
383 { 436 {
384 using (MemoryStream inMs = new MemoryStream(meshBytes)) 437 decodedMeshOsd = DecompressOsd(meshBytes);
385 {
386 using (MemoryStream outMs = new MemoryStream())
387 {
388 using (ZOutputStream zOut = new ZOutputStream(outMs))
389 {
390 byte[] readBuffer = new byte[2048];
391 int readLen = 0;
392 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
393 {
394 zOut.Write(readBuffer, 0, readLen);
395 }
396 zOut.Flush();
397 outMs.Seek(0, SeekOrigin.Begin);
398
399 byte[] decompressedBuf = outMs.GetBuffer();
400
401 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
402 }
403 }
404 }
405 } 438 }
406 catch (Exception e) 439 catch (Exception e)
407 { 440 {
@@ -428,6 +461,41 @@ namespace OpenSim.Region.Physics.Meshing
428 return true; 461 return true;
429 } 462 }
430 463
464
465 /// <summary>
466 /// decompresses a gzipped OSD object
467 /// </summary>
468 /// <param name="decodedOsd"></param> the OSD object
469 /// <param name="meshBytes"></param>
470 /// <returns></returns>
471 private static OSD DecompressOsd(byte[] meshBytes)
472 {
473 OSD decodedOsd = null;
474
475 using (MemoryStream inMs = new MemoryStream(meshBytes))
476 {
477 using (MemoryStream outMs = new MemoryStream())
478 {
479 using (ZOutputStream zOut = new ZOutputStream(outMs))
480 {
481 byte[] readBuffer = new byte[2048];
482 int readLen = 0;
483 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
484 {
485 zOut.Write(readBuffer, 0, readLen);
486 }
487 zOut.Flush();
488 outMs.Seek(0, SeekOrigin.Begin);
489
490 byte[] decompressedBuf = outMs.GetBuffer();
491
492 decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
493 }
494 }
495 }
496 return decodedOsd;
497 }
498
431 /// <summary> 499 /// <summary>
432 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. 500 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
433 /// </summary> 501 /// </summary>
@@ -704,6 +772,27 @@ namespace OpenSim.Region.Physics.Meshing
704 return true; 772 return true;
705 } 773 }
706 774
775 /// <summary>
776 /// temporary prototype code - please do not use until the interface has been finalized!
777 /// </summary>
778 /// <param name="size">value to scale the hull points by</param>
779 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns>
780 public List<List<Vector3>> GetConvexHulls(Vector3 size)
781 {
782 if (mConvexHulls == null)
783 return null;
784
785 List<List<Vector3>> hulls = new List<List<Vector3>>();
786 foreach (var hull in mConvexHulls)
787 {
788 List<Vector3> verts = new List<Vector3>();
789 foreach (var vert in hull)
790 verts.Add(vert * size);
791 }
792
793 return hulls;
794 }
795
707 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 796 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
708 { 797 {
709 return CreateMesh(primName, primShape, size, lod, false, true); 798 return CreateMesh(primName, primShape, size, lod, false, true);