aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs74
1 files changed, 55 insertions, 19 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index 05c147d..7609578 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 }
@@ -699,6 +704,7 @@ public sealed class BSShapeCollection : IDisposable
699 704
700 // See that hull shape exists in the physical world and update prim.BSShape. 705 // See that hull shape exists in the physical world and update prim.BSShape.
701 // We could be creating the hull because scale changed or whatever. 706 // We could be creating the hull because scale changed or whatever.
707 // Return 'true' if a new hull was built. Otherwise, returning a shared hull instance.
702 private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) 708 private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback)
703 { 709 {
704 BulletShape newShape; 710 BulletShape newShape;
@@ -717,6 +723,7 @@ public sealed class BSShapeCollection : IDisposable
717 DereferenceShape(prim.PhysShape, shapeCallback); 723 DereferenceShape(prim.PhysShape, shapeCallback);
718 724
719 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); 725 newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
726 // It might not have been created if we're waiting for an asset.
720 newShape = VerifyMeshCreated(newShape, prim); 727 newShape = VerifyMeshCreated(newShape, prim);
721 728
722 ReferenceShape(newShape); 729 ReferenceShape(newShape);
@@ -735,13 +742,13 @@ public sealed class BSShapeCollection : IDisposable
735 HullDesc hullDesc; 742 HullDesc hullDesc;
736 if (Hulls.TryGetValue(newHullKey, out hullDesc)) 743 if (Hulls.TryGetValue(newHullKey, out hullDesc))
737 { 744 {
738 // If the hull shape already is created, just use it. 745 // If the hull shape already has been created, just use the one shared instance.
739 newShape = hullDesc.shape.Clone(); 746 newShape = hullDesc.shape.Clone();
740 } 747 }
741 else 748 else
742 { 749 {
743 // Build a new hull in the physical world 750 // Build a new hull in the physical world.
744 // Pass true for physicalness as this creates some sort of bounding box which we don't need 751 // Pass true for physicalness as this prevents the creation of bounding box which is not needed
745 IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false); 752 IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false);
746 if (meshData != null) 753 if (meshData != null)
747 { 754 {
@@ -761,15 +768,35 @@ public sealed class BSShapeCollection : IDisposable
761 convVertices.Add(new float3(vv.X, vv.Y, vv.Z)); 768 convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
762 } 769 }
763 770
771 uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
772 if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
773 {
774 // Simple primitive shapes we know are convex so they are better implemented with
775 // fewer hulls.
776 // Check for simple shape (prim without cuts) and reduce split parameter if so.
777 if (PrimHasNoCuts(pbs))
778 {
779 maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
780 }
781 }
782
764 // setup and do convex hull conversion 783 // setup and do convex hull conversion
765 m_hulls = new List<ConvexResult>(); 784 m_hulls = new List<ConvexResult>();
766 DecompDesc dcomp = new DecompDesc(); 785 DecompDesc dcomp = new DecompDesc();
767 dcomp.mIndices = convIndices; 786 dcomp.mIndices = convIndices;
768 dcomp.mVertices = convVertices; 787 dcomp.mVertices = convVertices;
788 dcomp.mDepth = maxDepthSplit;
789 dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
790 dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
791 dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
792 dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
769 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn); 793 ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
770 // create the hull into the _hulls variable 794 // create the hull into the _hulls variable
771 convexBuilder.process(dcomp); 795 convexBuilder.process(dcomp);
772 796
797 DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
798 BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
799
773 // Convert the vertices and indices for passing to unmanaged. 800 // Convert the vertices and indices for passing to unmanaged.
774 // The hull information is passed as a large floating point array. 801 // The hull information is passed as a large floating point array.
775 // The format is: 802 // The format is:
@@ -905,11 +932,15 @@ public sealed class BSShapeCollection : IDisposable
905 return newShape; 932 return newShape;
906 933
907 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset 934 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
908 if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) 935 if (prim.BaseShape.SculptEntry
936 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Failed
937 && prim.PrimAssetState != BSPhysObject.PrimAssetCondition.Waiting
938 && prim.BaseShape.SculptTexture != OMV.UUID.Zero
939 )
909 { 940 {
910 DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lastFailed={1}", prim.LocalID, prim.LastAssetBuildFailed); 941 DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID);
911 // This will prevent looping through this code as we keep trying to get the failed shape 942 // Multiple requestors will know we're waiting for this asset
912 prim.LastAssetBuildFailed = true; 943 prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting;
913 944
914 BSPhysObject xprim = prim; 945 BSPhysObject xprim = prim;
915 Util.FireAndForget(delegate 946 Util.FireAndForget(delegate
@@ -920,7 +951,7 @@ public sealed class BSShapeCollection : IDisposable
920 BSPhysObject yprim = xprim; // probably not necessary, but, just in case. 951 BSPhysObject yprim = xprim; // probably not necessary, but, just in case.
921 assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset) 952 assetProvider(yprim.BaseShape.SculptTexture, delegate(AssetBase asset)
922 { 953 {
923 bool assetFound = false; // DEBUG DEBUG 954 bool assetFound = false;
924 string mismatchIDs = String.Empty; // DEBUG DEBUG 955 string mismatchIDs = String.Empty; // DEBUG DEBUG
925 if (asset != null && yprim.BaseShape.SculptEntry) 956 if (asset != null && yprim.BaseShape.SculptEntry)
926 { 957 {
@@ -938,6 +969,10 @@ public sealed class BSShapeCollection : IDisposable
938 mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID; 969 mismatchIDs = yprim.BaseShape.SculptTexture.ToString() + "/" + asset.ID;
939 } 970 }
940 } 971 }
972 if (assetFound)
973 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched;
974 else
975 yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
941 DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", 976 DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}",
942 yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); 977 yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs );
943 978
@@ -945,6 +980,7 @@ public sealed class BSShapeCollection : IDisposable
945 } 980 }
946 else 981 else
947 { 982 {
983 xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed;
948 PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", 984 PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}",
949 LogHeader, PhysicsScene.Name); 985 LogHeader, PhysicsScene.Name);
950 } 986 }
@@ -952,7 +988,7 @@ public sealed class BSShapeCollection : IDisposable
952 } 988 }
953 else 989 else
954 { 990 {
955 if (prim.LastAssetBuildFailed) 991 if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
956 { 992 {
957 PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", 993 PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
958 LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); 994 LogHeader, prim.LocalID, prim.BaseShape.SculptTexture);