diff options
author | Melanie | 2013-05-24 01:11:49 +0100 |
---|---|---|
committer | Melanie | 2013-05-24 01:11:49 +0100 |
commit | e2e839a0cd4035ffacfcdc601dfc534a05bc4e0f (patch) | |
tree | 1c9b02e48835c85a84b85d690428bf65adfe7fd9 /OpenSim/Region/Physics | |
parent | Merge branch 'master' into careminster (diff) | |
parent | minor: Remove unnecessary duplication of AbsolutePosition Vector3 in SOG.Copy() (diff) | |
download | opensim-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-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 2 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 309 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 84 |
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 | { |