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