diff options
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 33 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 55 |
2 files changed, 74 insertions, 14 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index 4d89a88..26d2d60 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -142,6 +142,14 @@ public static class BSParam | |||
142 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } | 142 | public static float VehicleAngularBankingTimescaleFudge { get; private set; } |
143 | public static bool VehicleDebuggingEnabled { get; private set; } | 143 | public static bool VehicleDebuggingEnabled { get; private set; } |
144 | 144 | ||
145 | // Convex Hulls | ||
146 | public static int CSHullMaxDepthSplit { get; private set; } | ||
147 | public static int CSHullMaxDepthSplitForSimpleShapes { get; private set; } | ||
148 | public static float CSHullConcavityThresholdPercent { get; private set; } | ||
149 | public static float CSHullVolumeConservationThresholdPercent { get; private set; } | ||
150 | public static int CSHullMaxVertices { get; private set; } | ||
151 | public static float CSHullMaxSkinWidth { get; private set; } | ||
152 | |||
145 | // Linkset implementation parameters | 153 | // Linkset implementation parameters |
146 | public static float LinksetImplementation { get; private set; } | 154 | public static float LinksetImplementation { get; private set; } |
147 | public static bool LinkConstraintUseFrameOffset { get; private set; } | 155 | public static bool LinkConstraintUseFrameOffset { get; private set; } |
@@ -623,6 +631,31 @@ public static class BSParam | |||
623 | (s) => { return GlobalContactBreakingThreshold; }, | 631 | (s) => { return GlobalContactBreakingThreshold; }, |
624 | (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), | 632 | (s,v) => { GlobalContactBreakingThreshold = v; s.UnmanagedParams[0].globalContactBreakingThreshold = v; } ), |
625 | 633 | ||
634 | new ParameterDefn<int>("CSHullMaxDepthSplit", "CS impl: max depth to split for hull. 1-10 but > 7 is iffy", | ||
635 | 7, | ||
636 | (s) => { return CSHullMaxDepthSplit; }, | ||
637 | (s,v) => { CSHullMaxDepthSplit = v; } ), | ||
638 | new ParameterDefn<int>("CSHullMaxDepthSplitForSimpleShapes", "CS impl: max depth setting for simple prim shapes", | ||
639 | 2, | ||
640 | (s) => { return CSHullMaxDepthSplitForSimpleShapes; }, | ||
641 | (s,v) => { CSHullMaxDepthSplitForSimpleShapes = v; } ), | ||
642 | new ParameterDefn<float>("CSHullConcavityThresholdPercent", "CS impl: concavity threshold percent (0-20)", | ||
643 | 5f, | ||
644 | (s) => { return CSHullConcavityThresholdPercent; }, | ||
645 | (s,v) => { CSHullConcavityThresholdPercent = v; } ), | ||
646 | new ParameterDefn<float>("CSHullVolumeConservationThresholdPercent", "percent volume conservation to collapse hulls (0-30)", | ||
647 | 5f, | ||
648 | (s) => { return CSHullVolumeConservationThresholdPercent; }, | ||
649 | (s,v) => { CSHullVolumeConservationThresholdPercent = v; } ), | ||
650 | new ParameterDefn<int>("CSHullMaxVertices", "CS impl: maximum number of vertices in output hulls. Keep < 50.", | ||
651 | 32, | ||
652 | (s) => { return CSHullMaxVertices; }, | ||
653 | (s,v) => { CSHullMaxVertices = v; } ), | ||
654 | new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.", | ||
655 | 0, | ||
656 | (s) => { return CSHullMaxSkinWidth; }, | ||
657 | (s,v) => { CSHullMaxSkinWidth = v; } ), | ||
658 | |||
626 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", | 659 | new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)", |
627 | (float)BSLinkset.LinksetImplementation.Compound, | 660 | (float)BSLinkset.LinksetImplementation.Compound, |
628 | (s) => { return LinksetImplementation; }, | 661 | (s) => { return LinksetImplementation; }, |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index b16bc10..457f204 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -447,17 +447,10 @@ public sealed class BSShapeCollection : IDisposable | |||
447 | 447 | ||
448 | // If the prim attributes are simple, this could be a simple Bullet native shape | 448 | // If the prim attributes are simple, this could be a simple Bullet native shape |
449 | if (!haveShape | 449 | if (!haveShape |
450 | && nativeShapePossible | ||
450 | && pbs != null | 451 | && pbs != null |
451 | && !pbs.SculptEntry | 452 | && !pbs.SculptEntry |
452 | && nativeShapePossible | 453 | && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) || PrimHasNoCuts(pbs)) ) |
453 | && ((pbs.SculptEntry && !BSParam.ShouldMeshSculptedPrim) | ||
454 | || (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | ||
455 | && pbs.ProfileHollow == 0 | ||
456 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | ||
457 | && pbs.PathBegin == 0 && pbs.PathEnd == 0 | ||
458 | && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 | ||
459 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | ||
460 | && pbs.PathShearX == 0 && pbs.PathShearY == 0) ) ) | ||
461 | { | 454 | { |
462 | // Get the scale of any existing shape so we can see if the new shape is same native type and same size. | 455 | // Get the scale of any existing shape so we can see if the new shape is same native type and same size. |
463 | OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; | 456 | OMV.Vector3 scaleOfExistingShape = OMV.Vector3.Zero; |
@@ -508,6 +501,18 @@ public sealed class BSShapeCollection : IDisposable | |||
508 | return ret; | 501 | return ret; |
509 | } | 502 | } |
510 | 503 | ||
504 | // return 'true' if this shape description does not include any cutting or twisting. | ||
505 | private bool PrimHasNoCuts(PrimitiveBaseShape pbs) | ||
506 | { | ||
507 | return pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 | ||
508 | && pbs.ProfileHollow == 0 | ||
509 | && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 | ||
510 | && pbs.PathBegin == 0 && pbs.PathEnd == 0 | ||
511 | && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 | ||
512 | && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 | ||
513 | && pbs.PathShearX == 0 && pbs.PathShearY == 0; | ||
514 | } | ||
515 | |||
511 | // return 'true' if the prim's shape was changed. | 516 | // return 'true' if the prim's shape was changed. |
512 | public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 517 | public bool CreateGeomMeshOrHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
513 | { | 518 | { |
@@ -518,7 +523,7 @@ public sealed class BSShapeCollection : IDisposable | |||
518 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) | 523 | if (prim.IsPhysical && BSParam.ShouldUseHullsForPhysicalObjects) |
519 | { | 524 | { |
520 | // Update prim.BSShape to reference a hull of this shape. | 525 | // Update prim.BSShape to reference a hull of this shape. |
521 | ret = GetReferenceToHull(prim,shapeCallback); | 526 | ret = GetReferenceToHull(prim, shapeCallback); |
522 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 527 | if (DDetail) DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
523 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 528 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
524 | } | 529 | } |
@@ -697,6 +702,7 @@ public sealed class BSShapeCollection : IDisposable | |||
697 | 702 | ||
698 | // See that hull shape exists in the physical world and update prim.BSShape. | 703 | // See that hull shape exists in the physical world and update prim.BSShape. |
699 | // We could be creating the hull because scale changed or whatever. | 704 | // We could be creating the hull because scale changed or whatever. |
705 | // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance. | ||
700 | private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) | 706 | private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
701 | { | 707 | { |
702 | BulletShape newShape; | 708 | BulletShape newShape; |
@@ -715,6 +721,7 @@ public sealed class BSShapeCollection : IDisposable | |||
715 | DereferenceShape(prim.PhysShape, shapeCallback); | 721 | DereferenceShape(prim.PhysShape, shapeCallback); |
716 | 722 | ||
717 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); | 723 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); |
724 | // It might not have been created if we're waiting for an asset. | ||
718 | newShape = VerifyMeshCreated(newShape, prim); | 725 | newShape = VerifyMeshCreated(newShape, prim); |
719 | 726 | ||
720 | ReferenceShape(newShape); | 727 | ReferenceShape(newShape); |
@@ -733,14 +740,14 @@ public sealed class BSShapeCollection : IDisposable | |||
733 | HullDesc hullDesc; | 740 | HullDesc hullDesc; |
734 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) | 741 | if (Hulls.TryGetValue(newHullKey, out hullDesc)) |
735 | { | 742 | { |
736 | // If the hull shape already is created, just use it. | 743 | // If the hull shape already has been created, just use the one shared instance. |
737 | newShape = hullDesc.shape.Clone(); | 744 | newShape = hullDesc.shape.Clone(); |
738 | } | 745 | } |
739 | else | 746 | else |
740 | { | 747 | { |
741 | // Build a new hull in the physical world | 748 | // Build a new hull in the physical world. |
742 | // Pass true for physicalness as this creates some sort of bounding box which we don't need | 749 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed |
743 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false); | 750 | IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */); |
744 | if (meshData != null) | 751 | if (meshData != null) |
745 | { | 752 | { |
746 | 753 | ||
@@ -759,15 +766,35 @@ public sealed class BSShapeCollection : IDisposable | |||
759 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); | 766 | convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); |
760 | } | 767 | } |
761 | 768 | ||
769 | uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit; | ||
770 | if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes) | ||
771 | { | ||
772 | // Simple primitive shapes we know are convex so they are better implemented with | ||
773 | // fewer hulls. | ||
774 | // Check for simple shape (prim without cuts) and reduce split parameter if so. | ||
775 | if (PrimHasNoCuts(pbs)) | ||
776 | { | ||
777 | maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes; | ||
778 | } | ||
779 | } | ||
780 | |||
762 | // setup and do convex hull conversion | 781 | // setup and do convex hull conversion |
763 | m_hulls = new List<ConvexResult>(); | 782 | m_hulls = new List<ConvexResult>(); |
764 | DecompDesc dcomp = new DecompDesc(); | 783 | DecompDesc dcomp = new DecompDesc(); |
765 | dcomp.mIndices = convIndices; | 784 | dcomp.mIndices = convIndices; |
766 | dcomp.mVertices = convVertices; | 785 | dcomp.mVertices = convVertices; |
786 | dcomp.mDepth = maxDepthSplit; | ||
787 | dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent; | ||
788 | dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent; | ||
789 | dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices; | ||
790 | dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth; | ||
767 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); | 791 | ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); |
768 | // create the hull into the _hulls variable | 792 | // create the hull into the _hulls variable |
769 | convexBuilder.process(dcomp); | 793 | convexBuilder.process(dcomp); |
770 | 794 | ||
795 | DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}", | ||
796 | BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count); | ||
797 | |||
771 | // Convert the vertices and indices for passing to unmanaged. | 798 | // Convert the vertices and indices for passing to unmanaged. |
772 | // The hull information is passed as a large floating point array. | 799 | // The hull information is passed as a large floating point array. |
773 | // The format is: | 800 | // The format is: |