diff options
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 259 |
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; | |||
42 | using System.IO; | 42 | using System.IO; |
43 | using ComponentAce.Compression.Libs.zlib; | 43 | using ComponentAce.Compression.Libs.zlib; |
44 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 44 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
45 | using System.Runtime.Serialization; | ||
46 | using System.Runtime.Serialization.Formatters.Binary; | ||
45 | 47 | ||
46 | namespace OpenSim.Region.Physics.Meshing | 48 | namespace 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 | } |