diff options
author | Melanie | 2009-10-05 12:58:52 +0100 |
---|---|---|
committer | Melanie | 2009-10-05 12:58:52 +0100 |
commit | 8d5a40aad03cb0f46aa90a90e3e8d9464041faf7 (patch) | |
tree | 05e5908228936457563e031bbaa1d4a65b9c2544 /OpenSim | |
parent | Fix build break (diff) | |
parent | Eliminate pinned Mesh data on managed heap by using IntPtrs to memory allocat... (diff) | |
download | opensim-SC_OLD-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.zip opensim-SC_OLD-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.gz opensim-SC_OLD-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.bz2 opensim-SC_OLD-8d5a40aad03cb0f46aa90a90e3e8d9464041faf7.tar.xz |
Merge branch 'master' into vehicles
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Physics/Manager/IMesher.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Mesh.cs | 166 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 13 |
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); |