aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs117
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}