aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs551
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs259
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs4
3 files changed, 532 insertions, 282 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
index a0a18c4..1e9b8bc 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
@@ -32,30 +32,49 @@ using System.Runtime.InteropServices;
32using OpenSim.Region.Physics.Manager; 32using OpenSim.Region.Physics.Manager;
33using PrimMesher; 33using PrimMesher;
34using OpenMetaverse; 34using OpenMetaverse;
35using System.Runtime.Serialization;
36using System.Runtime.Serialization.Formatters.Binary;
35 37
36namespace OpenSim.Region.Physics.Meshing 38namespace OpenSim.Region.Physics.Meshing
37{ 39{
38 public class Mesh : IMesh 40 public class MeshBuildingData
39 { 41 {
42 public Dictionary<Vertex, int> m_vertices;
43 public List<Triangle> m_triangles;
44 public float m_obbXmin;
45 public float m_obbXmax;
46 public float m_obbYmin;
47 public float m_obbYmax;
48 public float m_obbZmin;
49 public float m_obbZmax;
50 public Vector3 m_centroid;
51 public int m_centroidDiv;
52 }
40 53
41 private Dictionary<Vertex, int> m_vertices; 54 [Serializable()]
42 private List<Triangle> m_triangles; 55 public class Mesh : IMesh
43 GCHandle m_pinnedVertexes; 56 {
44 GCHandle m_pinnedIndex; 57 float[] vertices;
58 int[] indexes;
59 Vector3 m_obb;
60 Vector3 m_obboffset;
61 [NonSerialized()]
62 MeshBuildingData m_bdata;
63 [NonSerialized()]
64 GCHandle vhandler;
65 [NonSerialized()]
66 GCHandle ihandler;
67 [NonSerialized()]
45 IntPtr m_verticesPtr = IntPtr.Zero; 68 IntPtr m_verticesPtr = IntPtr.Zero;
46 int m_vertexCount = 0; 69 [NonSerialized()]
47 IntPtr m_indicesPtr = IntPtr.Zero; 70 IntPtr m_indicesPtr = IntPtr.Zero;
71 [NonSerialized()]
72 int m_vertexCount = 0;
73 [NonSerialized()]
48 int m_indexCount = 0; 74 int m_indexCount = 0;
49 public float[] m_normals;
50 Vector3 m_centroid;
51 float m_obbXmin;
52 float m_obbXmax;
53 float m_obbYmin;
54 float m_obbYmax;
55 float m_obbZmin;
56 float m_obbZmax;
57 75
58 int m_centroidDiv; 76 public int RefCount { get; set; }
77 public AMeshKey Key { get; set; }
59 78
60 private class vertexcomp : IEqualityComparer<Vertex> 79 private class vertexcomp : IEqualityComparer<Vertex>
61 { 80 {
@@ -79,42 +98,82 @@ namespace OpenSim.Region.Physics.Meshing
79 { 98 {
80 vertexcomp vcomp = new vertexcomp(); 99 vertexcomp vcomp = new vertexcomp();
81 100
82 m_vertices = new Dictionary<Vertex, int>(vcomp); 101 m_bdata = new MeshBuildingData();
83 m_triangles = new List<Triangle>(); 102 m_bdata.m_vertices = new Dictionary<Vertex, int>(vcomp);
84 m_centroid = Vector3.Zero; 103 m_bdata.m_triangles = new List<Triangle>();
85 m_centroidDiv = 0; 104 m_bdata.m_centroid = Vector3.Zero;
86 m_obbXmin = float.MaxValue; 105 m_bdata.m_centroidDiv = 0;
87 m_obbXmax = float.MinValue; 106 m_bdata.m_obbXmin = float.MaxValue;
88 m_obbYmin = float.MaxValue; 107 m_bdata.m_obbXmax = float.MinValue;
89 m_obbYmax = float.MinValue; 108 m_bdata.m_obbYmin = float.MaxValue;
90 m_obbZmin = float.MaxValue; 109 m_bdata.m_obbYmax = float.MinValue;
91 m_obbZmax = float.MinValue; 110 m_bdata.m_obbZmin = float.MaxValue;
111 m_bdata.m_obbZmax = float.MinValue;
112 m_obb = new Vector3(0.5f, 0.5f, 0.5f);
113 m_obboffset = Vector3.Zero;
92 } 114 }
93 115
94 public int RefCount { get; set; }
95
96 public AMeshKey Key { get; set; }
97 116
98 public void Scale(Vector3 scale) 117 public Mesh Scale(Vector3 scale)
99 { 118 {
119 if (m_verticesPtr == null || m_indicesPtr == null)
120 return null;
121
122 Mesh result = new Mesh();
123
124 float x = scale.X;
125 float y = scale.Y;
126 float z = scale.Z;
127
128 result.m_obb.X = m_obb.X * x;
129 result.m_obb.Y = m_obb.Y * y;
130 result.m_obb.Z = m_obb.Z * z;
131 result.m_obboffset.X = m_obboffset.X * x;
132 result.m_obboffset.Y = m_obboffset.Y * y;
133 result.m_obboffset.Z = m_obboffset.Z * z;
134
135 result.vertices = new float[vertices.Length];
136 int j = 0;
137 for (int i = 0; i < m_vertexCount; i++)
138 {
139 result.vertices[j] = vertices[j] * x;
140 j++;
141 result.vertices[j] = vertices[j] * y;
142 j++;
143 result.vertices[j] = vertices[j] * z;
144 j++;
145 }
146
147 result.indexes = new int[indexes.Length];
148 indexes.CopyTo(result.indexes,0);
149
150 result.pinMemory();
151
152 return result;
100 } 153 }
101 154
102 public Mesh Clone() 155 public Mesh Clone()
103 { 156 {
104 Mesh result = new Mesh(); 157 Mesh result = new Mesh();
105 158
106 foreach (Triangle t in m_triangles) 159 if (m_bdata != null)
107 { 160 {
108 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); 161 result.m_bdata = new MeshBuildingData();
162 foreach (Triangle t in m_bdata.m_triangles)
163 {
164 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
165 }
166 result.m_bdata.m_centroid = m_bdata.m_centroid;
167 result.m_bdata.m_centroidDiv = m_bdata.m_centroidDiv;
168 result.m_bdata.m_obbXmin = m_bdata.m_obbXmin;
169 result.m_bdata.m_obbXmax = m_bdata.m_obbXmax;
170 result.m_bdata.m_obbYmin = m_bdata.m_obbYmin;
171 result.m_bdata.m_obbYmax = m_bdata.m_obbYmax;
172 result.m_bdata.m_obbZmin = m_bdata.m_obbZmin;
173 result.m_bdata.m_obbZmax = m_bdata.m_obbZmax;
109 } 174 }
110 result.m_centroid = m_centroid; 175 result.m_obb = m_obb;
111 result.m_centroidDiv = m_centroidDiv; 176 result.m_obboffset = m_obboffset;
112 result.m_obbXmin = m_obbXmin;
113 result.m_obbXmax = m_obbXmax;
114 result.m_obbYmin = m_obbYmin;
115 result.m_obbYmax = m_obbYmax;
116 result.m_obbZmin = m_obbZmin;
117 result.m_obbZmax = m_obbZmax;
118 return result; 177 return result;
119 } 178 }
120 179
@@ -124,37 +183,34 @@ namespace OpenSim.Region.Physics.Meshing
124 float y = v.Y; 183 float y = v.Y;
125 float z = v.Z; 184 float z = v.Z;
126 185
127 m_centroid.X += x; 186 m_bdata.m_centroid.X += x;
128 m_centroid.Y += y; 187 m_bdata.m_centroid.Y += y;
129 m_centroid.Z += z; 188 m_bdata.m_centroid.Z += z;
130 m_centroidDiv++; 189 m_bdata.m_centroidDiv++;
131 190
132 if (x > m_obbXmax) 191 if (x > m_bdata.m_obbXmax)
133 m_obbXmax = x; 192 m_bdata.m_obbXmax = x;
134 else if (x < m_obbXmin) 193 else if (x < m_bdata.m_obbXmin)
135 m_obbXmin = x; 194 m_bdata.m_obbXmin = x;
136 195
137 if (y > m_obbYmax) 196 if (y > m_bdata.m_obbYmax)
138 m_obbYmax = y; 197 m_bdata.m_obbYmax = y;
139 else if (y < m_obbYmin) 198 else if (y < m_bdata.m_obbYmin)
140 m_obbYmin = y; 199 m_bdata.m_obbYmin = y;
141 200
142 if (z > m_obbZmax) 201 if (z > m_bdata.m_obbZmax)
143 m_obbZmax = z; 202 m_bdata.m_obbZmax = z;
144 else if (z < m_obbZmin) 203 else if (z < m_bdata.m_obbZmin)
145 m_obbZmin = z; 204 m_bdata.m_obbZmin = z;
146 205
147 } 206 }
148 207
149 208
150 public void Add(Triangle triangle) 209 public void Add(Triangle triangle)
151 { 210 {
152 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 211 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
153 throw new NotSupportedException("Attempt to Add to a pinned Mesh"); 212 throw new NotSupportedException("Attempt to Add to a pinned Mesh");
154 // If a vertex of the triangle is not yet in the vertices list, 213
155 // add it and set its index to the current index count
156 // vertex == seems broken
157 // skip colapsed triangles
158 if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z) 214 if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
159 || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z) 215 || (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
160 || (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z) 216 || (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
@@ -163,46 +219,45 @@ namespace OpenSim.Region.Physics.Meshing
163 return; 219 return;
164 } 220 }
165 221
166 if (m_vertices.Count == 0) 222 if (m_bdata.m_vertices.Count == 0)
167 { 223 {
168 m_centroidDiv = 0; 224 m_bdata.m_centroidDiv = 0;
169 m_centroid = Vector3.Zero; 225 m_bdata.m_centroid = Vector3.Zero;
170 } 226 }
171 227
172 if (!m_vertices.ContainsKey(triangle.v1)) 228 if (!m_bdata.m_vertices.ContainsKey(triangle.v1))
173 { 229 {
174 m_vertices[triangle.v1] = m_vertices.Count; 230 m_bdata.m_vertices[triangle.v1] = m_bdata.m_vertices.Count;
175 addVertexLStats(triangle.v1); 231 addVertexLStats(triangle.v1);
176 } 232 }
177 if (!m_vertices.ContainsKey(triangle.v2)) 233 if (!m_bdata.m_vertices.ContainsKey(triangle.v2))
178 { 234 {
179 m_vertices[triangle.v2] = m_vertices.Count; 235 m_bdata.m_vertices[triangle.v2] = m_bdata.m_vertices.Count;
180 addVertexLStats(triangle.v2); 236 addVertexLStats(triangle.v2);
181 } 237 }
182 if (!m_vertices.ContainsKey(triangle.v3)) 238 if (!m_bdata.m_vertices.ContainsKey(triangle.v3))
183 { 239 {
184 m_vertices[triangle.v3] = m_vertices.Count; 240 m_bdata.m_vertices[triangle.v3] = m_bdata.m_vertices.Count;
185 addVertexLStats(triangle.v3); 241 addVertexLStats(triangle.v3);
186 } 242 }
187 m_triangles.Add(triangle); 243 m_bdata.m_triangles.Add(triangle);
188 } 244 }
189 245
190 public Vector3 GetCentroid() 246 public Vector3 GetCentroid()
191 { 247 {
192 if (m_centroidDiv > 0) 248 return m_obboffset;
193 return new Vector3(m_centroid.X / m_centroidDiv, m_centroid.Y / m_centroidDiv, m_centroid.Z / m_centroidDiv); 249
194 else
195 return Vector3.Zero;
196 } 250 }
197 251
198 public Vector3 GetOBB() 252 public Vector3 GetOBB()
199 { 253 {
254 return m_obb;
200 float x, y, z; 255 float x, y, z;
201 if (m_centroidDiv > 0) 256 if (m_bdata.m_centroidDiv > 0)
202 { 257 {
203 x = (m_obbXmax - m_obbXmin) * 0.5f; 258 x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
204 y = (m_obbYmax - m_obbYmin) * 0.5f; 259 y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
205 z = (m_obbZmax - m_obbZmin) * 0.5f; 260 z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
206 } 261 }
207 else // ?? 262 else // ??
208 { 263 {
@@ -213,72 +268,10 @@ namespace OpenSim.Region.Physics.Meshing
213 return new Vector3(x, y, z); 268 return new Vector3(x, y, z);
214 } 269 }
215 270
216 public void CalcNormals()
217 {
218 int iTriangles = m_triangles.Count;
219
220 this.m_normals = new float[iTriangles * 3];
221
222 int i = 0;
223 foreach (Triangle t in m_triangles)
224 {
225 float ux, uy, uz;
226 float vx, vy, vz;
227 float wx, wy, wz;
228
229 ux = t.v1.X;
230 uy = t.v1.Y;
231 uz = t.v1.Z;
232
233 vx = t.v2.X;
234 vy = t.v2.Y;
235 vz = t.v2.Z;
236
237 wx = t.v3.X;
238 wy = t.v3.Y;
239 wz = t.v3.Z;
240
241
242 // Vectors for edges
243 float e1x, e1y, e1z;
244 float e2x, e2y, e2z;
245
246 e1x = ux - vx;
247 e1y = uy - vy;
248 e1z = uz - vz;
249
250 e2x = ux - wx;
251 e2y = uy - wy;
252 e2z = uz - wz;
253
254
255 // Cross product for normal
256 float nx, ny, nz;
257 nx = e1y * e2z - e1z * e2y;
258 ny = e1z * e2x - e1x * e2z;
259 nz = e1x * e2y - e1y * e2x;
260
261 // Length
262 float l = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz);
263 float lReciprocal = 1.0f / l;
264
265 // Normalized "normal"
266 //nx /= l;
267 //ny /= l;
268 //nz /= l;
269
270 m_normals[i] = nx * lReciprocal;
271 m_normals[i + 1] = ny * lReciprocal;
272 m_normals[i + 2] = nz * lReciprocal;
273
274 i += 3;
275 }
276 }
277
278 public List<Vector3> getVertexList() 271 public List<Vector3> getVertexList()
279 { 272 {
280 List<Vector3> result = new List<Vector3>(); 273 List<Vector3> result = new List<Vector3>();
281 foreach (Vertex v in m_vertices.Keys) 274 foreach (Vertex v in m_bdata.m_vertices.Keys)
282 { 275 {
283 result.Add(new Vector3(v.X, v.Y, v.Z)); 276 result.Add(new Vector3(v.X, v.Y, v.Z));
284 } 277 }
@@ -287,10 +280,10 @@ namespace OpenSim.Region.Physics.Meshing
287 280
288 private float[] getVertexListAsFloat() 281 private float[] getVertexListAsFloat()
289 { 282 {
290 if (m_vertices == null) 283 if (m_bdata.m_vertices == null)
291 throw new NotSupportedException(); 284 throw new NotSupportedException();
292 float[] result = new float[m_vertices.Count * 3]; 285 float[] result = new float[m_bdata.m_vertices.Count * 3];
293 foreach (KeyValuePair<Vertex, int> kvp in m_vertices) 286 foreach (KeyValuePair<Vertex, int> kvp in m_bdata.m_vertices)
294 { 287 {
295 Vertex v = kvp.Key; 288 Vertex v = kvp.Key;
296 int i = kvp.Value; 289 int i = kvp.Value;
@@ -303,74 +296,39 @@ namespace OpenSim.Region.Physics.Meshing
303 296
304 public float[] getVertexListAsFloatLocked() 297 public float[] getVertexListAsFloatLocked()
305 { 298 {
306 if (m_pinnedVertexes.IsAllocated) 299 return null;
307 return (float[])(m_pinnedVertexes.Target);
308
309 float[] result = getVertexListAsFloat();
310 m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned);
311 // Inform the garbage collector of this unmanaged allocation so it can schedule
312 // the next GC round more intelligently
313 GC.AddMemoryPressure(Buffer.ByteLength(result));
314
315 return result;
316 }
317
318 public void PrepForOde()
319 {
320 // If there isn't an unmanaged array allocated yet, do it now
321 if (m_verticesPtr == IntPtr.Zero)
322 {
323 float[] vertexList = getVertexListAsFloat();
324 // Each vertex is 3 elements (floats)
325 m_vertexCount = vertexList.Length / 3;
326 int byteCount = m_vertexCount * 3 * sizeof(float);
327 m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
328 System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3);
329 }
330
331 // If there isn't an unmanaged array allocated yet, do it now
332 if (m_indicesPtr == IntPtr.Zero)
333 {
334 int[] indexList = getIndexListAsInt();
335 m_indexCount = indexList.Length;
336 int byteCount = m_indexCount * sizeof(int);
337 m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
338 System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount);
339 }
340
341 releaseSourceMeshData();
342 } 300 }
343 301
344 public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount) 302 public void getVertexListAsPtrToFloatArray(out IntPtr _vertices, out int vertexStride, out int vertexCount)
345 { 303 {
346 // A vertex is 3 floats 304 // A vertex is 3 floats
347 vertexStride = 3 * sizeof(float); 305 vertexStride = 3 * sizeof(float);
348 306
349 // If there isn't an unmanaged array allocated yet, do it now 307 // If there isn't an unmanaged array allocated yet, do it now
350 if (m_verticesPtr == IntPtr.Zero) 308 if (m_verticesPtr == IntPtr.Zero && m_bdata != null)
351 { 309 {
352 float[] vertexList = getVertexListAsFloat(); 310 vertices = getVertexListAsFloat();
353 // Each vertex is 3 elements (floats) 311 // Each vertex is 3 elements (floats)
354 m_vertexCount = vertexList.Length / 3; 312 m_vertexCount = vertices.Length / 3;
355 int byteCount = m_vertexCount * vertexStride; 313 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
356 m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); 314 m_verticesPtr = vhandler.AddrOfPinnedObject();
357 System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3); 315 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
358 } 316 }
359 vertices = m_verticesPtr; 317 _vertices = m_verticesPtr;
360 vertexCount = m_vertexCount; 318 vertexCount = m_vertexCount;
361 } 319 }
362 320
363 public int[] getIndexListAsInt() 321 public int[] getIndexListAsInt()
364 { 322 {
365 if (m_triangles == null) 323 if (m_bdata.m_triangles == null)
366 throw new NotSupportedException(); 324 throw new NotSupportedException();
367 int[] result = new int[m_triangles.Count * 3]; 325 int[] result = new int[m_bdata.m_triangles.Count * 3];
368 for (int i = 0; i < m_triangles.Count; i++) 326 for (int i = 0; i < m_bdata.m_triangles.Count; i++)
369 { 327 {
370 Triangle t = m_triangles[i]; 328 Triangle t = m_bdata.m_triangles[i];
371 result[3 * i + 0] = m_vertices[t.v1]; 329 result[3 * i + 0] = m_bdata.m_vertices[t.v1];
372 result[3 * i + 1] = m_vertices[t.v2]; 330 result[3 * i + 1] = m_bdata.m_vertices[t.v2];
373 result[3 * i + 2] = m_vertices[t.v3]; 331 result[3 * i + 2] = m_bdata.m_vertices[t.v3];
374 } 332 }
375 return result; 333 return result;
376 } 334 }
@@ -381,28 +339,19 @@ namespace OpenSim.Region.Physics.Meshing
381 /// <returns></returns> 339 /// <returns></returns>
382 public int[] getIndexListAsIntLocked() 340 public int[] getIndexListAsIntLocked()
383 { 341 {
384 if (m_pinnedIndex.IsAllocated) 342 return null;
385 return (int[])(m_pinnedIndex.Target);
386
387 int[] result = getIndexListAsInt();
388 m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
389 // Inform the garbage collector of this unmanaged allocation so it can schedule
390 // the next GC round more intelligently
391 GC.AddMemoryPressure(Buffer.ByteLength(result));
392
393 return result;
394 } 343 }
395 344
396 public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount) 345 public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
397 { 346 {
398 // If there isn't an unmanaged array allocated yet, do it now 347 // If there isn't an unmanaged array allocated yet, do it now
399 if (m_indicesPtr == IntPtr.Zero) 348 if (m_indicesPtr == IntPtr.Zero && m_bdata != null)
400 { 349 {
401 int[] indexList = getIndexListAsInt(); 350 indexes = getIndexListAsInt();
402 m_indexCount = indexList.Length; 351 m_indexCount = indexes.Length;
403 int byteCount = m_indexCount * sizeof(int); 352 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
404 m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount); 353 m_indicesPtr = ihandler.AddrOfPinnedObject();
405 System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount); 354 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
406 } 355 }
407 // A triangle is 3 ints (indices) 356 // A triangle is 3 ints (indices)
408 triStride = 3 * sizeof(int); 357 triStride = 3 * sizeof(int);
@@ -412,18 +361,16 @@ namespace OpenSim.Region.Physics.Meshing
412 361
413 public void releasePinned() 362 public void releasePinned()
414 { 363 {
415 if (m_pinnedVertexes.IsAllocated)
416 m_pinnedVertexes.Free();
417 if (m_pinnedIndex.IsAllocated)
418 m_pinnedIndex.Free();
419 if (m_verticesPtr != IntPtr.Zero) 364 if (m_verticesPtr != IntPtr.Zero)
420 { 365 {
421 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr); 366 vhandler.Free();
367 vertices = null;
422 m_verticesPtr = IntPtr.Zero; 368 m_verticesPtr = IntPtr.Zero;
423 } 369 }
424 if (m_indicesPtr != IntPtr.Zero) 370 if (m_indicesPtr != IntPtr.Zero)
425 { 371 {
426 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr); 372 ihandler.Free();
373 indexes = null;
427 m_indicesPtr = IntPtr.Zero; 374 m_indicesPtr = IntPtr.Zero;
428 } 375 }
429 } 376 }
@@ -433,29 +380,42 @@ namespace OpenSim.Region.Physics.Meshing
433 /// </summary> 380 /// </summary>
434 public void releaseSourceMeshData() 381 public void releaseSourceMeshData()
435 { 382 {
436 m_triangles = null; 383 if (m_bdata != null)
437 m_vertices = null; 384 {
385 m_bdata.m_triangles = null;
386 m_bdata.m_vertices = null;
387 }
388 }
389
390 public void releaseBuildingMeshData()
391 {
392 if (m_bdata != null)
393 {
394 m_bdata.m_triangles = null;
395 m_bdata.m_vertices = null;
396 m_bdata = null;
397 }
438 } 398 }
439 399
440 public void Append(IMesh newMesh) 400 public void Append(IMesh newMesh)
441 { 401 {
442 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 402 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
443 throw new NotSupportedException("Attempt to Append to a pinned Mesh"); 403 throw new NotSupportedException("Attempt to Append to a pinned Mesh");
444 404
445 if (!(newMesh is Mesh)) 405 if (!(newMesh is Mesh))
446 return; 406 return;
447 407
448 foreach (Triangle t in ((Mesh)newMesh).m_triangles) 408 foreach (Triangle t in ((Mesh)newMesh).m_bdata.m_triangles)
449 Add(t); 409 Add(t);
450 } 410 }
451 411
452 // Do a linear transformation of mesh. 412 // Do a linear transformation of mesh.
453 public void TransformLinear(float[,] matrix, float[] offset) 413 public void TransformLinear(float[,] matrix, float[] offset)
454 { 414 {
455 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) 415 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
456 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh"); 416 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
457 417
458 foreach (Vertex v in m_vertices.Keys) 418 foreach (Vertex v in m_bdata.m_vertices.Keys)
459 { 419 {
460 if (v == null) 420 if (v == null)
461 continue; 421 continue;
@@ -473,10 +433,12 @@ namespace OpenSim.Region.Physics.Meshing
473 { 433 {
474 if (path == null) 434 if (path == null)
475 return; 435 return;
436 if (m_bdata == null)
437 return;
476 String fileName = name + "_" + title + ".raw"; 438 String fileName = name + "_" + title + ".raw";
477 String completePath = System.IO.Path.Combine(path, fileName); 439 String completePath = System.IO.Path.Combine(path, fileName);
478 StreamWriter sw = new StreamWriter(completePath); 440 StreamWriter sw = new StreamWriter(completePath);
479 foreach (Triangle t in m_triangles) 441 foreach (Triangle t in m_bdata.m_triangles)
480 { 442 {
481 String s = t.ToStringRaw(); 443 String s = t.ToStringRaw();
482 sw.WriteLine(s); 444 sw.WriteLine(s);
@@ -486,7 +448,144 @@ namespace OpenSim.Region.Physics.Meshing
486 448
487 public void TrimExcess() 449 public void TrimExcess()
488 { 450 {
489 m_triangles.TrimExcess(); 451 m_bdata.m_triangles.TrimExcess();
452 }
453
454 public void pinMemory()
455 {
456 m_vertexCount = vertices.Length / 3;
457 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
458 m_verticesPtr = vhandler.AddrOfPinnedObject();
459 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
460
461 m_indexCount = indexes.Length;
462 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
463 m_indicesPtr = ihandler.AddrOfPinnedObject();
464 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
465 }
466
467 public void PrepForOde()
468 {
469 // If there isn't an unmanaged array allocated yet, do it now
470 if (m_verticesPtr == IntPtr.Zero)
471 vertices = getVertexListAsFloat();
472
473 // If there isn't an unmanaged array allocated yet, do it now
474 if (m_indicesPtr == IntPtr.Zero)
475 indexes = getIndexListAsInt();
476
477 pinMemory();
478
479 float x, y, z;
480
481 if (m_bdata.m_centroidDiv > 0)
482 {
483 m_obboffset = new Vector3(m_bdata.m_centroid.X / m_bdata.m_centroidDiv, m_bdata.m_centroid.Y / m_bdata.m_centroidDiv, m_bdata.m_centroid.Z / m_bdata.m_centroidDiv);
484 x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
485 y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
486 z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
487 }
488
489 else
490 {
491 m_obboffset = Vector3.Zero;
492 x = 0.5f;
493 y = 0.5f;
494 z = 0.5f;
495 }
496 m_obb = new Vector3(x, y, z);
497
498 releaseBuildingMeshData();
499 }
500 public bool ToStream(Stream st)
501 {
502 if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero)
503 return false;
504
505 BinaryWriter bw = new BinaryWriter(st);
506 bool ok = true;
507
508 try
509 {
510
511 bw.Write(m_vertexCount);
512 bw.Write(m_indexCount);
513
514 for (int i = 0; i < 3 * m_vertexCount; i++)
515 bw.Write(vertices[i]);
516 for (int i = 0; i < m_indexCount; i++)
517 bw.Write(indexes[i]);
518 bw.Write(m_obb.X);
519 bw.Write(m_obb.Y);
520 bw.Write(m_obb.Z);
521 bw.Write(m_obboffset.X);
522 bw.Write(m_obboffset.Y);
523 bw.Write(m_obboffset.Z);
524 }
525 catch
526 {
527 ok = false;
528 }
529
530 if (bw != null)
531 {
532 bw.Flush();
533 bw.Close();
534 }
535
536 return ok;
537 }
538
539 public static Mesh FromStream(Stream st, AMeshKey key)
540 {
541 Mesh mesh = new Mesh();
542 mesh.releaseBuildingMeshData();
543
544 BinaryReader br = new BinaryReader(st);
545
546 bool ok = true;
547 try
548 {
549 mesh.m_vertexCount = br.ReadInt32();
550 mesh.m_indexCount = br.ReadInt32();
551
552 int n = 3 * mesh.m_vertexCount;
553 mesh.vertices = new float[n];
554 for (int i = 0; i < n; i++)
555 mesh.vertices[i] = br.ReadSingle();
556
557 mesh.indexes = new int[mesh.m_indexCount];
558 for (int i = 0; i < mesh.m_indexCount; i++)
559 mesh.indexes[i] = br.ReadInt32();
560
561 mesh.m_obb.X = br.ReadSingle();
562 mesh.m_obb.Y = br.ReadSingle();
563 mesh.m_obb.Z = br.ReadSingle();
564
565 mesh.m_obboffset.X = br.ReadSingle();
566 mesh.m_obboffset.Y = br.ReadSingle();
567 mesh.m_obboffset.Z = br.ReadSingle();
568 }
569 catch
570 {
571 ok = false;
572 }
573
574 br.Close();
575
576 if (ok)
577 {
578 mesh.pinMemory();
579
580 mesh.Key = key;
581 mesh.RefCount = 1;
582
583 return mesh;
584 }
585
586 mesh.vertices = null;
587 mesh.indexes = null;
588 return null;
490 } 589 }
491 } 590 }
492} 591}
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}
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 03048a4..6592e6c 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -718,7 +718,7 @@ namespace OpenSim.Region.Physics.OdePlugin
718 718
719 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 719 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
720 return; 720 return;
721 721/*
722// debug 722// debug
723 PhysicsActor dp2; 723 PhysicsActor dp2;
724 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass) 724 if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
@@ -742,7 +742,7 @@ namespace OpenSim.Region.Physics.OdePlugin
742 } 742 }
743 } 743 }
744// 744//
745 745*/
746 746
747 747
748 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || 748 if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||