diff options
Diffstat (limited to 'OpenSim/Region')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 53 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 1 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 223 |
3 files changed, 183 insertions, 94 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 385ed9e..06df85e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -86,6 +86,7 @@ public static class BSParam | |||
86 | public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes | 86 | public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes |
87 | public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects | 87 | public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects |
88 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } | 88 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } |
89 | public static bool ShouldUseBulletHACD { get; set; } | ||
89 | 90 | ||
90 | public static float TerrainImplementation { get; private set; } | 91 | public static float TerrainImplementation { get; private set; } |
91 | public static int TerrainMeshMagnification { get; private set; } | 92 | public static int TerrainMeshMagnification { get; private set; } |
@@ -149,6 +150,15 @@ public static class BSParam | |||
149 | public static float CSHullVolumeConservationThresholdPercent { get; private set; } | 150 | public static float CSHullVolumeConservationThresholdPercent { get; private set; } |
150 | public static int CSHullMaxVertices { get; private set; } | 151 | public static int CSHullMaxVertices { get; private set; } |
151 | public static float CSHullMaxSkinWidth { get; private set; } | 152 | public static float CSHullMaxSkinWidth { get; private set; } |
153 | public static float BHullMaxVerticesPerHull { get; private set; } // 100 | ||
154 | public static float BHullMinClusters { get; private set; } // 2 | ||
155 | public static float BHullCompacityWeight { get; private set; } // 0.1 | ||
156 | public static float BHullVolumeWeight { get; private set; } // 0.0 | ||
157 | public static float BHullConcavity { get; private set; } // 100 | ||
158 | public static bool BHullAddExtraDistPoints { get; private set; } // false | ||
159 | public static bool BHullAddNeighboursDistPoints { get; private set; } // false | ||
160 | public static bool BHullAddFacesPoints { get; private set; } // false | ||
161 | public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false | ||
152 | 162 | ||
153 | // Linkset implementation parameters | 163 | // Linkset implementation parameters |
154 | public static float LinksetImplementation { get; private set; } | 164 | public static float LinksetImplementation { get; private set; } |
@@ -325,6 +335,10 @@ public static class BSParam | |||
325 | true, | 335 | true, |
326 | (s) => { return ShouldRemoveZeroWidthTriangles; }, | 336 | (s) => { return ShouldRemoveZeroWidthTriangles; }, |
327 | (s,v) => { ShouldRemoveZeroWidthTriangles = v; } ), | 337 | (s,v) => { ShouldRemoveZeroWidthTriangles = v; } ), |
338 | new ParameterDefn<bool>("ShouldUseBulletHACD", "If true, use the Bullet version of HACD", | ||
339 | false, | ||
340 | (s) => { return ShouldUseBulletHACD; }, | ||
341 | (s,v) => { ShouldUseBulletHACD = v; } ), | ||
328 | 342 | ||
329 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", | 343 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
330 | 5, | 344 | 5, |
@@ -663,10 +677,47 @@ public static class BSParam | |||
663 | (s) => { return CSHullMaxVertices; }, | 677 | (s) => { return CSHullMaxVertices; }, |
664 | (s,v) => { CSHullMaxVertices = v; } ), | 678 | (s,v) => { CSHullMaxVertices = v; } ), |
665 | new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", | 679 | new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", |
666 | 0, | 680 | 0f, |
667 | (s) => { return CSHullMaxSkinWidth; }, | 681 | (s) => { return CSHullMaxSkinWidth; }, |
668 | (s,v) => { CSHullMaxSkinWidth = v; } ), | 682 | (s,v) => { CSHullMaxSkinWidth = v; } ), |
669 | 683 | ||
684 | new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull", | ||
685 | 100f, | ||
686 | (s) => { return BHullMaxVerticesPerHull; }, | ||
687 | (s,v) => { BHullMaxVerticesPerHull = v; } ), | ||
688 | new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh", | ||
689 | 2f, | ||
690 | (s) => { return BHullMinClusters; }, | ||
691 | (s,v) => { BHullMinClusters = v; } ), | ||
692 | new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls", | ||
693 | 2f, | ||
694 | (s) => { return BHullCompacityWeight; }, | ||
695 | (s,v) => { BHullCompacityWeight = v; } ), | ||
696 | new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull", | ||
697 | 0.1f, | ||
698 | (s) => { return BHullVolumeWeight; }, | ||
699 | (s,v) => { BHullVolumeWeight = v; } ), | ||
700 | new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be", | ||
701 | 100f, | ||
702 | (s) => { return BHullConcavity; }, | ||
703 | (s,v) => { BHullConcavity = v; } ), | ||
704 | new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors", | ||
705 | false, | ||
706 | (s) => { return BHullAddExtraDistPoints; }, | ||
707 | (s,v) => { BHullAddExtraDistPoints = v; } ), | ||
708 | new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls", | ||
709 | false, | ||
710 | (s) => { return BHullAddNeighboursDistPoints; }, | ||
711 | (s,v) => { BHullAddNeighboursDistPoints = v; } ), | ||
712 | new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces", | ||
713 | false, | ||
714 | (s) => { return BHullAddFacesPoints; }, | ||
715 | (s,v) => { BHullAddFacesPoints = v; } ), | ||
716 | new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin", | ||
717 | false, | ||
718 | (s) => { return BHullShouldAdjustCollisionMargin; }, | ||
719 | (s,v) => { BHullShouldAdjustCollisionMargin = v; } ), | ||
720 | |||
670 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", | 721 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", |
671 | (float)BSLinkset.LinksetImplementation.Compound, | 722 | (float)BSLinkset.LinksetImplementation.Compound, |
672 | (s) => { return LinksetImplementation; }, | 723 | (s) => { return LinksetImplementation; }, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 9818b05..8e05b58 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -316,6 +316,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
316 | break; | 316 | break; |
317 | case "bulletxna": | 317 | case "bulletxna": |
318 | ret = new BSAPIXNA(engineName, this); | 318 | ret = new BSAPIXNA(engineName, this); |
319 | BSParam.ShouldUseBulletHACD = false; | ||
319 | break; | 320 | break; |
320 | } | 321 | } |
321 | 322 | ||
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 | ||