diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 223 |
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 | ||