aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2009-10-05 12:58:52 +0100
committerMelanie2009-10-05 12:58:52 +0100
commit8d5a40aad03cb0f46aa90a90e3e8d9464041faf7 (patch)
tree05e5908228936457563e031bbaa1d4a65b9c2544 /OpenSim/Region
parentFix build break (diff)
parentEliminate pinned Mesh data on managed heap by using IntPtrs to memory allocat... (diff)
downloadopensim-SC-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.zip
opensim-SC-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.gz
opensim-SC-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.bz2
opensim-SC-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.xz
Merge branch 'master' into vehicles
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs2
-rw-r--r--OpenSim/Region/Physics/Meshing/Mesh.cs166
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs12
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs13
4 files changed, 124 insertions, 69 deletions
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index e26c623..ac14292 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -47,6 +47,8 @@ namespace OpenSim.Region.Physics.Manager
47 int[] getIndexListAsInt(); 47 int[] getIndexListAsInt();
48 int[] getIndexListAsIntLocked(); 48 int[] getIndexListAsIntLocked();
49 float[] getVertexListAsFloatLocked(); 49 float[] getVertexListAsFloatLocked();
50 void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount);
51 void getVertexListAsPtrToFloatArray( out IntPtr vertexList, out int vertexStride, out int vertexCount );
50 void releaseSourceMeshData(); 52 void releaseSourceMeshData();
51 void releasePinned(); 53 void releasePinned();
52 void Append(IMesh newMesh); 54 void Append(IMesh newMesh);
diff --git a/OpenSim/Region/Physics/Meshing/Mesh.cs b/OpenSim/Region/Physics/Meshing/Mesh.cs
index aae8871..ff1f816 100644
--- a/OpenSim/Region/Physics/Meshing/Mesh.cs
+++ b/OpenSim/Region/Physics/Meshing/Mesh.cs
@@ -36,23 +36,27 @@ namespace OpenSim.Region.Physics.Meshing
36{ 36{
37 public class Mesh : IMesh 37 public class Mesh : IMesh
38 { 38 {
39 private Dictionary<Vertex, int> vertices; 39 private Dictionary<Vertex, int> m_vertices;
40 private List<Triangle> triangles; 40 private List<Triangle> m_triangles;
41 GCHandle pinnedVirtexes; 41 GCHandle m_pinnedVertexes;
42 GCHandle pinnedIndex; 42 GCHandle m_pinnedIndex;
43 public float[] normals; 43 IntPtr m_verticesPtr = IntPtr.Zero;
44 int m_vertexCount = 0;
45 IntPtr m_indicesPtr = IntPtr.Zero;
46 int m_indexCount = 0;
47 public float[] m_normals;
44 48
45 public Mesh() 49 public Mesh()
46 { 50 {
47 vertices = new Dictionary<Vertex, int>(); 51 m_vertices = new Dictionary<Vertex, int>();
48 triangles = new List<Triangle>(); 52 m_triangles = new List<Triangle>();
49 } 53 }
50 54
51 public Mesh Clone() 55 public Mesh Clone()
52 { 56 {
53 Mesh result = new Mesh(); 57 Mesh result = new Mesh();
54 58
55 foreach (Triangle t in triangles) 59 foreach (Triangle t in m_triangles)
56 { 60 {
57 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); 61 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
58 } 62 }
@@ -62,27 +66,27 @@ namespace OpenSim.Region.Physics.Meshing
62 66
63 public void Add(Triangle triangle) 67 public void Add(Triangle triangle)
64 { 68 {
65 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) 69 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
66 throw new NotSupportedException("Attempt to Add to a pinned Mesh"); 70 throw new NotSupportedException("Attempt to Add to a pinned Mesh");
67 // If a vertex of the triangle is not yet in the vertices list, 71 // If a vertex of the triangle is not yet in the vertices list,
68 // add it and set its index to the current index count 72 // add it and set its index to the current index count
69 if (!vertices.ContainsKey(triangle.v1)) 73 if( !m_vertices.ContainsKey(triangle.v1) )
70 vertices[triangle.v1] = vertices.Count; 74 m_vertices[triangle.v1] = m_vertices.Count;
71 if (!vertices.ContainsKey(triangle.v2)) 75 if (!m_vertices.ContainsKey(triangle.v2))
72 vertices[triangle.v2] = vertices.Count; 76 m_vertices[triangle.v2] = m_vertices.Count;
73 if (!vertices.ContainsKey(triangle.v3)) 77 if (!m_vertices.ContainsKey(triangle.v3))
74 vertices[triangle.v3] = vertices.Count; 78 m_vertices[triangle.v3] = m_vertices.Count;
75 triangles.Add(triangle); 79 m_triangles.Add(triangle);
76 } 80 }
77 81
78 public void CalcNormals() 82 public void CalcNormals()
79 { 83 {
80 int iTriangles = triangles.Count; 84 int iTriangles = m_triangles.Count;
81 85
82 this.normals = new float[iTriangles * 3]; 86 this.m_normals = new float[iTriangles * 3];
83 87
84 int i = 0; 88 int i = 0;
85 foreach (Triangle t in triangles) 89 foreach (Triangle t in m_triangles)
86 { 90 {
87 float ux, uy, uz; 91 float ux, uy, uz;
88 float vx, vy, vz; 92 float vx, vy, vz;
@@ -129,9 +133,9 @@ namespace OpenSim.Region.Physics.Meshing
129 //ny /= l; 133 //ny /= l;
130 //nz /= l; 134 //nz /= l;
131 135
132 normals[i] = nx * lReciprocal; 136 m_normals[i] = nx * lReciprocal;
133 normals[i + 1] = ny * lReciprocal; 137 m_normals[i + 1] = ny * lReciprocal;
134 normals[i + 2] = nz * lReciprocal; 138 m_normals[i + 2] = nz * lReciprocal;
135 139
136 i += 3; 140 i += 3;
137 } 141 }
@@ -140,45 +144,70 @@ namespace OpenSim.Region.Physics.Meshing
140 public List<PhysicsVector> getVertexList() 144 public List<PhysicsVector> getVertexList()
141 { 145 {
142 List<PhysicsVector> result = new List<PhysicsVector>(); 146 List<PhysicsVector> result = new List<PhysicsVector>();
143 foreach (Vertex v in vertices.Keys) 147 foreach (Vertex v in m_vertices.Keys)
144 { 148 {
145 result.Add(v); 149 result.Add(v);
146 } 150 }
147 return result; 151 return result;
148 } 152 }
149 153
150 public float[] getVertexListAsFloatLocked() 154 private float[] getVertexListAsFloat()
151 { 155 {
152 if (pinnedVirtexes.IsAllocated) 156 if(m_vertices == null)
153 return (float[])(pinnedVirtexes.Target); 157 throw new NotSupportedException();
154 float[] result; 158 float[] result = new float[m_vertices.Count * 3];
155 159 foreach (KeyValuePair<Vertex, int> kvp in m_vertices)
156 //m_log.WarnFormat("vertices.Count = {0}", vertices.Count);
157 result = new float[vertices.Count * 3];
158 foreach (KeyValuePair<Vertex, int> kvp in vertices)
159 { 160 {
160 Vertex v = kvp.Key; 161 Vertex v = kvp.Key;
161 int i = kvp.Value; 162 int i = kvp.Value;
162 //m_log.WarnFormat("kvp.Value = {0}", i);
163 result[3 * i + 0] = v.X; 163 result[3 * i + 0] = v.X;
164 result[3 * i + 1] = v.Y; 164 result[3 * i + 1] = v.Y;
165 result[3 * i + 2] = v.Z; 165 result[3 * i + 2] = v.Z;
166 } 166 }
167 pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
168 return result; 167 return result;
169 } 168 }
170 169
171 public int[] getIndexListAsInt() 170 public float[] getVertexListAsFloatLocked()
172 { 171 {
173 int[] result; 172 if( m_pinnedVertexes.IsAllocated )
173 return (float[])(m_pinnedVertexes.Target);
174 174
175 result = new int[triangles.Count * 3]; 175 float[] result = getVertexListAsFloat();
176 for (int i = 0; i < triangles.Count; i++) 176 m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned);
177
178 return result;
179 }
180
181 public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount)
182 {
183 // A vertex is 3 floats
184 vertexStride = 3 * sizeof(float);
185
186 // If there isn't an unmanaged array allocated yet, do it now
187 if (m_verticesPtr == IntPtr.Zero)
177 { 188 {
178 Triangle t = triangles[i]; 189 float[] vertexList = getVertexListAsFloat();
179 result[3 * i + 0] = vertices[t.v1]; 190 // Each vertex is 3 elements (floats)
180 result[3 * i + 1] = vertices[t.v2]; 191 m_vertexCount = vertexList.Length / 3;
181 result[3 * i + 2] = vertices[t.v3]; 192 int byteCount = m_vertexCount * vertexStride;
193 m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
194 System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3);
195 }
196 vertices = m_verticesPtr;
197 vertexCount = m_vertexCount;
198 }
199
200 public int[] getIndexListAsInt()
201 {
202 if (m_triangles == null)
203 throw new NotSupportedException();
204 int[] result = new int[m_triangles.Count * 3];
205 for (int i = 0; i < m_triangles.Count; i++)
206 {
207 Triangle t = m_triangles[i];
208 result[3 * i + 0] = m_vertices[t.v1];
209 result[3 * i + 1] = m_vertices[t.v2];
210 result[3 * i + 2] = m_vertices[t.v3];
182 } 211 }
183 return result; 212 return result;
184 } 213 }
@@ -189,19 +218,48 @@ namespace OpenSim.Region.Physics.Meshing
189 /// <returns></returns> 218 /// <returns></returns>
190 public int[] getIndexListAsIntLocked() 219 public int[] getIndexListAsIntLocked()
191 { 220 {
192 if (pinnedIndex.IsAllocated) 221 if (m_pinnedIndex.IsAllocated)
193 return (int[])(pinnedIndex.Target); 222 return (int[])(m_pinnedIndex.Target);
194 223
195 int[] result = getIndexListAsInt(); 224 int[] result = getIndexListAsInt();
196 pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned); 225 m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
197 226
198 return result; 227 return result;
199 } 228 }
200 229
230 public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
231 {
232 // If there isn't an unmanaged array allocated yet, do it now
233 if (m_indicesPtr == IntPtr.Zero)
234 {
235 int[] indexList = getIndexListAsInt();
236 m_indexCount = indexList.Length;
237 int byteCount = m_indexCount * sizeof(int);
238 m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
239 System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount);
240 }
241 // A triangle is 3 ints (indices)
242 triStride = 3 * sizeof(int);
243 indices = m_indicesPtr;
244 indexCount = m_indexCount;
245 }
246
201 public void releasePinned() 247 public void releasePinned()
202 { 248 {
203 pinnedVirtexes.Free(); 249 if (m_pinnedVertexes.IsAllocated)
204 pinnedIndex.Free(); 250 m_pinnedVertexes.Free();
251 if (m_pinnedIndex.IsAllocated)
252 m_pinnedIndex.Free();
253 if (m_verticesPtr != IntPtr.Zero)
254 {
255 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr);
256 m_verticesPtr = IntPtr.Zero;
257 }
258 if (m_indicesPtr != IntPtr.Zero)
259 {
260 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr);
261 m_indicesPtr = IntPtr.Zero;
262 }
205 } 263 }
206 264
207 /// <summary> 265 /// <summary>
@@ -209,29 +267,29 @@ namespace OpenSim.Region.Physics.Meshing
209 /// </summary> 267 /// </summary>
210 public void releaseSourceMeshData() 268 public void releaseSourceMeshData()
211 { 269 {
212 triangles = null; 270 m_triangles = null;
213 vertices = null; 271 m_vertices = null;
214 } 272 }
215 273
216 public void Append(IMesh newMesh) 274 public void Append(IMesh newMesh)
217 { 275 {
218 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) 276 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
219 throw new NotSupportedException("Attempt to Append to a pinned Mesh"); 277 throw new NotSupportedException("Attempt to Append to a pinned Mesh");
220 278
221 if (!(newMesh is Mesh)) 279 if (!(newMesh is Mesh))
222 return; 280 return;
223 281
224 foreach (Triangle t in ((Mesh)newMesh).triangles) 282 foreach (Triangle t in ((Mesh)newMesh).m_triangles)
225 Add(t); 283 Add(t);
226 } 284 }
227 285
228 // Do a linear transformation of mesh. 286 // Do a linear transformation of mesh.
229 public void TransformLinear(float[,] matrix, float[] offset) 287 public void TransformLinear(float[,] matrix, float[] offset)
230 { 288 {
231 if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated) 289 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
232 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh"); 290 throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
233 291
234 foreach (Vertex v in vertices.Keys) 292 foreach (Vertex v in m_vertices.Keys)
235 { 293 {
236 if (v == null) 294 if (v == null)
237 continue; 295 continue;
@@ -252,7 +310,7 @@ namespace OpenSim.Region.Physics.Meshing
252 String fileName = name + "_" + title + ".raw"; 310 String fileName = name + "_" + title + ".raw";
253 String completePath = Path.Combine(path, fileName); 311 String completePath = Path.Combine(path, fileName);
254 StreamWriter sw = new StreamWriter(completePath); 312 StreamWriter sw = new StreamWriter(completePath);
255 foreach (Triangle t in triangles) 313 foreach (Triangle t in m_triangles)
256 { 314 {
257 String s = t.ToStringRaw(); 315 String s = t.ToStringRaw();
258 sw.WriteLine(s); 316 sw.WriteLine(s);
@@ -262,7 +320,7 @@ namespace OpenSim.Region.Physics.Meshing
262 320
263 public void TrimExcess() 321 public void TrimExcess()
264 { 322 {
265 triangles.TrimExcess(); 323 m_triangles.TrimExcess();
266 } 324 }
267 } 325 }
268} 326}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 0e29ccc..1ea08e2 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -498,12 +498,9 @@ namespace OpenSim.Region.Physics.Meshing
498 // If this mesh has been created already, return it instead of creating another copy 498 // If this mesh has been created already, return it instead of creating another copy
499 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory 499 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
500 500
501 if (! primShape.SculptEntry) 501 key = GetMeshKey(primShape, size, lod);
502 { 502 if (m_uniqueMeshes.TryGetValue(key, out mesh))
503 key = GetMeshKey(primShape, size, lod); 503 return mesh;
504 if (m_uniqueMeshes.TryGetValue(key, out mesh))
505 return mesh;
506 }
507 504
508 if (size.X < 0.01f) size.X = 0.01f; 505 if (size.X < 0.01f) size.X = 0.01f;
509 if (size.Y < 0.01f) size.Y = 0.01f; 506 if (size.Y < 0.01f) size.Y = 0.01f;
@@ -525,10 +522,9 @@ namespace OpenSim.Region.Physics.Meshing
525 522
526 // trim the vertex and triangle lists to free up memory 523 // trim the vertex and triangle lists to free up memory
527 mesh.TrimExcess(); 524 mesh.TrimExcess();
528 }
529 525
530 if (!primShape.SculptEntry)
531 m_uniqueMeshes.Add(key, mesh); 526 m_uniqueMeshes.Add(key, mesh);
527 }
532 528
533 return mesh; 529 return mesh;
534 } 530 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 86ed3bd..08aa32b 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -824,18 +824,17 @@ namespace OpenSim.Region.Physics.OdePlugin
824 } 824 }
825 } 825 }
826 826
827 float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory 827 IntPtr vertices, indices;
828 int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage 828 int vertexCount, indexCount;
829 int vertexStride, triStride;
830 mesh.getVertexListAsPtrToFloatArray( out vertices, out vertexStride, out vertexCount ); // Note, that vertices are fixed in unmanaged heap
831 mesh.getIndexListAsPtrToIntArray( out indices, out triStride, out indexCount ); // Also fixed, needs release after usage
829 832
830 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 833 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
831 834
832 int VertexCount = vertexList.GetLength(0)/3;
833 int IndexCount = indexList.GetLength(0);
834
835 _triMeshData = d.GeomTriMeshDataCreate(); 835 _triMeshData = d.GeomTriMeshDataCreate();
836 836
837 d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount, 837 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
838 3*sizeof (int));
839 d.GeomTriMeshDataPreprocess(_triMeshData); 838 d.GeomTriMeshDataPreprocess(_triMeshData);
840 839
841 _parent_scene.waitForSpaceUnlock(m_targetSpace); 840 _parent_scene.waitForSpaceUnlock(m_targetSpace);