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
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs3
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs9
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs5
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs8
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs15
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs415
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt14
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs152
12 files changed, 504 insertions, 159 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/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
index c16b7d3..311cf4f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs
@@ -617,7 +617,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
617 // Vehicles report collision events so we know when it's on the ground 617 // Vehicles report collision events so we know when it's on the ground
618 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS); 618 m_physicsScene.PE.AddToCollisionFlags(ControllingPrim.PhysBody, CollisionFlags.BS_VEHICLE_COLLISIONS);
619 619
620 ControllingPrim.Inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass); 620 Vector3 inertia = m_physicsScene.PE.CalculateLocalInertia(ControllingPrim.PhysShape.physShapeInfo, m_vehicleMass);
621 ControllingPrim.Inertia = inertia * BSParam.VehicleInertiaFactor;
621 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia); 622 m_physicsScene.PE.SetMassProps(ControllingPrim.PhysBody, m_vehicleMass, ControllingPrim.Inertia);
622 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody); 623 m_physicsScene.PE.UpdateInertiaTensor(ControllingPrim.PhysBody);
623 624
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index d33292f..2651e3b 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; }
@@ -146,6 +148,7 @@ public static class BSParam
146 public static float VehicleRestitution { get; private set; } 148 public static float VehicleRestitution { get; private set; }
147 public static Vector3 VehicleLinearFactor { get; private set; } 149 public static Vector3 VehicleLinearFactor { get; private set; }
148 public static Vector3 VehicleAngularFactor { get; private set; } 150 public static Vector3 VehicleAngularFactor { get; private set; }
151 public static Vector3 VehicleInertiaFactor { get; private set; }
149 public static float VehicleGroundGravityFudge { get; private set; } 152 public static float VehicleGroundGravityFudge { get; private set; }
150 public static float VehicleAngularBankingTimescaleFudge { get; private set; } 153 public static float VehicleAngularBankingTimescaleFudge { get; private set; }
151 public static bool VehicleDebuggingEnable { get; private set; } 154 public static bool VehicleDebuggingEnable { get; private set; }
@@ -369,6 +372,10 @@ public static class BSParam
369 false ), 372 false ),
370 new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", 373 new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
371 true ), 374 true ),
375 new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
376 false ),
377 new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info",
378 true ),
372 379
373 new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", 380 new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
374 5 ), 381 5 ),
@@ -577,6 +584,8 @@ public static class BSParam
577 new Vector3(1f, 1f, 1f) ), 584 new Vector3(1f, 1f, 1f) ),
578 new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)", 585 new ParameterDefn<Vector3>("VehicleAngularFactor", "Fraction of physical angular changes applied to vehicle (<0,0,0> to <1,1,1>)",
579 new Vector3(1f, 1f, 1f) ), 586 new Vector3(1f, 1f, 1f) ),
587 new ParameterDefn<Vector3>("VehicleInertiaFactor", "Fraction of physical inertia applied (<0,0,0> to <1,1,1>)",
588 new Vector3(1f, 1f, 1f) ),
580 new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)", 589 new ParameterDefn<float>("VehicleFriction", "Friction of vehicle on the ground (0.0 - 1.0)",
581 0.0f ), 590 0.0f ),
582 new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)", 591 new ParameterDefn<float>("VehicleRestitution", "Bouncyness factor for vehicles (0.0 - 1.0)",
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index f5b0361..e11e365 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -511,7 +511,10 @@ public class BSPrim : BSPhysObject
511 511
512 PhysScene.TaintedObject("setVehicleType", delegate() 512 PhysScene.TaintedObject("setVehicleType", delegate()
513 { 513 {
514 ZeroMotion(true /* inTaintTime */); 514 // Some vehicle scripts change vehicle type on the fly as an easy way to
515 // change all the parameters. Like a plane changing to CAR when on the
516 // ground. In this case, don't want to zero motion.
517 // ZeroMotion(true /* inTaintTime */);
515 VehicleActor.ProcessTypeChange(type); 518 VehicleActor.ProcessTypeChange(type);
516 ActivateIfPhysical(false); 519 ActivateIfPhysical(false);
517 }); 520 });
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 72d039b..81edc12 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,15 +423,32 @@ 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 = null;
431 false, // say it is not physical so a bounding box is not built 445 lock (physicsScene.mesher)
432 false // do not cache the mesh and do not use previously built versions 446 {
433 ); 447 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
448 false, // say it is not physical so a bounding box is not built
449 false // do not cache the mesh and do not use previously built versions
450 );
451 }
434 452
435 if (meshData != null) 453 if (meshData != null)
436 { 454 {
@@ -482,8 +500,7 @@ public class BSShapeMesh : BSShape
482 500
483 if (realIndicesIndex != 0) 501 if (realIndicesIndex != 0)
484 { 502 {
485 newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, 503 newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
486 realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
487 } 504 }
488 else 505 else
489 { 506 {
@@ -561,13 +578,74 @@ public class BSShapeHull : BSShape
561 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 578 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
562 { 579 {
563 BulletShape newShape = new BulletShape(); 580 BulletShape newShape = new BulletShape();
564 IntPtr hullPtr = IntPtr.Zero;
565 581
566 if (BSParam.ShouldUseBulletHACD) 582 IMesh meshData = null;
583 List<List<OMV.Vector3>> allHulls = null;
584 lock (physicsScene.mesher)
585 {
586 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
587 meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
588
589 // If we should use the asset's hull info, fetch it out of the locked mesher
590 if (meshData != null && BSParam.ShouldUseAssetHulls)
591 {
592 Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
593 if (realMesher != null)
594 {
595 allHulls = realMesher.GetConvexHulls(size);
596 }
597 if (allHulls == null)
598 {
599 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID);
600 }
601 }
602 }
603
604 // If there is hull data in the mesh asset, build the hull from that
605 if (allHulls != null && BSParam.ShouldUseAssetHulls)
606 {
607 int hullCount = allHulls.Count;
608 int totalVertices = 1; // include one for the count of the hulls
609 // Using the structure described for HACD hulls, create the memory sturcture
610 // to pass the hull data to the creater.
611 foreach (List<OMV.Vector3> hullVerts in allHulls)
612 {
613 totalVertices += 4; // add four for the vertex count and centroid
614 totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
615 }
616 float[] convHulls = new float[totalVertices];
617
618 convHulls[0] = (float)hullCount;
619 int jj = 1;
620 foreach (List<OMV.Vector3> hullVerts in allHulls)
621 {
622 convHulls[jj + 0] = hullVerts.Count;
623 convHulls[jj + 1] = 0f; // centroid x,y,z
624 convHulls[jj + 2] = 0f;
625 convHulls[jj + 3] = 0f;
626 jj += 4;
627 foreach (OMV.Vector3 oneVert in hullVerts)
628 {
629 convHulls[jj + 0] = oneVert.X;
630 convHulls[jj + 1] = oneVert.Y;
631 convHulls[jj + 2] = oneVert.Z;
632 jj += 3;
633 }
634 }
635
636 // create the hull data structure in Bullet
637 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
638
639 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}",
640 prim.LocalID, hullCount, totalVertices, newShape);
641 }
642
643 // If no hull specified in the asset and we should use Bullet's HACD approximation...
644 if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
567 { 645 {
568 // Build the hull shape from an existing mesh shape. 646 // Build the hull shape from an existing mesh shape.
569 // The mesh should have already been created in Bullet. 647 // The mesh should have already been created in Bullet.
570 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); 648 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID);
571 BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); 649 BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
572 650
573 if (meshShape.physShapeInfo.HasPhysicalShape) 651 if (meshShape.physShapeInfo.HasPhysicalShape)
@@ -585,129 +663,125 @@ public class BSShapeHull : BSShape
585 663
586 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); 664 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
587 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); 665 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
588 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 666 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
589 667
590 // Now done with the mesh shape. 668 // Now done with the mesh shape.
591 meshShape.Dereference(physicsScene); 669 meshShape.Dereference(physicsScene);
592 } 670 }
593 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 671 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
594 } 672 }
595 if (!newShape.HasPhysicalShape) 673
674 // If no other hull specifications, use our HACD hull approximation.
675 if (!newShape.HasPhysicalShape && meshData != null)
596 { 676 {
597 // Build a new hull in the physical world using the C# HACD algorigthm. 677 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
598 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
599 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
600 if (meshData != null)
601 { 678 {
602 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) 679 // Release the fetched asset data once it has been used.
603 { 680 pbs.SculptData = new byte[0];
604 // Release the fetched asset data once it has been used. 681 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
605 pbs.SculptData = new byte[0]; 682 }
606 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
607 }
608 683
609 int[] indices = meshData.getIndexListAsInt(); 684 int[] indices = meshData.getIndexListAsInt();
610 List<OMV.Vector3> vertices = meshData.getVertexList(); 685 List<OMV.Vector3> vertices = meshData.getVertexList();
611 686
612 //format conversion from IMesh format to DecompDesc format 687 //format conversion from IMesh format to DecompDesc format
613 List<int> convIndices = new List<int>(); 688 List<int> convIndices = new List<int>();
614 List<float3> convVertices = new List<float3>(); 689 List<float3> convVertices = new List<float3>();
615 for (int ii = 0; ii < indices.GetLength(0); ii++) 690 for (int ii = 0; ii < indices.GetLength(0); ii++)
616 { 691 {
617 convIndices.Add(indices[ii]); 692 convIndices.Add(indices[ii]);
618 } 693 }
619 foreach (OMV.Vector3 vv in vertices) 694 foreach (OMV.Vector3 vv in vertices)
620 { 695 {
621 convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); 696 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
622 } 697 }
623 698
624 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; 699 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
625 if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) 700 if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
701 {
702 // Simple primitive shapes we know are convex so they are better implemented with
703 // fewer hulls.
704 // Check for simple shape (prim without cuts) and reduce split parameter if so.
705 if (BSShapeCollection.PrimHasNoCuts(pbs))
626 { 706 {
627 // Simple primitive shapes we know are convex so they are better implemented with 707 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
628 // fewer hulls.
629 // Check for simple shape (prim without cuts) and reduce split parameter if so.
630 if (BSShapeCollection.PrimHasNoCuts(pbs))
631 {
632 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
633 }
634 } 708 }
709 }
710
711 // setup and do convex hull conversion
712 m_hulls = new List<ConvexResult>();
713 DecompDesc dcomp = new DecompDesc();
714 dcomp.mIndices = convIndices;
715 dcomp.mVertices = convVertices;
716 dcomp.mDepth = maxDepthSplit;
717 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
718 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
719 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
720 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
721 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
722 // create the hull into the _hulls variable
723 convexBuilder.process(dcomp);
724
725 physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
726 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
727
728 // Convert the vertices and indices for passing to unmanaged.
729 // The hull information is passed as a large floating point array.
730 // The format is:
731 // convHulls[0] = number of hulls
732 // convHulls[1] = number of vertices in first hull
733 // convHulls[2] = hull centroid X coordinate
734 // convHulls[3] = hull centroid Y coordinate
735 // convHulls[4] = hull centroid Z coordinate
736 // convHulls[5] = first hull vertex X
737 // convHulls[6] = first hull vertex Y
738 // convHulls[7] = first hull vertex Z
739 // convHulls[8] = second hull vertex X
740 // ...
741 // convHulls[n] = number of vertices in second hull
742 // convHulls[n+1] = second hull centroid X coordinate
743 // ...
744 //
745 // TODO: is is very inefficient. Someday change the convex hull generator to return
746 // data structures that do not need to be converted in order to pass to Bullet.
747 // And maybe put the values directly into pinned memory rather than marshaling.
748 int hullCount = m_hulls.Count;
749 int totalVertices = 1; // include one for the count of the hulls
750 foreach (ConvexResult cr in m_hulls)
751 {
752 totalVertices += 4; // add four for the vertex count and centroid
753 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
754 }
755 float[] convHulls = new float[totalVertices];
635 756
636 // setup and do convex hull conversion 757 convHulls[0] = (float)hullCount;
637 m_hulls = new List<ConvexResult>(); 758 int jj = 1;
638 DecompDesc dcomp = new DecompDesc(); 759 foreach (ConvexResult cr in m_hulls)
639 dcomp.mIndices = convIndices; 760 {
640 dcomp.mVertices = convVertices; 761 // copy vertices for index access
641 dcomp.mDepth = maxDepthSplit; 762 float3[] verts = new float3[cr.HullVertices.Count];
642 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; 763 int kk = 0;
643 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; 764 foreach (float3 ff in cr.HullVertices)
644 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
645 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
646 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
647 // create the hull into the _hulls variable
648 convexBuilder.process(dcomp);
649
650 physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
651 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
652
653 // Convert the vertices and indices for passing to unmanaged.
654 // The hull information is passed as a large floating point array.
655 // The format is:
656 // convHulls[0] = number of hulls
657 // convHulls[1] = number of vertices in first hull
658 // convHulls[2] = hull centroid X coordinate
659 // convHulls[3] = hull centroid Y coordinate
660 // convHulls[4] = hull centroid Z coordinate
661 // convHulls[5] = first hull vertex X
662 // convHulls[6] = first hull vertex Y
663 // convHulls[7] = first hull vertex Z
664 // convHulls[8] = second hull vertex X
665 // ...
666 // convHulls[n] = number of vertices in second hull
667 // convHulls[n+1] = second hull centroid X coordinate
668 // ...
669 //
670 // TODO: is is very inefficient. Someday change the convex hull generator to return
671 // data structures that do not need to be converted in order to pass to Bullet.
672 // And maybe put the values directly into pinned memory rather than marshaling.
673 int hullCount = m_hulls.Count;
674 int totalVertices = 1; // include one for the count of the hulls
675 foreach (ConvexResult cr in m_hulls)
676 { 765 {
677 totalVertices += 4; // add four for the vertex count and centroid 766 verts[kk++] = ff;
678 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
679 } 767 }
680 float[] convHulls = new float[totalVertices];
681 768
682 convHulls[0] = (float)hullCount; 769 // add to the array one hull's worth of data
683 int jj = 1; 770 convHulls[jj++] = cr.HullIndices.Count;
684 foreach (ConvexResult cr in m_hulls) 771 convHulls[jj++] = 0f; // centroid x,y,z
772 convHulls[jj++] = 0f;
773 convHulls[jj++] = 0f;
774 foreach (int ind in cr.HullIndices)
685 { 775 {
686 // copy vertices for index access 776 convHulls[jj++] = verts[ind].x;
687 float3[] verts = new float3[cr.HullVertices.Count]; 777 convHulls[jj++] = verts[ind].y;
688 int kk = 0; 778 convHulls[jj++] = verts[ind].z;
689 foreach (float3 ff in cr.HullVertices)
690 {
691 verts[kk++] = ff;
692 }
693
694 // add to the array one hull's worth of data
695 convHulls[jj++] = cr.HullIndices.Count;
696 convHulls[jj++] = 0f; // centroid x,y,z
697 convHulls[jj++] = 0f;
698 convHulls[jj++] = 0f;
699 foreach (int ind in cr.HullIndices)
700 {
701 convHulls[jj++] = verts[ind].x;
702 convHulls[jj++] = verts[ind].y;
703 convHulls[jj++] = verts[ind].z;
704 }
705 } 779 }
706 // create the hull data structure in Bullet
707 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
708 } 780 }
709 newShape.shapeKey = newHullKey; 781 // create the hull data structure in Bullet
782 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
710 } 783 }
784 newShape.shapeKey = newHullKey;
711 return newShape; 785 return newShape;
712 } 786 }
713 // Callback from convex hull creater with a newly created hull. 787 // Callback from convex hull creater with a newly created hull.
@@ -803,6 +877,7 @@ public class BSShapeCompound : BSShape
803 // Called at taint-time. 877 // Called at taint-time.
804 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) 878 private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
805 { 879 {
880 // TODO: figure a better way to go through all the shape types and find a possible instance.
806 BSShapeMesh meshDesc; 881 BSShapeMesh meshDesc;
807 if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) 882 if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
808 { 883 {
@@ -824,17 +899,27 @@ public class BSShapeCompound : BSShape
824 } 899 }
825 else 900 else
826 { 901 {
827 if (physicsScene.PE.IsCompound(pShape)) 902 BSShapeGImpact gImpactDesc;
903 if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
828 { 904 {
829 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); 905 gImpactDesc.Dereference(physicsScene);
830 recursiveCompound.Dereference(physicsScene);
831 } 906 }
832 else 907 else
833 { 908 {
834 if (physicsScene.PE.IsNativeShape(pShape)) 909 // Didn't find it in the lists of specific types. It could be compound.
910 if (physicsScene.PE.IsCompound(pShape))
911 {
912 BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
913 recursiveCompound.Dereference(physicsScene);
914 }
915 else
835 { 916 {
836 BSShapeNative nativeShape = new BSShapeNative(pShape); 917 // If none of the above, maybe it is a simple native shape.
837 nativeShape.Dereference(physicsScene); 918 if (physicsScene.PE.IsNativeShape(pShape))
919 {
920 BSShapeNative nativeShape = new BSShapeNative(pShape);
921 nativeShape.Dereference(physicsScene);
922 }
838 } 923 }
839 } 924 }
840 } 925 }
@@ -857,7 +942,7 @@ public class BSShapeConvexHull : BSShape
857 float lod; 942 float lod;
858 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); 943 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
859 944
860 physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", 945 physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}",
861 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); 946 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
862 947
863 BSShapeConvexHull retConvexHull = null; 948 BSShapeConvexHull retConvexHull = null;
@@ -937,6 +1022,98 @@ public class BSShapeConvexHull : BSShape
937 return ret; 1022 return ret;
938 } 1023 }
939} 1024}
1025// ============================================================================================================
1026public class BSShapeGImpact : BSShape
1027{
1028 private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
1029 public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
1030
1031 public BSShapeGImpact(BulletShape pShape) : base(pShape)
1032 {
1033 }
1034 public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
1035 {
1036 float lod;
1037 System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
1038
1039 physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}",
1040 prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
1041
1042 BSShapeGImpact retGImpact = null;
1043 lock (GImpacts)
1044 {
1045 if (GImpacts.TryGetValue(newMeshKey, out retGImpact))
1046 {
1047 // The mesh has already been created. Return a new reference to same.
1048 retGImpact.IncrementReference();
1049 }
1050 else
1051 {
1052 retGImpact = new BSShapeGImpact(new BulletShape());
1053 BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
1054
1055 // Check to see if mesh was created (might require an asset).
1056 newShape = VerifyMeshCreated(physicsScene, newShape, prim);
1057 newShape.shapeKey = newMeshKey;
1058 if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
1059 {
1060 // If a mesh was what was created, remember the built shape for later sharing.
1061 // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh.
1062 GImpacts.Add(newMeshKey, retGImpact);
1063 }
1064
1065 retGImpact.physShapeInfo = newShape;
1066 }
1067 }
1068 return retGImpact;
1069 }
1070
1071 private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
1072 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
1073 {
1074 return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
1075 (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) );
1076 }
1077
1078 public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
1079 {
1080 // Calling this reference means we want another handle to an existing shape
1081 // (usually linksets) so return this copy.
1082 IncrementReference();
1083 return this;
1084 }
1085 // Dereferencing a compound shape releases the hold on all the child shapes.
1086 public override void Dereference(BSScene physicsScene)
1087 {
1088 lock (GImpacts)
1089 {
1090 this.DecrementReference();
1091 physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this);
1092 // TODO: schedule aging and destruction of unused meshes.
1093 }
1094 }
1095 // Loop through all the known hulls and return the description based on the physical address.
1096 public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull)
1097 {
1098 bool ret = false;
1099 BSShapeGImpact foundDesc = null;
1100 lock (GImpacts)
1101 {
1102 foreach (BSShapeGImpact sh in GImpacts.Values)
1103 {
1104 if (sh.physShapeInfo.ReferenceSame(pShape))
1105 {
1106 foundDesc = sh;
1107 ret = true;
1108 break;
1109 }
1110
1111 }
1112 }
1113 outHull = foundDesc;
1114 return ret;
1115 }
1116}
940 1117
941// ============================================================================================================ 1118// ============================================================================================================
942public class BSShapeAvatar : BSShape 1119public 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 79edc12..fc679e7 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing
64 public class Meshmerizer : IMesher 64 public class Meshmerizer : IMesher
65 { 65 {
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 private static string LogHeader = "[MESH]";
67 68
68 // Setting baseDir to a path will enable the dumping of raw files 69 // Setting baseDir to a path will enable the dumping of raw files
69 // raw files can be imported by blender so a visual inspection of the results can be done 70 // raw files can be imported by blender so a visual inspection of the results can be done
@@ -72,6 +73,8 @@ namespace OpenSim.Region.Physics.Meshing
72#else 73#else
73 private const string baseDir = null; //"rawFiles"; 74 private const string baseDir = null; //"rawFiles";
74#endif 75#endif
76 // If 'true', lots of DEBUG logging of asset parsing details
77 private bool debugDetail = false;
75 78
76 private bool cacheSculptMaps = true; 79 private bool cacheSculptMaps = true;
77 private string decodedSculptMapPath = null; 80 private string decodedSculptMapPath = null;
@@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 83 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
81 84
82 private List<List<Vector3>> mConvexHulls = null; 85 private List<List<Vector3>> mConvexHulls = null;
86 private List<Vector3> mBoundingHull = null;
83 87
84 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 88 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
85 89
@@ -90,8 +94,11 @@ namespace OpenSim.Region.Physics.Meshing
90 94
91 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); 95 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
92 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); 96 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
93 if(mesh_config != null) 97 if (mesh_config != null)
98 {
94 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 99 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
100 debugDetail = mesh_config.GetBoolean("LogMeshDetails", debugDetail);
101 }
95 102
96 try 103 try
97 { 104 {
@@ -321,6 +328,9 @@ namespace OpenSim.Region.Physics.Meshing
321 faces = new List<Face>(); 328 faces = new List<Face>();
322 OSD meshOsd = null; 329 OSD meshOsd = null;
323 330
331 mConvexHulls = null;
332 mBoundingHull = null;
333
324 if (primShape.SculptData.Length <= 0) 334 if (primShape.SculptData.Length <= 0)
325 { 335 {
326 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this 336 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
@@ -357,43 +367,79 @@ namespace OpenSim.Region.Physics.Meshing
357 OSDMap physicsParms = null; 367 OSDMap physicsParms = null;
358 OSDMap map = (OSDMap)meshOsd; 368 OSDMap map = (OSDMap)meshOsd;
359 if (map.ContainsKey("physics_shape")) 369 if (map.ContainsKey("physics_shape"))
370 {
360 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 371 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
372 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
373 }
361 else if (map.ContainsKey("physics_mesh")) 374 else if (map.ContainsKey("physics_mesh"))
375 {
362 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 376 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
377 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
378 }
363 else if (map.ContainsKey("medium_lod")) 379 else if (map.ContainsKey("medium_lod"))
380 {
364 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh 381 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
382 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
383 }
365 else if (map.ContainsKey("high_lod")) 384 else if (map.ContainsKey("high_lod"))
385 {
366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) 386 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
387 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
388 }
367 389
368 if (map.ContainsKey("physics_convex")) 390 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it 391 { // pull this out also in case physics engine can use it
392 OSD convexBlockOsd = null;
370 try 393 try
371 { 394 {
372 OSDMap convexBlock = (OSDMap)map["physics_convex"]; 395 OSDMap convexBlock = (OSDMap)map["physics_convex"];
373 if (convexBlock.ContainsKey("HullList"))
374 { 396 {
375 byte[] hullList = convexBlock["HullList"].AsBinary(); 397 int convexOffset = convexBlock["offset"].AsInteger() + (int)start;
398 int convexSize = convexBlock["size"].AsInteger();
399
400 byte[] convexBytes = new byte[convexSize];
401
402 System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize);
403
404 try
405 {
406 convexBlockOsd = DecompressOsd(convexBytes);
407 }
408 catch (Exception e)
409 {
410 m_log.ErrorFormat("{0} prim='{1}': exception decoding convex block: {2}", LogHeader, primName, e);
411 //return false;
412 }
413 }
414
415 if (convexBlockOsd != null && convexBlockOsd is OSDMap)
416 {
417 convexBlock = convexBlockOsd as OSDMap;
418
419 if (debugDetail)
420 {
421 string keys = LogHeader + " keys found in convexBlock: ";
422 foreach (KeyValuePair<string, OSD> kvp in convexBlock)
423 keys += "'" + kvp.Key + "' ";
424 m_log.Debug(keys);
425 }
426
376 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); 427 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
377 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); 428 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
378 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); 429 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
379 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); 430 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
380 431
381 // decompress and decode hull points 432 List<Vector3> boundingHull = null;
382 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
383
384 List<List<Vector3>> hulls = new List<List<Vector3>>();
385 int posNdx = 0;
386 433
387 foreach (byte cnt in hullList) 434 if (convexBlock.ContainsKey("BoundingVerts"))
388 { 435 {
389 int count = cnt == 0 ? 256 : cnt; 436 byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary();
390 List<Vector3> hull = new List<Vector3>(); 437 boundingHull = new List<Vector3>();
391 438 for (int i = 0; i < boundingVertsBytes.Length; )
392 for (int i = 0; i < count; i++)
393 { 439 {
394 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 440 ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
395 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 441 ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
396 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 442 ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
397 443
398 Vector3 pos = new Vector3( 444 Vector3 pos = new Vector3(
399 Utils.UInt16ToFloat(uX, min.X, max.X), 445 Utils.UInt16ToFloat(uX, min.X, max.X),
@@ -401,18 +447,57 @@ namespace OpenSim.Region.Physics.Meshing
401 Utils.UInt16ToFloat(uZ, min.Z, max.Z) 447 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
402 ); 448 );
403 449
404 hull.Add(pos); 450 boundingHull.Add(pos);
405 } 451 }
406 452
407 hulls.Add(hull); 453 mBoundingHull = boundingHull;
454 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nVerts={2}", LogHeader, primName, mBoundingHull.Count);
408 } 455 }
409 456
410 mConvexHulls = hulls; 457 if (convexBlock.ContainsKey("HullList"))
458 {
459 byte[] hullList = convexBlock["HullList"].AsBinary();
460
461 byte[] posBytes = convexBlock["Positions"].AsBinary();
462
463 List<List<Vector3>> hulls = new List<List<Vector3>>();
464 int posNdx = 0;
465
466 foreach (byte cnt in hullList)
467 {
468 int count = cnt == 0 ? 256 : cnt;
469 List<Vector3> hull = new List<Vector3>();
470
471 for (int i = 0; i < count; i++)
472 {
473 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
474 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
475 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
476
477 Vector3 pos = new Vector3(
478 Utils.UInt16ToFloat(uX, min.X, max.X),
479 Utils.UInt16ToFloat(uY, min.Y, max.Y),
480 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
481 );
482
483 hull.Add(pos);
484 }
485
486 hulls.Add(hull);
487 }
488
489 mConvexHulls = hulls;
490 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
491 }
492 else
493 {
494 if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
495 }
411 } 496 }
412 } 497 }
413 catch (Exception e) 498 catch (Exception e)
414 { 499 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); 500 m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
416 } 501 }
417 } 502 }
418 503
@@ -431,14 +516,14 @@ namespace OpenSim.Region.Physics.Meshing
431 OSD decodedMeshOsd = new OSD(); 516 OSD decodedMeshOsd = new OSD();
432 byte[] meshBytes = new byte[physSize]; 517 byte[] meshBytes = new byte[physSize];
433 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 518 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
434// byte[] decompressed = new byte[physSize * 5]; 519 // byte[] decompressed = new byte[physSize * 5];
435 try 520 try
436 { 521 {
437 decodedMeshOsd = DecompressOsd(meshBytes); 522 decodedMeshOsd = DecompressOsd(meshBytes);
438 } 523 }
439 catch (Exception e) 524 catch (Exception e)
440 { 525 {
441 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 526 m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
442 return false; 527 return false;
443 } 528 }
444 529
@@ -447,7 +532,7 @@ namespace OpenSim.Region.Physics.Meshing
447 // physics_shape is an array of OSDMaps, one for each submesh 532 // physics_shape is an array of OSDMaps, one for each submesh
448 if (decodedMeshOsd is OSDArray) 533 if (decodedMeshOsd is OSDArray)
449 { 534 {
450// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 535 // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
451 536
452 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 537 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
453 foreach (OSD subMeshOsd in decodedMeshOsdArray) 538 foreach (OSD subMeshOsd in decodedMeshOsdArray)
@@ -455,6 +540,9 @@ namespace OpenSim.Region.Physics.Meshing
455 if (subMeshOsd is OSDMap) 540 if (subMeshOsd is OSDMap)
456 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 541 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
457 } 542 }
543 if (debugDetail)
544 m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
545 LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
458 } 546 }
459 } 547 }
460 548
@@ -776,6 +864,23 @@ namespace OpenSim.Region.Physics.Meshing
776 /// temporary prototype code - please do not use until the interface has been finalized! 864 /// temporary prototype code - please do not use until the interface has been finalized!
777 /// </summary> 865 /// </summary>
778 /// <param name="size">value to scale the hull points by</param> 866 /// <param name="size">value to scale the hull points by</param>
867 /// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns>
868 public List<Vector3> GetBoundingHull(Vector3 size)
869 {
870 if (mBoundingHull == null)
871 return null;
872
873 List<Vector3> verts = new List<Vector3>();
874 foreach (var vert in mBoundingHull)
875 verts.Add(vert * size);
876
877 return verts;
878 }
879
880 /// <summary>
881 /// temporary prototype code - please do not use until the interface has been finalized!
882 /// </summary>
883 /// <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> 884 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns>
780 public List<List<Vector3>> GetConvexHulls(Vector3 size) 885 public List<List<Vector3>> GetConvexHulls(Vector3 size)
781 { 886 {
@@ -788,6 +893,7 @@ namespace OpenSim.Region.Physics.Meshing
788 List<Vector3> verts = new List<Vector3>(); 893 List<Vector3> verts = new List<Vector3>();
789 foreach (var vert in hull) 894 foreach (var vert in hull)
790 verts.Add(vert * size); 895 verts.Add(vert * size);
896 hulls.Add(verts);
791 } 897 }
792 898
793 return hulls; 899 return hulls;