aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs185
1 files changed, 172 insertions, 13 deletions
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