diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 11 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 3 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 282 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 27 |
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 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.Meshing; | ||
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 35 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
35 | 36 | ||
36 | using OMV = OpenMetaverse; | 37 | using 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 | ||