diff options
Diffstat (limited to '')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 185 |
1 files changed, 172 insertions, 13 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 6b09468..fca4258 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; |
@@ -422,9 +423,22 @@ public class BSShapeMesh : BSShape | |||
422 | outMesh = foundDesc; | 423 | outMesh = foundDesc; |
423 | return ret; | 424 | return ret; |
424 | } | 425 | } |
426 | |||
427 | public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); | ||
425 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 428 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, |
426 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 429 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
427 | { | 430 | { |
431 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
432 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | ||
433 | } | ||
434 | |||
435 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | ||
436 | // This is used by the passed 'makeShape' call to create the Bullet mesh shape. | ||
437 | // The actual build call is passed so this logic can be used by several of the shapes that use a | ||
438 | // simple mesh as their base shape. | ||
439 | public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
440 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) | ||
441 | { | ||
428 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
429 | 443 | ||
430 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
@@ -484,8 +498,7 @@ public class BSShapeMesh : BSShape | |||
484 | 498 | ||
485 | if (realIndicesIndex != 0) | 499 | if (realIndicesIndex != 0) |
486 | { | 500 | { |
487 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | 501 | newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); |
488 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
489 | } | 502 | } |
490 | else | 503 | else |
491 | { | 504 | { |
@@ -563,9 +576,56 @@ public class BSShapeHull : BSShape | |||
563 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 576 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
564 | { | 577 | { |
565 | BulletShape newShape = new BulletShape(); | 578 | BulletShape newShape = new BulletShape(); |
566 | IntPtr hullPtr = IntPtr.Zero; | 579 | newShape.shapeKey = newHullKey; |
580 | |||
581 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
582 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
567 | 583 | ||
568 | if (BSParam.ShouldUseBulletHACD) | 584 | // If there is hull data in the mesh asset, build the hull from that |
585 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
586 | { | ||
587 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | ||
588 | if (realMesher != null) | ||
589 | { | ||
590 | List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size); | ||
591 | if (allHulls != null) | ||
592 | { | ||
593 | int hullCount = allHulls.Count; | ||
594 | int totalVertices = 1; // include one for the count of the hulls | ||
595 | // Using the structure described for HACD hulls, create the memory sturcture | ||
596 | // to pass the hull data to the creater. | ||
597 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
598 | { | ||
599 | totalVertices += 4; // add four for the vertex count and centroid | ||
600 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | ||
601 | } | ||
602 | float[] convHulls = new float[totalVertices]; | ||
603 | |||
604 | convHulls[0] = (float)hullCount; | ||
605 | int jj = 1; | ||
606 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
607 | { | ||
608 | convHulls[jj + 0] = hullVerts.Count; | ||
609 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
610 | convHulls[jj + 2] = 0f; | ||
611 | convHulls[jj + 3] = 0f; | ||
612 | jj += 4; | ||
613 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
614 | { | ||
615 | convHulls[jj + 0] = oneVert.X; | ||
616 | convHulls[jj + 1] = oneVert.Y; | ||
617 | convHulls[jj + 2] = oneVert.Z; | ||
618 | jj += 3; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | // create the hull data structure in Bullet | ||
623 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | ||
628 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | ||
569 | { | 629 | { |
570 | // Build the hull shape from an existing mesh shape. | 630 | // Build the hull shape from an existing mesh shape. |
571 | // The mesh should have already been created in Bullet. | 631 | // The mesh should have already been created in Bullet. |
@@ -594,11 +654,10 @@ public class BSShapeHull : BSShape | |||
594 | } | 654 | } |
595 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 655 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
596 | } | 656 | } |
657 | // If no hull specified, use our HACD hull approximation. | ||
597 | if (!newShape.HasPhysicalShape) | 658 | if (!newShape.HasPhysicalShape) |
598 | { | 659 | { |
599 | // Build a new hull in the physical world using the C# HACD algorigthm. | 660 | // Build a new hull in the physical world using the C# HACD algorigthm. |
600 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
601 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
602 | if (meshData != null) | 661 | if (meshData != null) |
603 | { | 662 | { |
604 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 663 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
@@ -805,6 +864,7 @@ public class BSShapeCompound : BSShape | |||
805 | // Called at taint-time. | 864 | // Called at taint-time. |
806 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | 865 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) |
807 | { | 866 | { |
867 | // TODO: figure a better way to go through all the shape types and find a possible instance. | ||
808 | BSShapeMesh meshDesc; | 868 | BSShapeMesh meshDesc; |
809 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | 869 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) |
810 | { | 870 | { |
@@ -826,17 +886,25 @@ public class BSShapeCompound : BSShape | |||
826 | } | 886 | } |
827 | else | 887 | else |
828 | { | 888 | { |
829 | if (physicsScene.PE.IsCompound(pShape)) | 889 | BSShapeGImpact gImpactDesc; |
890 | if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) | ||
830 | { | 891 | { |
831 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | 892 | gImpactDesc.Dereference(physicsScene); |
832 | recursiveCompound.Dereference(physicsScene); | ||
833 | } | 893 | } |
834 | else | 894 | else |
835 | { | 895 | { |
836 | if (physicsScene.PE.IsNativeShape(pShape)) | 896 | if (physicsScene.PE.IsCompound(pShape)) |
837 | { | 897 | { |
838 | BSShapeNative nativeShape = new BSShapeNative(pShape); | 898 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); |
839 | nativeShape.Dereference(physicsScene); | 899 | recursiveCompound.Dereference(physicsScene); |
900 | } | ||
901 | else | ||
902 | { | ||
903 | if (physicsScene.PE.IsNativeShape(pShape)) | ||
904 | { | ||
905 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
906 | nativeShape.Dereference(physicsScene); | ||
907 | } | ||
840 | } | 908 | } |
841 | } | 909 | } |
842 | } | 910 | } |
@@ -859,7 +927,7 @@ public class BSShapeConvexHull : BSShape | |||
859 | float lod; | 927 | float lod; |
860 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 928 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
861 | 929 | ||
862 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", | 930 | physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", |
863 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | 931 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
864 | 932 | ||
865 | BSShapeConvexHull retConvexHull = null; | 933 | BSShapeConvexHull retConvexHull = null; |
@@ -939,6 +1007,97 @@ public class BSShapeConvexHull : BSShape | |||
939 | return ret; | 1007 | return ret; |
940 | } | 1008 | } |
941 | } | 1009 | } |
1010 | // ============================================================================================================ | ||
1011 | public class BSShapeGImpact : BSShape | ||
1012 | { | ||
1013 | private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; | ||
1014 | public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); | ||
1015 | |||
1016 | public BSShapeGImpact(BulletShape pShape) : base(pShape) | ||
1017 | { | ||
1018 | } | ||
1019 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
1020 | { | ||
1021 | float lod; | ||
1022 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
1023 | |||
1024 | physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", | ||
1025 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | ||
1026 | |||
1027 | BSShapeGImpact retGImpact = null; | ||
1028 | lock (GImpacts) | ||
1029 | { | ||
1030 | if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) | ||
1031 | { | ||
1032 | // The mesh has already been created. Return a new reference to same. | ||
1033 | retGImpact.IncrementReference(); | ||
1034 | } | ||
1035 | else | ||
1036 | { | ||
1037 | retGImpact = new BSShapeGImpact(new BulletShape()); | ||
1038 | BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
1039 | |||
1040 | // Check to see if mesh was created (might require an asset). | ||
1041 | newShape = VerifyMeshCreated(physicsScene, newShape, prim); | ||
1042 | if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | ||
1043 | { | ||
1044 | // If a mesh was what was created, remember the built shape for later sharing. | ||
1045 | // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. | ||
1046 | GImpacts.Add(newMeshKey, retGImpact); | ||
1047 | } | ||
1048 | |||
1049 | retGImpact.physShapeInfo = newShape; | ||
1050 | } | ||
1051 | } | ||
1052 | return retGImpact; | ||
1053 | } | ||
1054 | |||
1055 | private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
1056 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
1057 | { | ||
1058 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
1059 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | ||
1060 | } | ||
1061 | |||
1062 | public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) | ||
1063 | { | ||
1064 | // Calling this reference means we want another handle to an existing shape | ||
1065 | // (usually linksets) so return this copy. | ||
1066 | IncrementReference(); | ||
1067 | return this; | ||
1068 | } | ||
1069 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
1070 | public override void Dereference(BSScene physicsScene) | ||
1071 | { | ||
1072 | lock (GImpacts) | ||
1073 | { | ||
1074 | this.DecrementReference(); | ||
1075 | physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
1076 | // TODO: schedule aging and destruction of unused meshes. | ||
1077 | } | ||
1078 | } | ||
1079 | // Loop through all the known hulls and return the description based on the physical address. | ||
1080 | public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) | ||
1081 | { | ||
1082 | bool ret = false; | ||
1083 | BSShapeGImpact foundDesc = null; | ||
1084 | lock (GImpacts) | ||
1085 | { | ||
1086 | foreach (BSShapeGImpact sh in GImpacts.Values) | ||
1087 | { | ||
1088 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
1089 | { | ||
1090 | foundDesc = sh; | ||
1091 | ret = true; | ||
1092 | break; | ||
1093 | } | ||
1094 | |||
1095 | } | ||
1096 | } | ||
1097 | outHull = foundDesc; | ||
1098 | return ret; | ||
1099 | } | ||
1100 | } | ||
942 | 1101 | ||
943 | // ============================================================================================================ | 1102 | // ============================================================================================================ |
944 | public class BSShapeAvatar : BSShape | 1103 | public class BSShapeAvatar : BSShape |