aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs11
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSParam.cs3
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapes.cs282
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs27
4 files changed, 209 insertions, 114 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index ff5b6ab..48f842e 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject
483 { 483 {
484 // Bullet assumes we know what we are doing when forcing orientation 484 // Bullet assumes we know what we are doing when forcing orientation
485 // so it lets us go against all the rules and just compensates for them later. 485 // so it lets us go against all the rules and just compensates for them later.
486 // This keeps us from flipping the capsule over which the veiwer does not understand. 486 // This forces rotation to be only around the Z axis and doesn't change any of the other axis.
487 ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0); 487 // This keeps us from flipping the capsule over which the veiwer does not understand.
488 float oRoll, oPitch, oYaw;
489 _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
490 OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
491 // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
492 // LocalID, _orientation, OMV.Vector3.UnitX * _orientation,
493 // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
494 ForceOrientation = trimmedOrientation;
488 }); 495 });
489 } 496 }
490 } 497 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
index 9a9e527..c19eda1 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs
@@ -90,6 +90,7 @@ public static class BSParam
90 public static bool ShouldUseBulletHACD { get; set; } 90 public static bool ShouldUseBulletHACD { get; set; }
91 public static bool ShouldUseSingleConvexHullForPrims { get; set; } 91 public static bool ShouldUseSingleConvexHullForPrims { get; set; }
92 public static bool ShouldUseGImpactShapeForPrims { get; set; } 92 public static bool ShouldUseGImpactShapeForPrims { get; set; }
93 public static bool ShouldUseAssetHulls { get; set; }
93 94
94 public static float TerrainImplementation { get; set; } 95 public static float TerrainImplementation { get; set; }
95 public static int TerrainMeshMagnification { get; private set; } 96 public static int TerrainMeshMagnification { get; private set; }
@@ -372,6 +373,8 @@ public static class BSParam
372 true ), 373 true ),
373 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",
374 false ), 375 false ),
376 new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info",
377 false ),
375 378
376 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",
377 5 ), 380 5 ),
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
index 0152233..48f1394 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs
@@ -31,6 +31,7 @@ using System.Text;
31 31
32using OpenSim.Framework; 32using OpenSim.Framework;
33using OpenSim.Region.Physics.Manager; 33using OpenSim.Region.Physics.Manager;
34using OpenSim.Region.Physics.Meshing;
34using OpenSim.Region.Physics.ConvexDecompositionDotNet; 35using OpenSim.Region.Physics.ConvexDecompositionDotNet;
35 36
36using OMV = OpenMetaverse; 37using OMV = OpenMetaverse;
@@ -440,10 +441,14 @@ public class BSShapeMesh : BSShape
440 { 441 {
441 BulletShape newShape = new BulletShape(); 442 BulletShape newShape = new BulletShape();
442 443
443 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, 444 IMesh meshData = null;
444 false, // say it is not physical so a bounding box is not built 445 lock (physicsScene.mesher)
445 false // do not cache the mesh and do not use previously built versions 446 {
446 ); 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 }
447 452
448 if (meshData != null) 453 if (meshData != null)
449 { 454 {
@@ -573,13 +578,75 @@ public class BSShapeHull : BSShape
573 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) 578 PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
574 { 579 {
575 BulletShape newShape = new BulletShape(); 580 BulletShape newShape = new BulletShape();
576 IntPtr hullPtr = IntPtr.Zero; 581 newShape.shapeKey = newHullKey;
577 582
578 if (BSParam.ShouldUseBulletHACD) 583 IMesh meshData = null;
584 List<List<OMV.Vector3>> allHulls = null;
585 lock (physicsScene.mesher)
586 {
587 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
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)
592 {
593 Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
594 if (realMesher != null)
595 {
596 allHulls = realMesher.GetConvexHulls(size);
597 }
598 if (allHulls == null)
599 {
600 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID);
601 }
602 }
603 }
604
605 // If there is hull data in the mesh asset, build the hull from that
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];
618
619 convHulls[0] = (float)hullCount;
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;
634 }
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);
642 }
643
644 // If no hull specified in the asset and we should use Bullet's HACD approximation...
645 if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
579 { 646 {
580 // Build the hull shape from an existing mesh shape. 647 // Build the hull shape from an existing mesh shape.
581 // The mesh should have already been created in Bullet. 648 // The mesh should have already been created in Bullet.
582 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID); 649 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID);
583 BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim); 650 BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
584 651
585 if (meshShape.physShapeInfo.HasPhysicalShape) 652 if (meshShape.physShapeInfo.HasPhysicalShape)
@@ -597,128 +664,123 @@ public class BSShapeHull : BSShape
597 664
598 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape); 665 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
599 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms); 666 newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
600 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 667 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
601 668
602 // Now done with the mesh shape. 669 // Now done with the mesh shape.
603 meshShape.Dereference(physicsScene); 670 meshShape.Dereference(physicsScene);
604 } 671 }
605 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); 672 physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
606 } 673 }
607 if (!newShape.HasPhysicalShape) 674
675 // If no other hull specifications, use our HACD hull approximation.
676 if (!newShape.HasPhysicalShape && meshData != null)
608 { 677 {
609 // Build a new hull in the physical world using the C# HACD algorigthm. 678 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
610 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
611 IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
612 if (meshData != null)
613 { 679 {
614 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) 680 // Release the fetched asset data once it has been used.
615 { 681 pbs.SculptData = new byte[0];
616 // Release the fetched asset data once it has been used. 682 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
617 pbs.SculptData = new byte[0]; 683 }
618 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
619 }
620 684
621 int[] indices = meshData.getIndexListAsInt(); 685 int[] indices = meshData.getIndexListAsInt();
622 List<OMV.Vector3> vertices = meshData.getVertexList(); 686 List<OMV.Vector3> vertices = meshData.getVertexList();
623 687
624 //format conversion from IMesh format to DecompDesc format 688 //format conversion from IMesh format to DecompDesc format
625 List<int> convIndices = new List<int>(); 689 List<int> convIndices = new List<int>();
626 List<float3> convVertices = new List<float3>(); 690 List<float3> convVertices = new List<float3>();
627 for (int ii = 0; ii < indices.GetLength(0); ii++) 691 for (int ii = 0; ii < indices.GetLength(0); ii++)
628 { 692 {
629 convIndices.Add(indices[ii]); 693 convIndices.Add(indices[ii]);
630 } 694 }
631 foreach (OMV.Vector3 vv in vertices) 695 foreach (OMV.Vector3 vv in vertices)
632 { 696 {
633 convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); 697 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
634 } 698 }
635 699
636 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; 700 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
637 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))
638 { 707 {
639 // Simple primitive shapes we know are convex so they are better implemented with 708 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
640 // fewer hulls.
641 // Check for simple shape (prim without cuts) and reduce split parameter if so.
642 if (BSShapeCollection.PrimHasNoCuts(pbs))
643 {
644 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
645 }
646 } 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];
647 757
648 // setup and do convex hull conversion 758 convHulls[0] = (float)hullCount;
649 m_hulls = new List<ConvexResult>(); 759 int jj = 1;
650 DecompDesc dcomp = new DecompDesc(); 760 foreach (ConvexResult cr in m_hulls)
651 dcomp.mIndices = convIndices; 761 {
652 dcomp.mVertices = convVertices; 762 // copy vertices for index access
653 dcomp.mDepth = maxDepthSplit; 763 float3[] verts = new float3[cr.HullVertices.Count];
654 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; 764 int kk = 0;
655 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; 765 foreach (float3 ff in cr.HullVertices)
656 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
657 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
658 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
659 // create the hull into the _hulls variable
660 convexBuilder.process(dcomp);
661
662 physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
663 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
664
665 // Convert the vertices and indices for passing to unmanaged.
666 // The hull information is passed as a large floating point array.
667 // The format is:
668 // convHulls[0] = number of hulls
669 // convHulls[1] = number of vertices in first hull
670 // convHulls[2] = hull centroid X coordinate
671 // convHulls[3] = hull centroid Y coordinate
672 // convHulls[4] = hull centroid Z coordinate
673 // convHulls[5] = first hull vertex X
674 // convHulls[6] = first hull vertex Y
675 // convHulls[7] = first hull vertex Z
676 // convHulls[8] = second hull vertex X
677 // ...
678 // convHulls[n] = number of vertices in second hull
679 // convHulls[n+1] = second hull centroid X coordinate
680 // ...
681 //
682 // TODO: is is very inefficient. Someday change the convex hull generator to return
683 // data structures that do not need to be converted in order to pass to Bullet.
684 // And maybe put the values directly into pinned memory rather than marshaling.
685 int hullCount = m_hulls.Count;
686 int totalVertices = 1; // include one for the count of the hulls
687 foreach (ConvexResult cr in m_hulls)
688 { 766 {
689 totalVertices += 4; // add four for the vertex count and centroid 767 verts[kk++] = ff;
690 totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
691 } 768 }
692 float[] convHulls = new float[totalVertices];
693 769
694 convHulls[0] = (float)hullCount; 770 // add to the array one hull's worth of data
695 int jj = 1; 771 convHulls[jj++] = cr.HullIndices.Count;
696 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)
697 { 776 {
698 // copy vertices for index access 777 convHulls[jj++] = verts[ind].x;
699 float3[] verts = new float3[cr.HullVertices.Count]; 778 convHulls[jj++] = verts[ind].y;
700 int kk = 0; 779 convHulls[jj++] = verts[ind].z;
701 foreach (float3 ff in cr.HullVertices)
702 {
703 verts[kk++] = ff;
704 }
705
706 // add to the array one hull's worth of data
707 convHulls[jj++] = cr.HullIndices.Count;
708 convHulls[jj++] = 0f; // centroid x,y,z
709 convHulls[jj++] = 0f;
710 convHulls[jj++] = 0f;
711 foreach (int ind in cr.HullIndices)
712 {
713 convHulls[jj++] = verts[ind].x;
714 convHulls[jj++] = verts[ind].y;
715 convHulls[jj++] = verts[ind].z;
716 }
717 } 780 }
718 // create the hull data structure in Bullet
719 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
720 } 781 }
721 newShape.shapeKey = newHullKey; 782 // create the hull data structure in Bullet
783 newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
722 } 784 }
723 return newShape; 785 return newShape;
724 } 786 }
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 79edc12..adc0dc9 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;
@@ -357,13 +360,25 @@ namespace OpenSim.Region.Physics.Meshing
357 OSDMap physicsParms = null; 360 OSDMap physicsParms = null;
358 OSDMap map = (OSDMap)meshOsd; 361 OSDMap map = (OSDMap)meshOsd;
359 if (map.ContainsKey("physics_shape")) 362 if (map.ContainsKey("physics_shape"))
363 {
360 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 364 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
365 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
366 }
361 else if (map.ContainsKey("physics_mesh")) 367 else if (map.ContainsKey("physics_mesh"))
368 {
362 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 369 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
370 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
371 }
363 else if (map.ContainsKey("medium_lod")) 372 else if (map.ContainsKey("medium_lod"))
373 {
364 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh 374 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
375 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
376 }
365 else if (map.ContainsKey("high_lod")) 377 else if (map.ContainsKey("high_lod"))
378 {
366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) 379 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
380 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
381 }
367 382
368 if (map.ContainsKey("physics_convex")) 383 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it 384 { // pull this out also in case physics engine can use it
@@ -408,11 +423,16 @@ namespace OpenSim.Region.Physics.Meshing
408 } 423 }
409 424
410 mConvexHulls = hulls; 425 mConvexHulls = hulls;
426 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
427 }
428 else
429 {
430 if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
411 } 431 }
412 } 432 }
413 catch (Exception e) 433 catch (Exception e)
414 { 434 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); 435 m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
416 } 436 }
417 } 437 }
418 438
@@ -438,7 +458,7 @@ namespace OpenSim.Region.Physics.Meshing
438 } 458 }
439 catch (Exception e) 459 catch (Exception e)
440 { 460 {
441 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 461 m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
442 return false; 462 return false;
443 } 463 }
444 464
@@ -455,6 +475,9 @@ namespace OpenSim.Region.Physics.Meshing
455 if (subMeshOsd is OSDMap) 475 if (subMeshOsd is OSDMap)
456 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 476 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
457 } 477 }
478 if (debugDetail)
479 m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
480 LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
458 } 481 }
459 } 482 }
460 483