aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/UbitMeshing/Mesh.cs')
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs551
1 files changed, 325 insertions, 226 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}