aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs259
1 files changed, 205 insertions, 54 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index dec5eb7..952ecc8 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -42,6 +42,8 @@ using System.Reflection;
42using System.IO; 42using System.IO;
43using ComponentAce.Compression.Libs.zlib; 43using ComponentAce.Compression.Libs.zlib;
44using OpenSim.Region.Physics.ConvexDecompositionDotNet; 44using OpenSim.Region.Physics.ConvexDecompositionDotNet;
45using System.Runtime.Serialization;
46using System.Runtime.Serialization.Formatters.Binary;
45 47
46namespace OpenSim.Region.Physics.Meshing 48namespace OpenSim.Region.Physics.Meshing
47{ 49{
@@ -68,18 +70,20 @@ namespace OpenSim.Region.Physics.Meshing
68 70
69 // Setting baseDir to a path will enable the dumping of raw files 71 // Setting baseDir to a path will enable the dumping of raw files
70 // raw files can be imported by blender so a visual inspection of the results can be done 72 // raw files can be imported by blender so a visual inspection of the results can be done
71#if SPAM 73
72 const string baseDir = "rawFiles"; 74 public object diskLock = new object();
73#else 75
76 public bool doMeshFileCache = true;
77
78 public string cachePath = "MeshCache";
79
80// const string baseDir = "rawFiles";
74 private const string baseDir = null; //"rawFiles"; 81 private const string baseDir = null; //"rawFiles";
75#endif
76 82
77 private bool useMeshiesPhysicsMesh = false; 83 private bool useMeshiesPhysicsMesh = false;
78 84
79 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 85 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
80 86
81// private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
82// private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>();
83 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>(); 87 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
84 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>(); 88 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
85 89
@@ -89,8 +93,16 @@ namespace OpenSim.Region.Physics.Meshing
89 IConfig mesh_config = config.Configs["Mesh"]; 93 IConfig mesh_config = config.Configs["Mesh"];
90 94
91 if(mesh_config != null) 95 if(mesh_config != null)
96 {
92 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 97 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
93 98 if(useMeshiesPhysicsMesh)
99 {
100 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
101 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
102 }
103 else
104 doMeshFileCache = false;
105 }
94 } 106 }
95 107
96 /// <summary> 108 /// <summary>
@@ -188,7 +200,7 @@ namespace OpenSim.Region.Physics.Meshing
188 /// <param name="size">Size of entire object</param> 200 /// <param name="size">Size of entire object</param>
189 /// <param name="coords"></param> 201 /// <param name="coords"></param>
190 /// <param name="faces"></param> 202 /// <param name="faces"></param>
191 private void AddSubMesh(OSDMap subMeshData, Vector3 size, List<Coord> coords, List<Face> faces) 203 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces)
192 { 204 {
193 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); 205 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
194 206
@@ -221,9 +233,9 @@ namespace OpenSim.Region.Physics.Meshing
221 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4); 233 ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
222 234
223 Coord c = new Coord( 235 Coord c = new Coord(
224 Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X, 236 Utils.UInt16ToFloat(uX, posMin.X, posMax.X),
225 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y, 237 Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y),
226 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z); 238 Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z));
227 239
228 coords.Add(c); 240 coords.Add(c);
229 } 241 }
@@ -247,7 +259,7 @@ namespace OpenSim.Region.Physics.Meshing
247 /// <param name="size"></param> 259 /// <param name="size"></param>
248 /// <param name="lod"></param> 260 /// <param name="lod"></param>
249 /// <returns></returns> 261 /// <returns></returns>
250 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool convex) 262 private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, float lod, bool convex)
251 { 263 {
252// m_log.DebugFormat( 264// m_log.DebugFormat(
253// "[MESH]: Creating physics proxy for {0}, shape {1}", 265// "[MESH]: Creating physics proxy for {0}, shape {1}",
@@ -263,18 +275,18 @@ namespace OpenSim.Region.Physics.Meshing
263 if (!useMeshiesPhysicsMesh) 275 if (!useMeshiesPhysicsMesh)
264 return null; 276 return null;
265 277
266 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, convex)) 278 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
267 return null; 279 return null;
268 } 280 }
269 else 281 else
270 { 282 {
271 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces)) 283 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
272 return null; 284 return null;
273 } 285 }
274 } 286 }
275 else 287 else
276 { 288 {
277 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces)) 289 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, out coords, out faces))
278 return null; 290 return null;
279 } 291 }
280 292
@@ -309,7 +321,7 @@ namespace OpenSim.Region.Physics.Meshing
309 /// <param name="faces">Faces are added to this list by the method.</param> 321 /// <param name="faces">Faces are added to this list by the method.</param>
310 /// <returns>true if coords and faces were successfully generated, false if not</returns> 322 /// <returns>true if coords and faces were successfully generated, false if not</returns>
311 private bool GenerateCoordsAndFacesFromPrimMeshData( 323 private bool GenerateCoordsAndFacesFromPrimMeshData(
312 string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces, bool convex) 324 string primName, PrimitiveBaseShape primShape, out List<Coord> coords, out List<Face> faces, bool convex)
313 { 325 {
314// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName); 326// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
315 327
@@ -382,7 +394,7 @@ namespace OpenSim.Region.Physics.Meshing
382 OSD decodedMeshOsd = new OSD(); 394 OSD decodedMeshOsd = new OSD();
383 byte[] meshBytes = new byte[physSize]; 395 byte[] meshBytes = new byte[physSize];
384 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 396 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
385// byte[] decompressed = new byte[physSize * 5]; 397
386 try 398 try
387 { 399 {
388 using (MemoryStream inMs = new MemoryStream(meshBytes)) 400 using (MemoryStream inMs = new MemoryStream(meshBytes))
@@ -420,13 +432,13 @@ namespace OpenSim.Region.Physics.Meshing
420 // physics_shape is an array of OSDMaps, one for each submesh 432 // physics_shape is an array of OSDMaps, one for each submesh
421 if (decodedMeshOsd is OSDArray) 433 if (decodedMeshOsd is OSDArray)
422 { 434 {
423// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 435// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
424 436
425 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 437 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
426 foreach (OSD subMeshOsd in decodedMeshOsdArray) 438 foreach (OSD subMeshOsd in decodedMeshOsdArray)
427 { 439 {
428 if (subMeshOsd is OSDMap) 440 if (subMeshOsd is OSDMap)
429 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 441 AddSubMesh(subMeshOsd as OSDMap, coords, faces);
430 } 442 }
431 } 443 }
432 } 444 }
@@ -498,9 +510,9 @@ namespace OpenSim.Region.Physics.Meshing
498 t3 = data[ptr++]; 510 t3 = data[ptr++];
499 t3 += data[ptr++] << 8; 511 t3 += data[ptr++] << 8;
500 512
501 f3 = new float3((t1 * range.X + min.X) * size.X, 513 f3 = new float3((t1 * range.X + min.X),
502 (t2 * range.Y + min.Y) * size.Y, 514 (t2 * range.Y + min.Y),
503 (t3 * range.Z + min.Z) * size.Z); 515 (t3 * range.Z + min.Z));
504 vs.Add(f3); 516 vs.Add(f3);
505 } 517 }
506 518
@@ -597,9 +609,9 @@ namespace OpenSim.Region.Physics.Meshing
597 t3 = data[i++]; 609 t3 = data[i++];
598 t3 += data[i++] << 8; 610 t3 += data[i++] << 8;
599 611
600 f3 = new float3((t1 * range.X + min.X) * size.X, 612 f3 = new float3((t1 * range.X + min.X),
601 (t2 * range.Y + min.Y) * size.Y, 613 (t2 * range.Y + min.Y),
602 (t3 * range.Z + min.Z) * size.Z); 614 (t3 * range.Z + min.Z));
603 vs.Add(f3); 615 vs.Add(f3);
604 } 616 }
605 617
@@ -687,7 +699,7 @@ namespace OpenSim.Region.Physics.Meshing
687 /// <param name="faces">Faces are added to this list by the method.</param> 699 /// <param name="faces">Faces are added to this list by the method.</param>
688 /// <returns>true if coords and faces were successfully generated, false if not</returns> 700 /// <returns>true if coords and faces were successfully generated, false if not</returns>
689 private bool GenerateCoordsAndFacesFromPrimSculptData( 701 private bool GenerateCoordsAndFacesFromPrimSculptData(
690 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces) 702 string primName, PrimitiveBaseShape primShape, float lod, out List<Coord> coords, out List<Face> faces)
691 { 703 {
692 coords = new List<Coord>(); 704 coords = new List<Coord>();
693 faces = new List<Face>(); 705 faces = new List<Face>();
@@ -757,9 +769,7 @@ namespace OpenSim.Region.Physics.Meshing
757 769
758 idata.Dispose(); 770 idata.Dispose();
759 771
760 sculptMesh.DumpRaw(baseDir, primName, "primMesh"); 772// sculptMesh.DumpRaw(baseDir, primName, "primMesh");
761
762 sculptMesh.Scale(size.X, size.Y, size.Z);
763 773
764 coords = sculptMesh.coords; 774 coords = sculptMesh.coords;
765 faces = sculptMesh.faces; 775 faces = sculptMesh.faces;
@@ -777,7 +787,7 @@ namespace OpenSim.Region.Physics.Meshing
777 /// <param name="faces">Faces are added to this list by the method.</param> 787 /// <param name="faces">Faces are added to this list by the method.</param>
778 /// <returns>true if coords and faces were successfully generated, false if not</returns> 788 /// <returns>true if coords and faces were successfully generated, false if not</returns>
779 private bool GenerateCoordsAndFacesFromPrimShapeData( 789 private bool GenerateCoordsAndFacesFromPrimShapeData(
780 string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces) 790 string primName, PrimitiveBaseShape primShape, float lod, out List<Coord> coords, out List<Face> faces)
781 { 791 {
782 PrimMesh primMesh; 792 PrimMesh primMesh;
783 coords = new List<Coord>(); 793 coords = new List<Coord>();
@@ -912,9 +922,7 @@ namespace OpenSim.Region.Physics.Meshing
912 } 922 }
913 } 923 }
914 924
915 primMesh.DumpRaw(baseDir, primName, "primMesh"); 925// primMesh.DumpRaw(baseDir, primName, "primMesh");
916
917 primMesh.Scale(size.X, size.Y, size.Z);
918 926
919 coords = primMesh.coords; 927 coords = primMesh.coords;
920 faces = primMesh.faces; 928 faces = primMesh.faces;
@@ -934,6 +942,7 @@ namespace OpenSim.Region.Physics.Meshing
934 { 942 {
935 key.uuid = primShape.SculptTexture; 943 key.uuid = primShape.SculptTexture;
936 key.hashB = mdjb2(key.hashB, primShape.SculptType); 944 key.hashB = mdjb2(key.hashB, primShape.SculptType);
945 key.hashB = mdjb2(key.hashB, primShape.PCode);
937 } 946 }
938 else 947 else
939 { 948 {
@@ -956,6 +965,7 @@ namespace OpenSim.Region.Physics.Meshing
956 hash = mdjb2(hash, primShape.ProfileBegin); 965 hash = mdjb2(hash, primShape.ProfileBegin);
957 hash = mdjb2(hash, primShape.ProfileEnd); 966 hash = mdjb2(hash, primShape.ProfileEnd);
958 hash = mdjb2(hash, primShape.ProfileHollow); 967 hash = mdjb2(hash, primShape.ProfileHollow);
968 hash = mdjb2(hash, primShape.PCode);
959 key.hashA = hash; 969 key.hashA = hash;
960 } 970 }
961 971
@@ -1001,8 +1011,6 @@ namespace OpenSim.Region.Physics.Meshing
1001 return CreateMesh(primName, primShape, size, lod, false,false,false); 1011 return CreateMesh(primName, primShape, size, lod, false,false,false);
1002 } 1012 }
1003 1013
1004 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
1005
1006 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) 1014 public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
1007 { 1015 {
1008 Mesh mesh = null; 1016 Mesh mesh = null;
@@ -1031,7 +1039,13 @@ namespace OpenSim.Region.Physics.Meshing
1031 { 1039 {
1032 m_uniqueReleasedMeshes.Remove(key); 1040 m_uniqueReleasedMeshes.Remove(key);
1033 lock (m_uniqueMeshes) 1041 lock (m_uniqueMeshes)
1034 m_uniqueMeshes.Add(key, mesh); 1042 {
1043 try
1044 {
1045 m_uniqueMeshes.Add(key, mesh);
1046 }
1047 catch { }
1048 }
1035 mesh.RefCount = 1; 1049 mesh.RefCount = 1;
1036 return mesh; 1050 return mesh;
1037 } 1051 }
@@ -1039,6 +1053,8 @@ namespace OpenSim.Region.Physics.Meshing
1039 return null; 1053 return null;
1040 } 1054 }
1041 1055
1056 private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f);
1057
1042 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) 1058 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde)
1043 { 1059 {
1044#if SPAM 1060#if SPAM
@@ -1074,41 +1090,78 @@ namespace OpenSim.Region.Physics.Meshing
1074 { 1090 {
1075 m_uniqueReleasedMeshes.Remove(key); 1091 m_uniqueReleasedMeshes.Remove(key);
1076 lock (m_uniqueMeshes) 1092 lock (m_uniqueMeshes)
1077 m_uniqueMeshes.Add(key, mesh); 1093 {
1094 try
1095 {
1096 m_uniqueMeshes.Add(key, mesh);
1097 }
1098 catch { }
1099 }
1078 mesh.RefCount = 1; 1100 mesh.RefCount = 1;
1079 return mesh; 1101 return mesh;
1080 } 1102 }
1081 } 1103 }
1082 1104
1083 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); 1105 Mesh UnitMesh = null;
1106 AMeshKey unitKey = GetMeshUniqueKey(primShape, m_MeshUnitSize, (byte)lod, convex);
1084 1107
1085 if (mesh != null) 1108 lock (m_uniqueReleasedMeshes)
1086 { 1109 {
1087 if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh) 1110 m_uniqueReleasedMeshes.TryGetValue(unitKey, out UnitMesh);
1111 if (UnitMesh != null)
1088 { 1112 {
1089#if SPAM 1113 UnitMesh.RefCount = 1;
1090 m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " +
1091 minSizeForComplexMesh.ToString() + " - creating simple bounding box");
1092#endif
1093 mesh = CreateBoundingBoxMesh(mesh);
1094 mesh.DumpRaw(baseDir, primName, "Z extruded");
1095 } 1114 }
1115 }
1116
1117 if (UnitMesh == null && primShape.SculptEntry && doMeshFileCache)
1118 UnitMesh = GetFromFileCache(unitKey);
1119
1120 if (UnitMesh == null)
1121 {
1122 UnitMesh = CreateMeshFromPrimMesher(primName, primShape, lod, convex);
1123
1124 if (UnitMesh == null)
1125 return null;
1126
1127 UnitMesh.DumpRaw(baseDir, unitKey.ToString(), "Z");
1096 1128
1097 if (forOde) 1129 if (forOde)
1098 { 1130 {
1099 // force pinned mem allocation 1131 // force pinned mem allocation
1100 mesh.PrepForOde(); 1132 UnitMesh.PrepForOde();
1101 } 1133 }
1102 else 1134 else
1103 mesh.TrimExcess(); 1135 UnitMesh.TrimExcess();
1104 1136
1105 mesh.Key = key; 1137 UnitMesh.Key = unitKey;
1106 mesh.RefCount = 1; 1138 UnitMesh.RefCount = 1;
1107 1139
1108 lock(m_uniqueMeshes) 1140 if (doMeshFileCache && primShape.SculptEntry)
1109 m_uniqueMeshes.Add(key, mesh); 1141 StoreToFileCache(unitKey, UnitMesh);
1142
1143 lock (m_uniqueReleasedMeshes)
1144 {
1145 try
1146 {
1147 m_uniqueReleasedMeshes.Add(unitKey, UnitMesh);
1148 }
1149 catch { }
1150 }
1110 } 1151 }
1111 1152
1153 mesh = UnitMesh.Scale(size);
1154 mesh.Key = key;
1155 mesh.RefCount = 1;
1156 lock (m_uniqueMeshes)
1157 {
1158 try
1159 {
1160 m_uniqueMeshes.Add(key, mesh);
1161 }
1162 catch { }
1163 }
1164
1112 return mesh; 1165 return mesh;
1113 } 1166 }
1114 1167
@@ -1133,7 +1186,13 @@ namespace OpenSim.Region.Physics.Meshing
1133 mesh.RefCount = 0; 1186 mesh.RefCount = 0;
1134 m_uniqueMeshes.Remove(mesh.Key); 1187 m_uniqueMeshes.Remove(mesh.Key);
1135 lock (m_uniqueReleasedMeshes) 1188 lock (m_uniqueReleasedMeshes)
1136 m_uniqueReleasedMeshes.Add(mesh.Key, mesh); 1189 {
1190 try
1191 {
1192 m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
1193 }
1194 catch { }
1195 }
1137 } 1196 }
1138 } 1197 }
1139 1198
@@ -1160,10 +1219,102 @@ namespace OpenSim.Region.Physics.Meshing
1160 foreach (Mesh m in meshstodelete) 1219 foreach (Mesh m in meshstodelete)
1161 { 1220 {
1162 m_uniqueReleasedMeshes.Remove(m.Key); 1221 m_uniqueReleasedMeshes.Remove(m.Key);
1163 m.releaseSourceMeshData(); 1222 m.releaseBuildingMeshData();
1164 m.releasePinned(); 1223 m.releasePinned();
1165 } 1224 }
1166 } 1225 }
1167 } 1226 }
1227
1228 public void FileNames(AMeshKey key, out string dir,out string fullFileName)
1229 {
1230 string id = key.ToString();
1231 string init = id.Substring(0, 1);
1232 dir = System.IO.Path.Combine(cachePath, init);
1233 fullFileName = System.IO.Path.Combine(dir, id);
1234 }
1235
1236 public string FullFileName(AMeshKey key)
1237 {
1238 string id = key.ToString();
1239 string init = id.Substring(0,1);
1240 id = System.IO.Path.Combine(init, id);
1241 id = System.IO.Path.Combine(cachePath, id);
1242 return id;
1243 }
1244
1245 private Mesh GetFromFileCache(AMeshKey key)
1246 {
1247 Mesh mesh = null;
1248 string filename = FullFileName(key);
1249 bool ok = true;
1250
1251 lock (diskLock)
1252 {
1253 if (File.Exists(filename))
1254 {
1255 FileStream stream = null;
1256 try
1257 {
1258 stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
1259 BinaryFormatter bformatter = new BinaryFormatter();
1260
1261 mesh = Mesh.FromStream(stream, key);
1262 }
1263 catch (Exception e)
1264 {
1265 ok = false;
1266 m_log.ErrorFormat(
1267 "[MESH CACHE]: Failed to get file {0}. Exception {1} {2}",
1268 filename, e.Message, e.StackTrace);
1269 }
1270 if (stream != null)
1271 stream.Close();
1272
1273 if (mesh == null || !ok)
1274 File.Delete(filename);
1275 }
1276 }
1277
1278 return mesh;
1279 }
1280
1281 private void StoreToFileCache(AMeshKey key, Mesh mesh)
1282 {
1283 Stream stream = null;
1284 bool ok = false;
1285
1286 // Make sure the target cache directory exists
1287 string dir = String.Empty;
1288 string filename = String.Empty;
1289
1290 FileNames(key, out dir, out filename);
1291
1292 lock (diskLock)
1293 {
1294 try
1295 {
1296 if (!Directory.Exists(dir))
1297 {
1298 Directory.CreateDirectory(dir);
1299 }
1300
1301 stream = File.Open(filename, FileMode.Create);
1302 ok = mesh.ToStream(stream);
1303 }
1304 catch (IOException e)
1305 {
1306 m_log.ErrorFormat(
1307 "[MESH CACHE]: Failed to write file {0}. Exception {1} {2}.",
1308 filename, e.Message, e.StackTrace);
1309 ok = false;
1310 }
1311
1312 if (stream != null)
1313 stream.Close();
1314
1315 if (!ok && File.Exists(filename))
1316 File.Delete(filename);
1317 }
1318 }
1168 } 1319 }
1169} 1320}