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.cs183
1 files changed, 172 insertions, 11 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index f002bba..4c40175 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -82,7 +82,10 @@ namespace OpenSim.Region.Physics.Meshing
82 82
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>();
87 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
88 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
86 89
87 public Meshmerizer(IConfigSource config) 90 public Meshmerizer(IConfigSource config)
88 { 91 {
@@ -314,6 +317,9 @@ namespace OpenSim.Region.Physics.Meshing
314 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z)); 317 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z));
315 } 318 }
316 319
320 coords.Clear();
321 faces.Clear();
322
317 return mesh; 323 return mesh;
318 } 324 }
319 325
@@ -780,7 +786,9 @@ namespace OpenSim.Region.Physics.Meshing
780 } 786 }
781 787
782 PrimMesher.SculptMesh.SculptType sculptType; 788 PrimMesher.SculptMesh.SculptType sculptType;
783 switch ((OpenMetaverse.SculptType)primShape.SculptType) 789 // remove mirror and invert bits
790 OpenMetaverse.SculptType pbsSculptType = ((OpenMetaverse.SculptType)(primShape.SculptType & 0x3f));
791 switch (pbsSculptType)
784 { 792 {
785 case OpenMetaverse.SculptType.Cylinder: 793 case OpenMetaverse.SculptType.Cylinder:
786 sculptType = PrimMesher.SculptMesh.SculptType.cylinder; 794 sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
@@ -802,7 +810,7 @@ namespace OpenSim.Region.Physics.Meshing
802 bool mirror = ((primShape.SculptType & 128) != 0); 810 bool mirror = ((primShape.SculptType & 128) != 0);
803 bool invert = ((primShape.SculptType & 64) != 0); 811 bool invert = ((primShape.SculptType & 64) != 0);
804 812
805 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); 813 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, mirror, invert);
806 814
807 idata.Dispose(); 815 idata.Dispose();
808 816
@@ -971,6 +979,76 @@ namespace OpenSim.Region.Physics.Meshing
971 return true; 979 return true;
972 } 980 }
973 981
982 public AMeshKey GetMeshUniqueKey(PrimitiveBaseShape primShape, Vector3 size, byte lod, bool convex)
983 {
984 AMeshKey key = new AMeshKey();
985 Byte[] someBytes;
986
987 key.hashB = 5181;
988 ulong hash = 5381;
989
990 if (primShape.SculptEntry)
991 {
992 key.uuid = primShape.SculptTexture;
993 key.hashB = mdjb2(key.hashB, primShape.SculptType);
994 }
995 else
996 {
997 hash = mdjb2(hash, primShape.PathCurve);
998 hash = mdjb2(hash, (byte)primShape.HollowShape);
999 hash = mdjb2(hash, (byte)primShape.ProfileShape);
1000 hash = mdjb2(hash, primShape.PathBegin);
1001 hash = mdjb2(hash, primShape.PathEnd);
1002 hash = mdjb2(hash, primShape.PathScaleX);
1003 hash = mdjb2(hash, primShape.PathScaleY);
1004 hash = mdjb2(hash, primShape.PathShearX);
1005 hash = mdjb2(hash, primShape.PathShearY);
1006 hash = mdjb2(hash, (byte)primShape.PathTwist);
1007 hash = mdjb2(hash, (byte)primShape.PathTwistBegin);
1008 hash = mdjb2(hash, (byte)primShape.PathRadiusOffset);
1009 hash = mdjb2(hash, (byte)primShape.PathTaperX);
1010 hash = mdjb2(hash, (byte)primShape.PathTaperY);
1011 hash = mdjb2(hash, primShape.PathRevolutions);
1012 hash = mdjb2(hash, (byte)primShape.PathSkew);
1013 hash = mdjb2(hash, primShape.ProfileBegin);
1014 hash = mdjb2(hash, primShape.ProfileEnd);
1015 hash = mdjb2(hash, primShape.ProfileHollow);
1016 key.hashA = hash;
1017 }
1018
1019 hash = key.hashB;
1020
1021 someBytes = size.GetBytes();
1022 for (int i = 0; i < someBytes.Length; i++)
1023 hash = mdjb2(hash, someBytes[i]);
1024
1025 hash = mdjb2(hash, lod);
1026
1027 hash &= 0x3fffffffffffffff;
1028
1029 if (convex)
1030 hash |= 0x4000000000000000;
1031
1032 if (primShape.SculptEntry)
1033 hash |= 0x8000000000000000;
1034
1035 key.hashB = hash;
1036
1037 return key;
1038 }
1039
1040 private ulong mdjb2(ulong hash, byte c)
1041 {
1042 return ((hash << 5) + hash) + (ulong)c;
1043 }
1044
1045 private ulong mdjb2(ulong hash, ushort c)
1046 {
1047 hash = ((hash << 5) + hash) + (ulong)((byte)c);
1048 return ((hash << 5) + hash) + (ulong)(c >> 8);
1049 }
1050
1051
974 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 1052 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
975 { 1053 {
976 return CreateMesh(primName, primShape, size, lod, false,false); 1054 return CreateMesh(primName, primShape, size, lod, false,false);
@@ -981,6 +1059,8 @@ namespace OpenSim.Region.Physics.Meshing
981 return CreateMesh(primName, primShape, size, lod, false,false); 1059 return CreateMesh(primName, primShape, size, lod, false,false);
982 } 1060 }
983 1061
1062 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
1063
984 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) 1064 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
985 { 1065 {
986#if SPAM 1066#if SPAM
@@ -988,18 +1068,42 @@ namespace OpenSim.Region.Physics.Meshing
988#endif 1068#endif
989 1069
990 Mesh mesh = null; 1070 Mesh mesh = null;
991 ulong key = 0; 1071// ulong key = 0;
992 1072
993 // If this mesh has been created already, return it instead of creating another copy
994 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
995 key = primShape.GetMeshKey(size, lod, convex);
996 if (m_uniqueMeshes.TryGetValue(key, out mesh))
997 return mesh;
998 1073
999 if (size.X < 0.01f) size.X = 0.01f; 1074 if (size.X < 0.01f) size.X = 0.01f;
1000 if (size.Y < 0.01f) size.Y = 0.01f; 1075 if (size.Y < 0.01f) size.Y = 0.01f;
1001 if (size.Z < 0.01f) size.Z = 0.01f; 1076 if (size.Z < 0.01f) size.Z = 0.01f;
1002 1077
1078 // try to find a identical mesh on meshs in use
1079// key = primShape.GetMeshKey(size, lod, convex);
1080 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
1081
1082 lock (m_uniqueMeshes)
1083 {
1084 m_uniqueMeshes.TryGetValue(key, out mesh);
1085
1086 if (mesh != null)
1087 {
1088 mesh.RefCount++;
1089 return mesh;
1090 }
1091 }
1092
1093 // try to find a identical mesh on meshs recently released
1094 lock (m_uniqueReleasedMeshes)
1095 {
1096 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1097 if (mesh != null)
1098 {
1099 m_uniqueReleasedMeshes.Remove(key);
1100 lock (m_uniqueMeshes)
1101 m_uniqueMeshes.Add(key, mesh);
1102 mesh.RefCount = 1;
1103 return mesh;
1104 }
1105 }
1106
1003 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); 1107 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
1004 1108
1005 if (mesh != null) 1109 if (mesh != null)
@@ -1016,11 +1120,68 @@ namespace OpenSim.Region.Physics.Meshing
1016 1120
1017 // trim the vertex and triangle lists to free up memory 1121 // trim the vertex and triangle lists to free up memory
1018 mesh.TrimExcess(); 1122 mesh.TrimExcess();
1123 mesh.Key = key;
1124 mesh.RefCount = 1;
1019 1125
1020 m_uniqueMeshes.Add(key, mesh); 1126 lock(m_uniqueMeshes)
1127 m_uniqueMeshes.Add(key, mesh);
1021 } 1128 }
1022 1129
1023 return mesh; 1130 return mesh;
1024 } 1131 }
1132
1133 public void ReleaseMesh(IMesh imesh)
1134 {
1135 if (imesh == null)
1136 return;
1137
1138 Mesh mesh = (Mesh)imesh;
1139
1140 int curRefCount = mesh.RefCount;
1141 curRefCount--;
1142
1143 if (curRefCount > 0)
1144 {
1145 mesh.RefCount = curRefCount;
1146 return;
1147 }
1148
1149 lock (m_uniqueMeshes)
1150 {
1151 mesh.RefCount = 0;
1152 m_uniqueMeshes.Remove(mesh.Key);
1153 lock (m_uniqueReleasedMeshes)
1154 m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
1155 }
1156 }
1157
1158 public void ExpireReleaseMeshs()
1159 {
1160 if (m_uniqueReleasedMeshes.Count == 0)
1161 return;
1162
1163 List<Mesh> meshstodelete = new List<Mesh>();
1164 int refcntr;
1165
1166 lock (m_uniqueReleasedMeshes)
1167 {
1168 foreach (Mesh m in m_uniqueReleasedMeshes.Values)
1169 {
1170 refcntr = m.RefCount;
1171 refcntr--;
1172 if (refcntr > -6)
1173 m.RefCount = refcntr;
1174 else
1175 meshstodelete.Add(m);
1176 }
1177
1178 foreach (Mesh m in meshstodelete)
1179 {
1180 m_uniqueReleasedMeshes.Remove(m.Key);
1181 m.releaseSourceMeshData();
1182 m.releasePinned();
1183 }
1184 }
1185 }
1025 } 1186 }
1026} 1187}