diff options
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 309 |
2 files changed, 163 insertions, 148 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 5cff668..c19eda1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -373,7 +373,7 @@ public static class BSParam | |||
373 | true ), | 373 | true ), |
374 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", | 374 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", |
375 | false ), | 375 | false ), |
376 | new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info", | 376 | new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info", |
377 | false ), | 377 | false ), |
378 | 378 | ||
379 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", | 379 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index fca4258..046c12c 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -441,12 +441,16 @@ public class BSShapeMesh : BSShape | |||
441 | { | 441 | { |
442 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
443 | 443 | ||
444 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = null; |
445 | false, // say it is not physical so a bounding box is not built | 445 | lock (physicsScene.mesher) |
446 | false, // do not cache the mesh and do not use previously built versions | 446 | { |
447 | false, | 447 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
448 | false | 448 | false, // say it is not physical so a bounding box is not built |
449 | ); | 449 | false, // do not cache the mesh and do not use previously built versions |
450 | false, | ||
451 | false | ||
452 | ); | ||
453 | } | ||
450 | 454 | ||
451 | if (meshData != null) | 455 | if (meshData != null) |
452 | { | 456 | { |
@@ -578,58 +582,73 @@ public class BSShapeHull : BSShape | |||
578 | BulletShape newShape = new BulletShape(); | 582 | BulletShape newShape = new BulletShape(); |
579 | newShape.shapeKey = newHullKey; | 583 | newShape.shapeKey = newHullKey; |
580 | 584 | ||
581 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | 585 | IMesh meshData = null; |
582 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | 586 | List<List<OMV.Vector3>> allHulls = null; |
583 | 587 | lock (physicsScene.mesher) | |
584 | // If there is hull data in the mesh asset, build the hull from that | ||
585 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
586 | { | 588 | { |
587 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | 589 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed |
588 | if (realMesher != null) | 590 | meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); |
591 | |||
592 | // If we should use the asset's hull info, fetch it out of the locked mesher | ||
593 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
589 | { | 594 | { |
590 | List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size); | 595 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; |
591 | if (allHulls != null) | 596 | if (realMesher != null) |
592 | { | 597 | { |
593 | int hullCount = allHulls.Count; | 598 | allHulls = realMesher.GetConvexHulls(size); |
594 | int totalVertices = 1; // include one for the count of the hulls | 599 | } |
595 | // Using the structure described for HACD hulls, create the memory sturcture | 600 | if (allHulls == null) |
596 | // to pass the hull data to the creater. | 601 | { |
597 | foreach (List<OMV.Vector3> hullVerts in allHulls) | 602 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID); |
598 | { | 603 | } |
599 | totalVertices += 4; // add four for the vertex count and centroid | 604 | } |
600 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | 605 | } |
601 | } | ||
602 | float[] convHulls = new float[totalVertices]; | ||
603 | 606 | ||
604 | convHulls[0] = (float)hullCount; | 607 | // If there is hull data in the mesh asset, build the hull from that |
605 | int jj = 1; | 608 | if (allHulls != null && BSParam.ShouldUseAssetHulls) |
606 | foreach (List<OMV.Vector3> hullVerts in allHulls) | 609 | { |
607 | { | 610 | int hullCount = allHulls.Count; |
608 | convHulls[jj + 0] = hullVerts.Count; | 611 | int totalVertices = 1; // include one for the count of the hulls |
609 | convHulls[jj + 1] = 0f; // centroid x,y,z | 612 | // Using the structure described for HACD hulls, create the memory sturcture |
610 | convHulls[jj + 2] = 0f; | 613 | // to pass the hull data to the creater. |
611 | convHulls[jj + 3] = 0f; | 614 | foreach (List<OMV.Vector3> hullVerts in allHulls) |
612 | jj += 4; | 615 | { |
613 | foreach (OMV.Vector3 oneVert in hullVerts) | 616 | totalVertices += 4; // add four for the vertex count and centroid |
614 | { | 617 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions |
615 | convHulls[jj + 0] = oneVert.X; | 618 | } |
616 | convHulls[jj + 1] = oneVert.Y; | 619 | float[] convHulls = new float[totalVertices]; |
617 | convHulls[jj + 2] = oneVert.Z; | ||
618 | jj += 3; | ||
619 | } | ||
620 | } | ||
621 | 620 | ||
622 | // create the hull data structure in Bullet | 621 | convHulls[0] = (float)hullCount; |
623 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | 622 | int jj = 1; |
623 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
624 | { | ||
625 | convHulls[jj + 0] = hullVerts.Count; | ||
626 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
627 | convHulls[jj + 2] = 0f; | ||
628 | convHulls[jj + 3] = 0f; | ||
629 | jj += 4; | ||
630 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
631 | { | ||
632 | convHulls[jj + 0] = oneVert.X; | ||
633 | convHulls[jj + 1] = oneVert.Y; | ||
634 | convHulls[jj + 2] = oneVert.Z; | ||
635 | jj += 3; | ||
624 | } | 636 | } |
625 | } | 637 | } |
638 | |||
639 | // create the hull data structure in Bullet | ||
640 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
641 | |||
642 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}", | ||
643 | prim.LocalID, hullCount, totalVertices, newShape); | ||
626 | } | 644 | } |
645 | |||
627 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | 646 | // If no hull specified in the asset and we should use Bullet's HACD approximation... |
628 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | 647 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) |
629 | { | 648 | { |
630 | // Build the hull shape from an existing mesh shape. | 649 | // Build the hull shape from an existing mesh shape. |
631 | // The mesh should have already been created in Bullet. | 650 | // The mesh should have already been created in Bullet. |
632 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); | 651 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID); |
633 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); | 652 | BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); |
634 | 653 | ||
635 | if (meshShape.physShapeInfo.HasPhysicalShape) | 654 | if (meshShape.physShapeInfo.HasPhysicalShape) |
@@ -647,127 +666,123 @@ public class BSShapeHull : BSShape | |||
647 | 666 | ||
648 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); | 667 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); |
649 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); | 668 | newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); |
650 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 669 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape); |
651 | 670 | ||
652 | // Now done with the mesh shape. | 671 | // Now done with the mesh shape. |
653 | meshShape.Dereference(physicsScene); | 672 | meshShape.Dereference(physicsScene); |
654 | } | 673 | } |
655 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 674 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
656 | } | 675 | } |
657 | // If no hull specified, use our HACD hull approximation. | 676 | |
658 | if (!newShape.HasPhysicalShape) | 677 | // If no other hull specifications, use our HACD hull approximation. |
678 | if (!newShape.HasPhysicalShape && meshData != null) | ||
659 | { | 679 | { |
660 | // Build a new hull in the physical world using the C# HACD algorigthm. | 680 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
661 | if (meshData != null) | ||
662 | { | 681 | { |
663 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 682 | // Release the fetched asset data once it has been used. |
664 | { | 683 | pbs.SculptData = new byte[0]; |
665 | // Release the fetched asset data once it has been used. | 684 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; |
666 | pbs.SculptData = new byte[0]; | 685 | } |
667 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown; | ||
668 | } | ||
669 | 686 | ||
670 | int[] indices = meshData.getIndexListAsInt(); | 687 | int[] indices = meshData.getIndexListAsInt(); |
671 | List<OMV.Vector3> vertices = meshData.getVertexList(); | 688 | List<OMV.Vector3> vertices = meshData.getVertexList(); |
672 | 689 | ||
673 | //format conversion from IMesh format to DecompDesc format | 690 | //format conversion from IMesh format to DecompDesc format |
674 | List<int> convIndices = new List<int>(); | 691 | List<int> convIndices = new List<int>(); |
675 | List<float3> convVertices = new List<float3>(); | 692 | List<float3> convVertices = new List<float3>(); |
676 | for (int ii = 0; ii < indices.GetLength(0); ii++) | 693 | for (int ii = 0; ii < indices.GetLength(0); ii++) |
677 | { | 694 | { |
678 | convIndices.Add(indices[ii]); | 695 | convIndices.Add(indices[ii]); |
679 | } | 696 | } |
680 | foreach (OMV.Vector3 vv in vertices) | 697 | foreach (OMV.Vector3 vv in vertices) |
681 | { | 698 | { |
682 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | 699 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); |
683 | } | 700 | } |
684 | 701 | ||
685 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | 702 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; |
686 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | 703 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) |
704 | { | ||
705 | // Simple primitive shapes we know are convex so they are better implemented with | ||
706 | // fewer hulls. | ||
707 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
708 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
687 | { | 709 | { |
688 | // Simple primitive shapes we know are convex so they are better implemented with | 710 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; |
689 | // fewer hulls. | ||
690 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
691 | if (BSShapeCollection.PrimHasNoCuts(pbs)) | ||
692 | { | ||
693 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
694 | } | ||
695 | } | 711 | } |
712 | } | ||
713 | |||
714 | // setup and do convex hull conversion | ||
715 | m_hulls = new List<ConvexResult>(); | ||
716 | DecompDesc dcomp = new DecompDesc(); | ||
717 | dcomp.mIndices = convIndices; | ||
718 | dcomp.mVertices = convVertices; | ||
719 | dcomp.mDepth = maxDepthSplit; | ||
720 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
721 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
722 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
723 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
724 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
725 | // create the hull into the _hulls variable | ||
726 | convexBuilder.process(dcomp); | ||
727 | |||
728 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
729 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
730 | |||
731 | // Convert the vertices and indices for passing to unmanaged. | ||
732 | // The hull information is passed as a large floating point array. | ||
733 | // The format is: | ||
734 | // convHulls[0] = number of hulls | ||
735 | // convHulls[1] = number of vertices in first hull | ||
736 | // convHulls[2] = hull centroid X coordinate | ||
737 | // convHulls[3] = hull centroid Y coordinate | ||
738 | // convHulls[4] = hull centroid Z coordinate | ||
739 | // convHulls[5] = first hull vertex X | ||
740 | // convHulls[6] = first hull vertex Y | ||
741 | // convHulls[7] = first hull vertex Z | ||
742 | // convHulls[8] = second hull vertex X | ||
743 | // ... | ||
744 | // convHulls[n] = number of vertices in second hull | ||
745 | // convHulls[n+1] = second hull centroid X coordinate | ||
746 | // ... | ||
747 | // | ||
748 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
749 | // data structures that do not need to be converted in order to pass to Bullet. | ||
750 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
751 | int hullCount = m_hulls.Count; | ||
752 | int totalVertices = 1; // include one for the count of the hulls | ||
753 | foreach (ConvexResult cr in m_hulls) | ||
754 | { | ||
755 | totalVertices += 4; // add four for the vertex count and centroid | ||
756 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
757 | } | ||
758 | float[] convHulls = new float[totalVertices]; | ||
696 | 759 | ||
697 | // setup and do convex hull conversion | 760 | convHulls[0] = (float)hullCount; |
698 | m_hulls = new List<ConvexResult>(); | 761 | int jj = 1; |
699 | DecompDesc dcomp = new DecompDesc(); | 762 | foreach (ConvexResult cr in m_hulls) |
700 | dcomp.mIndices = convIndices; | 763 | { |
701 | dcomp.mVertices = convVertices; | 764 | // copy vertices for index access |
702 | dcomp.mDepth = maxDepthSplit; | 765 | float3[] verts = new float3[cr.HullVertices.Count]; |
703 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | 766 | int kk = 0; |
704 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | 767 | foreach (float3 ff in cr.HullVertices) |
705 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
706 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
707 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | ||
708 | // create the hull into the _hulls variable | ||
709 | convexBuilder.process(dcomp); | ||
710 | |||
711 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
712 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
713 | |||
714 | // Convert the vertices and indices for passing to unmanaged. | ||
715 | // The hull information is passed as a large floating point array. | ||
716 | // The format is: | ||
717 | // convHulls[0] = number of hulls | ||
718 | // convHulls[1] = number of vertices in first hull | ||
719 | // convHulls[2] = hull centroid X coordinate | ||
720 | // convHulls[3] = hull centroid Y coordinate | ||
721 | // convHulls[4] = hull centroid Z coordinate | ||
722 | // convHulls[5] = first hull vertex X | ||
723 | // convHulls[6] = first hull vertex Y | ||
724 | // convHulls[7] = first hull vertex Z | ||
725 | // convHulls[8] = second hull vertex X | ||
726 | // ... | ||
727 | // convHulls[n] = number of vertices in second hull | ||
728 | // convHulls[n+1] = second hull centroid X coordinate | ||
729 | // ... | ||
730 | // | ||
731 | // TODO: is is very inefficient. Someday change the convex hull generator to return | ||
732 | // data structures that do not need to be converted in order to pass to Bullet. | ||
733 | // And maybe put the values directly into pinned memory rather than marshaling. | ||
734 | int hullCount = m_hulls.Count; | ||
735 | int totalVertices = 1; // include one for the count of the hulls | ||
736 | foreach (ConvexResult cr in m_hulls) | ||
737 | { | 768 | { |
738 | totalVertices += 4; // add four for the vertex count and centroid | 769 | verts[kk++] = ff; |
739 | totalVertices += cr.HullIndices.Count * 3; // we pass just triangles | ||
740 | } | 770 | } |
741 | float[] convHulls = new float[totalVertices]; | ||
742 | 771 | ||
743 | convHulls[0] = (float)hullCount; | 772 | // add to the array one hull's worth of data |
744 | int jj = 1; | 773 | convHulls[jj++] = cr.HullIndices.Count; |
745 | foreach (ConvexResult cr in m_hulls) | 774 | convHulls[jj++] = 0f; // centroid x,y,z |
775 | convHulls[jj++] = 0f; | ||
776 | convHulls[jj++] = 0f; | ||
777 | foreach (int ind in cr.HullIndices) | ||
746 | { | 778 | { |
747 | // copy vertices for index access | 779 | convHulls[jj++] = verts[ind].x; |
748 | float3[] verts = new float3[cr.HullVertices.Count]; | 780 | convHulls[jj++] = verts[ind].y; |
749 | int kk = 0; | 781 | convHulls[jj++] = verts[ind].z; |
750 | foreach (float3 ff in cr.HullVertices) | ||
751 | { | ||
752 | verts[kk++] = ff; | ||
753 | } | ||
754 | |||
755 | // add to the array one hull's worth of data | ||
756 | convHulls[jj++] = cr.HullIndices.Count; | ||
757 | convHulls[jj++] = 0f; // centroid x,y,z | ||
758 | convHulls[jj++] = 0f; | ||
759 | convHulls[jj++] = 0f; | ||
760 | foreach (int ind in cr.HullIndices) | ||
761 | { | ||
762 | convHulls[jj++] = verts[ind].x; | ||
763 | convHulls[jj++] = verts[ind].y; | ||
764 | convHulls[jj++] = verts[ind].z; | ||
765 | } | ||
766 | } | 782 | } |
767 | // create the hull data structure in Bullet | ||
768 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
769 | } | 783 | } |
770 | newShape.shapeKey = newHullKey; | 784 | // create the hull data structure in Bullet |
785 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
771 | } | 786 | } |
772 | return newShape; | 787 | return newShape; |
773 | } | 788 | } |