diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 117 |
1 files changed, 110 insertions, 7 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 3b1bdfb..a894e5f 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -83,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
83 | 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 |
84 | 84 | ||
85 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 85 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
86 | private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>(); | ||
86 | 87 | ||
87 | public Meshmerizer(IConfigSource config) | 88 | public Meshmerizer(IConfigSource config) |
88 | { | 89 | { |
@@ -986,6 +987,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
986 | return CreateMesh(primName, primShape, size, lod, false,false); | 987 | return CreateMesh(primName, primShape, size, lod, false,false); |
987 | } | 988 | } |
988 | 989 | ||
990 | private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); | ||
991 | |||
989 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) | 992 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) |
990 | { | 993 | { |
991 | #if SPAM | 994 | #if SPAM |
@@ -995,17 +998,60 @@ namespace OpenSim.Region.Physics.Meshing | |||
995 | Mesh mesh = null; | 998 | Mesh mesh = null; |
996 | ulong key = 0; | 999 | ulong key = 0; |
997 | 1000 | ||
998 | // If this mesh has been created already, return it instead of creating another copy | ||
999 | // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory | ||
1000 | key = primShape.GetMeshKey(size, lod, convex); | ||
1001 | if (m_uniqueMeshes.TryGetValue(key, out mesh)) | ||
1002 | return mesh; | ||
1003 | |||
1004 | if (size.X < 0.01f) size.X = 0.01f; | 1001 | if (size.X < 0.01f) size.X = 0.01f; |
1005 | if (size.Y < 0.01f) size.Y = 0.01f; | 1002 | if (size.Y < 0.01f) size.Y = 0.01f; |
1006 | if (size.Z < 0.01f) size.Z = 0.01f; | 1003 | if (size.Z < 0.01f) size.Z = 0.01f; |
1007 | 1004 | ||
1005 | // try to find a identical mesh on meshs in use | ||
1006 | key = primShape.GetMeshKey(size, lod, convex); | ||
1007 | |||
1008 | lock (m_uniqueMeshes) | ||
1009 | { | ||
1010 | m_uniqueMeshes.TryGetValue(key, out mesh); | ||
1011 | |||
1012 | if (mesh != null) | ||
1013 | { | ||
1014 | mesh.RefCount++; | ||
1015 | return mesh; | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | // try to find a identical mesh on meshs recently released | ||
1020 | lock (m_uniqueReleasedMeshes) | ||
1021 | { | ||
1022 | m_uniqueReleasedMeshes.TryGetValue(key, out mesh); | ||
1023 | if (mesh != null) | ||
1024 | { | ||
1025 | m_uniqueReleasedMeshes.Remove(key); | ||
1026 | lock (m_uniqueMeshes) | ||
1027 | m_uniqueMeshes.Add(key, mesh); | ||
1028 | mesh.RefCount = 1; | ||
1029 | return mesh; | ||
1030 | } | ||
1031 | } | ||
1032 | /* | ||
1033 | Mesh UnitSizeMesh = null; | ||
1034 | ulong unitsizekey = 0; | ||
1035 | |||
1036 | unitsizekey = primShape.GetMeshKey(m_MeshUnitSize, lod, convex); | ||
1037 | |||
1038 | lock(m_uniqueMeshes) | ||
1039 | m_uniqueMeshes.TryGetValue(unitsizekey, out UnitSizeMesh); | ||
1040 | |||
1041 | if (UnitSizeMesh !=null) | ||
1042 | { | ||
1043 | UnitSizeMesh.RefCount++; | ||
1044 | mesh = UnitSizeMesh.Clone(); | ||
1045 | mesh.Key = key; | ||
1046 | mesh.Scale(size); | ||
1047 | mesh.RefCount++; | ||
1048 | lock(m_uniqueMeshes) | ||
1049 | m_uniqueMeshes.Add(key, mesh); | ||
1050 | return mesh; | ||
1051 | } | ||
1052 | */ | ||
1008 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); | 1053 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); |
1054 | // mesh.Key = unitsizekey; | ||
1009 | 1055 | ||
1010 | if (mesh != null) | 1056 | if (mesh != null) |
1011 | { | 1057 | { |
@@ -1021,11 +1067,68 @@ namespace OpenSim.Region.Physics.Meshing | |||
1021 | 1067 | ||
1022 | // trim the vertex and triangle lists to free up memory | 1068 | // trim the vertex and triangle lists to free up memory |
1023 | mesh.TrimExcess(); | 1069 | mesh.TrimExcess(); |
1070 | mesh.Key = key; | ||
1071 | mesh.RefCount++; | ||
1024 | 1072 | ||
1025 | m_uniqueMeshes.Add(key, mesh); | 1073 | lock(m_uniqueMeshes) |
1074 | m_uniqueMeshes.Add(key, mesh); | ||
1026 | } | 1075 | } |
1027 | 1076 | ||
1028 | return mesh; | 1077 | return mesh; |
1029 | } | 1078 | } |
1079 | |||
1080 | public void ReleaseMesh(IMesh imesh) | ||
1081 | { | ||
1082 | if (imesh == null) | ||
1083 | return; | ||
1084 | |||
1085 | Mesh mesh = (Mesh)imesh; | ||
1086 | |||
1087 | int curRefCount = mesh.RefCount; | ||
1088 | curRefCount--; | ||
1089 | |||
1090 | if (curRefCount > 0) | ||
1091 | { | ||
1092 | mesh.RefCount = curRefCount; | ||
1093 | return; | ||
1094 | } | ||
1095 | |||
1096 | lock (m_uniqueMeshes) | ||
1097 | { | ||
1098 | mesh.RefCount = 0; | ||
1099 | m_uniqueMeshes.Remove(mesh.Key); | ||
1100 | lock (m_uniqueReleasedMeshes) | ||
1101 | m_uniqueReleasedMeshes.Add(mesh.Key, mesh); | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | public void ExpireReleaseMeshs() | ||
1106 | { | ||
1107 | if (m_uniqueMeshes.Count == 0) | ||
1108 | return; | ||
1109 | |||
1110 | List<Mesh> meshstodelete = new List<Mesh>(); | ||
1111 | int refcntr; | ||
1112 | |||
1113 | lock (m_uniqueReleasedMeshes) | ||
1114 | { | ||
1115 | foreach (Mesh m in m_uniqueReleasedMeshes.Values) | ||
1116 | { | ||
1117 | refcntr = m.RefCount; | ||
1118 | refcntr--; | ||
1119 | if (refcntr > -6) | ||
1120 | m.RefCount = refcntr; | ||
1121 | else | ||
1122 | meshstodelete.Add(m); | ||
1123 | } | ||
1124 | |||
1125 | foreach (Mesh m in meshstodelete) | ||
1126 | { | ||
1127 | m_uniqueReleasedMeshes.Remove(m.Key); | ||
1128 | m.releaseSourceMeshData(); | ||
1129 | m.releasePinned(); | ||
1130 | } | ||
1131 | } | ||
1132 | } | ||
1030 | } | 1133 | } |
1031 | } | 1134 | } |