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