aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs223
1 files changed, 130 insertions, 93 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 220fbbc..76860e4 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -722,7 +722,7 @@ public sealed class BSShapeCollection : IDisposable
722 // Remove usage of the previous shape. 722 // Remove usage of the previous shape.
723 DereferenceShape(prim.PhysShape, shapeCallback); 723 DereferenceShape(prim.PhysShape, shapeCallback);
724 724
725 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); 725 newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod);
726 // It might not have been created if we're waiting for an asset. 726 // It might not have been created if we're waiting for an asset.
727 newShape = VerifyMeshCreated(newShape, prim); 727 newShape = VerifyMeshCreated(newShape, prim);
728 728
@@ -733,7 +733,7 @@ public sealed class BSShapeCollection : IDisposable
733 } 733 }
734 734
735 List<ConvexResult> m_hulls; 735 List<ConvexResult> m_hulls;
736 private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 736 private BulletShape CreatePhysicalHull(BSPhysObject prim, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
737 { 737 {
738 738
739 BulletShape newShape = new BulletShape(); 739 BulletShape newShape = new BulletShape();
@@ -747,116 +747,153 @@ public sealed class BSShapeCollection : IDisposable
747 } 747 }
748 else 748 else
749 { 749 {
750 // Build a new hull in the physical world. 750 if (BSParam.ShouldUseBulletHACD)
751 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
752 IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false);
753 if (meshData != null)
754 { 751 {
755 752 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
756 int[] indices = meshData.getIndexListAsInt(); 753 MeshDesc meshDesc;
757 List<OMV.Vector3> vertices = meshData.getVertexList(); 754 if (!Meshes.TryGetValue(newHullKey, out meshDesc))
758
759 //format conversion from IMesh format to DecompDesc format
760 List<int> convIndices = new List<int>();
761 List<float3> convVertices = new List<float3>();
762 for (int ii = 0; ii < indices.GetLength(0); ii++)
763 { 755 {
764 convIndices.Add(indices[ii]); 756 // That's odd because the mesh should have been created before the hull
757 // but, since it doesn't exist, create it.
758 newShape = CreatePhysicalMesh(prim, newHullKey, prim.BaseShape, prim.Size, lod);
759 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,noMeshBuiltNew,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
760
761 if (newShape.HasPhysicalShape)
762 {
763 ReferenceShape(newShape);
764 Meshes.TryGetValue(newHullKey, out meshDesc);
765 }
765 } 766 }
766 foreach (OMV.Vector3 vv in vertices) 767 if (meshDesc.shape.HasPhysicalShape)
767 { 768 {
768 convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); 769 HACDParams parms;
770 parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
771 parms.minClusters = BSParam.BHullMinClusters;
772 parms.compacityWeight = BSParam.BHullCompacityWeight;
773 parms.volumeWeight = BSParam.BHullVolumeWeight;
774 parms.concavity = BSParam.BHullConcavity;
775 parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
776 parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
777 parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
778 parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
779
780 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
781 newShape = PhysicsScene.PE.BuildHullShapeFromMesh(PhysicsScene.World, meshDesc.shape, parms);
782 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
769 } 783 }
770 784 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
771 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; 785 }
772 if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) 786 if (!newShape.HasPhysicalShape)
787 {
788 // Build a new hull in the physical world.
789 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
790 IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
791 if (meshData != null)
773 { 792 {
774 // Simple primitive shapes we know are convex so they are better implemented with 793 int[] indices = meshData.getIndexListAsInt();
775 // fewer hulls. 794 List<OMV.Vector3> vertices = meshData.getVertexList();
776 // Check for simple shape (prim without cuts) and reduce split parameter if so. 795
777 if (PrimHasNoCuts(pbs)) 796 //format conversion from IMesh format to DecompDesc format
797 List<int> convIndices = new List<int>();
798 List<float3> convVertices = new List<float3>();
799 for (int ii = 0; ii < indices.GetLength(0); ii++)
778 { 800 {
779 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; 801 convIndices.Add(indices[ii]);
802 }
803 foreach (OMV.Vector3 vv in vertices)
804 {
805 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
780 } 806 }
781 }
782 807
783 // setup and do convex hull conversion 808 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
784 m_hulls = new List<ConvexResult>(); 809 if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
785 DecompDesc dcomp = new DecompDesc(); 810 {
786 dcomp.mIndices = convIndices; 811 // Simple primitive shapes we know are convex so they are better implemented with
787 dcomp.mVertices = convVertices; 812 // fewer hulls.
788 dcomp.mDepth = maxDepthSplit; 813 // Check for simple shape (prim without cuts) and reduce split parameter if so.
789 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; 814 if (PrimHasNoCuts(pbs))
790 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; 815 {
791 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; 816 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
792 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; 817 }
793 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); 818 }
794 // create the hull into the _hulls variable
795 convexBuilder.process(dcomp);
796
797 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
798 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
799
800 // Convert the vertices and indices for passing to unmanaged.
801 // The hull information is passed as a large floating point array.
802 // The format is:
803 // convHulls[0] = number of hulls
804 // convHulls[1] = number of vertices in first hull
805 // convHulls[2] = hull centroid X coordinate
806 // convHulls[3] = hull centroid Y coordinate
807 // convHulls[4] = hull centroid Z coordinate
808 // convHulls[5] = first hull vertex X
809 // convHulls[6] = first hull vertex Y
810 // convHulls[7] = first hull vertex Z
811 // convHulls[8] = second hull vertex X
812 // ...
813 // convHulls[n] = number of vertices in second hull
814 // convHulls[n+1] = second hull centroid X coordinate
815 // ...
816 //
817 // TODO: is is very inefficient. Someday change the convex hull generator to return
818 // data structures that do not need to be converted in order to pass to Bullet.
819 // And maybe put the values directly into pinned memory rather than marshaling.
820 int hullCount = m_hulls.Count;
821 int totalVertices = 1; // include one for the count of the hulls
822 foreach (ConvexResult cr in m_hulls)
823 {
824 totalVertices += 4; // add four for the vertex count and centroid
825 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
826 }
827 float[] convHulls = new float[totalVertices];
828 819
829 convHulls[0] = (float)hullCount; 820 // setup and do convex hull conversion
830 int jj = 1; 821 m_hulls = new List<ConvexResult>();
831 foreach (ConvexResult cr in m_hulls) 822 DecompDesc dcomp = new DecompDesc();
832 { 823 dcomp.mIndices = convIndices;
833 // copy vertices for index access 824 dcomp.mVertices = convVertices;
834 float3[] verts = new float3[cr.HullVertices.Count]; 825 dcomp.mDepth = maxDepthSplit;
835 int kk = 0; 826 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
836 foreach (float3 ff in cr.HullVertices) 827 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
828 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
829 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
830 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
831 // create the hull into the _hulls variable
832 convexBuilder.process(dcomp);
833
834 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
835 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
836
837 // Convert the vertices and indices for passing to unmanaged.
838 // The hull information is passed as a large floating point array.
839 // The format is:
840 // convHulls[0] = number of hulls
841 // convHulls[1] = number of vertices in first hull
842 // convHulls[2] = hull centroid X coordinate
843 // convHulls[3] = hull centroid Y coordinate
844 // convHulls[4] = hull centroid Z coordinate
845 // convHulls[5] = first hull vertex X
846 // convHulls[6] = first hull vertex Y
847 // convHulls[7] = first hull vertex Z
848 // convHulls[8] = second hull vertex X
849 // ...
850 // convHulls[n] = number of vertices in second hull
851 // convHulls[n+1] = second hull centroid X coordinate
852 // ...
853 //
854 // TODO: is is very inefficient. Someday change the convex hull generator to return
855 // data structures that do not need to be converted in order to pass to Bullet.
856 // And maybe put the values directly into pinned memory rather than marshaling.
857 int hullCount = m_hulls.Count;
858 int totalVertices = 1; // include one for the count of the hulls
859 foreach (ConvexResult cr in m_hulls)
837 { 860 {
838 verts[kk++] = ff; 861 totalVertices += 4; // add four for the vertex count and centroid
862 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
839 } 863 }
864 float[] convHulls = new float[totalVertices];
840 865
841 // add to the array one hull's worth of data 866 convHulls[0] = (float)hullCount;
842 convHulls[jj++] = cr.HullIndices.Count; 867 int jj = 1;
843 convHulls[jj++] = 0f; // centroid x,y,z 868 foreach (ConvexResult cr in m_hulls)
844 convHulls[jj++] = 0f;
845 convHulls[jj++] = 0f;
846 foreach (int ind in cr.HullIndices)
847 { 869 {
848 convHulls[jj++] = verts[ind].x; 870 // copy vertices for index access
849 convHulls[jj++] = verts[ind].y; 871 float3[] verts = new float3[cr.HullVertices.Count];
850 convHulls[jj++] = verts[ind].z; 872 int kk = 0;
873 foreach (float3 ff in cr.HullVertices)
874 {
875 verts[kk++] = ff;
876 }
877
878 // add to the array one hull's worth of data
879 convHulls[jj++] = cr.HullIndices.Count;
880 convHulls[jj++] = 0f; // centroid x,y,z
881 convHulls[jj++] = 0f;
882 convHulls[jj++] = 0f;
883 foreach (int ind in cr.HullIndices)
884 {
885 convHulls[jj++] = verts[ind].x;
886 convHulls[jj++] = verts[ind].y;
887 convHulls[jj++] = verts[ind].z;
888 }
851 } 889 }
890 // create the hull data structure in Bullet
891 newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
852 } 892 }
853 // create the hull data structure in Bullet
854 newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
855 } 893 }
894 newShape.shapeKey = newHullKey;
856 } 895 }
857 896
858 newShape.shapeKey = newHullKey;
859
860 return newShape; 897 return newShape;
861 } 898 }
862 899