aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorMelanie2013-05-24 01:11:49 +0100
committerMelanie2013-05-24 01:11:49 +0100
commite2e839a0cd4035ffacfcdc601dfc534a05bc4e0f (patch)
tree1c9b02e48835c85a84b85d690428bf65adfe7fd9 /OpenSim/Region/Physics
parentMerge branch 'master' into careminster (diff)
parentminor: Remove unnecessary duplication of AbsolutePosition Vector3 in SOG.Copy() (diff)
downloadopensim-SC-e2e839a0cd4035ffacfcdc601dfc534a05bc4e0f.zip
opensim-SC-e2e839a0cd4035ffacfcdc601dfc534a05bc4e0f.tar.gz
opensim-SC-e2e839a0cd4035ffacfcdc601dfc534a05bc4e0f.tar.bz2
opensim-SC-e2e839a0cd4035ffacfcdc601dfc534a05bc4e0f.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/SceneObjectPart.cs OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs2
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs309
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs84
3 files changed, 241 insertions, 154 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 }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index db5d962..ffdee0f 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing
64 public class Meshmerizer : IMesher 64 public class Meshmerizer : IMesher
65 { 65 {
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 private static string LogHeader = "[MESH]";
67 68
68 // Setting baseDir to a path will enable the dumping of raw files 69 // Setting baseDir to a path will enable the dumping of raw files
69 // raw files can be imported by blender so a visual inspection of the results can be done 70 // raw files can be imported by blender so a visual inspection of the results can be done
@@ -72,6 +73,8 @@ namespace OpenSim.Region.Physics.Meshing
72#else 73#else
73 private const string baseDir = null; //"rawFiles"; 74 private const string baseDir = null; //"rawFiles";
74#endif 75#endif
76 // If 'true', lots of DEBUG logging of asset parsing details
77 private bool debugDetail = true;
75 78
76 private bool cacheSculptMaps = true; 79 private bool cacheSculptMaps = true;
77 private string decodedSculptMapPath = null; 80 private string decodedSculptMapPath = null;
@@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 83 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
81 84
82 private List<List<Vector3>> mConvexHulls = null; 85 private List<List<Vector3>> mConvexHulls = null;
86 private List<Vector3> mBoundingHull = null;
83 87
84 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 88 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
85 89
@@ -321,6 +325,9 @@ namespace OpenSim.Region.Physics.Meshing
321 faces = new List<Face>(); 325 faces = new List<Face>();
322 OSD meshOsd = null; 326 OSD meshOsd = null;
323 327
328 mConvexHulls = null;
329 mBoundingHull = null;
330
324 if (primShape.SculptData.Length <= 0) 331 if (primShape.SculptData.Length <= 0)
325 { 332 {
326 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this 333 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
@@ -357,26 +364,66 @@ namespace OpenSim.Region.Physics.Meshing
357 OSDMap physicsParms = null; 364 OSDMap physicsParms = null;
358 OSDMap map = (OSDMap)meshOsd; 365 OSDMap map = (OSDMap)meshOsd;
359 if (map.ContainsKey("physics_shape")) 366 if (map.ContainsKey("physics_shape"))
367 {
360 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 368 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
369 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
370 }
361 else if (map.ContainsKey("physics_mesh")) 371 else if (map.ContainsKey("physics_mesh"))
372 {
362 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 373 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
374 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
375 }
363 else if (map.ContainsKey("medium_lod")) 376 else if (map.ContainsKey("medium_lod"))
377 {
364 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh 378 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
379 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
380 }
365 else if (map.ContainsKey("high_lod")) 381 else if (map.ContainsKey("high_lod"))
382 {
366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) 383 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
384 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
385 }
367 386
368 if (map.ContainsKey("physics_convex")) 387 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it 388 { // pull this out also in case physics engine can use it
370 try 389 try
371 { 390 {
372 OSDMap convexBlock = (OSDMap)map["physics_convex"]; 391 OSDMap convexBlock = (OSDMap)map["physics_convex"];
392
393 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
394 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
395 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
396 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
397
398 List<Vector3> boundingHull = null;
399
400 if (convexBlock.ContainsKey("BoundingVerts"))
401 {
402 // decompress and decode bounding hull points
403 byte[] boundingVertsBytes = DecompressOsd(convexBlock["BoundingVerts"].AsBinary()).AsBinary();
404 boundingHull = new List<Vector3>();
405 for (int i = 0; i < boundingVertsBytes.Length;)
406 {
407 ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
408 ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
409 ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
410
411 Vector3 pos = new Vector3(
412 Utils.UInt16ToFloat(uX, min.X, max.X),
413 Utils.UInt16ToFloat(uY, min.Y, max.Y),
414 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
415 );
416
417 boundingHull.Add(pos);
418 }
419
420 mBoundingHull = boundingHull;
421 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nHulls={2}", LogHeader, primName, mBoundingHull.Count);
422 }
423
373 if (convexBlock.ContainsKey("HullList")) 424 if (convexBlock.ContainsKey("HullList"))
374 { 425 {
375 byte[] hullList = convexBlock["HullList"].AsBinary(); 426 byte[] hullList = convexBlock["HullList"].AsBinary();
376 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
377 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
378 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
379 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
380 427
381 // decompress and decode hull points 428 // decompress and decode hull points
382 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary(); 429 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
@@ -408,11 +455,16 @@ namespace OpenSim.Region.Physics.Meshing
408 } 455 }
409 456
410 mConvexHulls = hulls; 457 mConvexHulls = hulls;
458 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
459 }
460 else
461 {
462 if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
411 } 463 }
412 } 464 }
413 catch (Exception e) 465 catch (Exception e)
414 { 466 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); 467 m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
416 } 468 }
417 } 469 }
418 470
@@ -438,7 +490,7 @@ namespace OpenSim.Region.Physics.Meshing
438 } 490 }
439 catch (Exception e) 491 catch (Exception e)
440 { 492 {
441 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 493 m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
442 return false; 494 return false;
443 } 495 }
444 496
@@ -455,6 +507,9 @@ namespace OpenSim.Region.Physics.Meshing
455 if (subMeshOsd is OSDMap) 507 if (subMeshOsd is OSDMap)
456 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 508 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
457 } 509 }
510 if (debugDetail)
511 m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
512 LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
458 } 513 }
459 } 514 }
460 515
@@ -776,6 +831,23 @@ namespace OpenSim.Region.Physics.Meshing
776 /// temporary prototype code - please do not use until the interface has been finalized! 831 /// temporary prototype code - please do not use until the interface has been finalized!
777 /// </summary> 832 /// </summary>
778 /// <param name="size">value to scale the hull points by</param> 833 /// <param name="size">value to scale the hull points by</param>
834 /// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns>
835 public List<Vector3> GetBoundingHull(Vector3 size)
836 {
837 if (mBoundingHull == null)
838 return null;
839
840 List<Vector3> verts = new List<Vector3>();
841 foreach (var vert in mBoundingHull)
842 verts.Add(vert * size);
843
844 return verts;
845 }
846
847 /// <summary>
848 /// temporary prototype code - please do not use until the interface has been finalized!
849 /// </summary>
850 /// <param name="size">value to scale the hull points by</param>
779 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> 851 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns>
780 public List<List<Vector3>> GetConvexHulls(Vector3 size) 852 public List<List<Vector3>> GetConvexHulls(Vector3 size)
781 { 853 {