29 using System.Collections.Generic;
31 using System.Runtime.InteropServices;
32 using OpenSim.Region.PhysicsModules.SharedBase;
36 namespace OpenSim.Region.PhysicsModule.Meshing
40 private Dictionary<Vertex, int> m_vertices;
41 private List<Triangle> m_triangles;
42 GCHandle m_pinnedVertexes;
43 GCHandle m_pinnedIndex;
44 IntPtr m_verticesPtr = IntPtr.Zero;
45 int m_vertexCount = 0;
46 IntPtr m_indicesPtr = IntPtr.Zero;
52 private class vertexcomp : IEqualityComparer<Vertex>
56 if (v1.
X == v2.
X && v1.
Y == v2.
Y && v1.
Z == v2.
Z)
61 public int GetHashCode(
Vertex v)
63 int a = v.X.GetHashCode();
64 int b = v.Y.GetHashCode();
65 int c = v.Z.GetHashCode();
66 return (a << 16) ^ (b << 8) ^ c;
73 vertexcomp vcomp =
new vertexcomp();
75 m_vertices =
new Dictionary<Vertex, int>(vcomp);
76 m_triangles =
new List<Triangle>();
77 _centroid = Vector3.Zero;
89 result._centroid = _centroid;
90 result._centroidDiv = _centroidDiv;
96 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
97 throw new NotSupportedException(
"Attempt to Add to a pinned Mesh");
102 if ((triangle.
v1.
X == triangle.
v2.
X && triangle.
v1.
Y == triangle.
v2.
Y && triangle.
v1.
Z == triangle.
v2.
Z)
103 || (triangle.
v1.
X == triangle.
v3.
X && triangle.
v1.
Y == triangle.
v3.
Y && triangle.
v1.
Z == triangle.
v3.
Z)
104 || (triangle.
v2.
X == triangle.
v3.
X && triangle.
v2.
Y == triangle.
v3.
Y && triangle.
v2.
Z == triangle.
v3.
Z)
110 if (m_vertices.Count == 0)
113 _centroid = Vector3.Zero;
116 if (!m_vertices.ContainsKey(triangle.
v1))
118 m_vertices[triangle.v1] = m_vertices.Count;
119 _centroid.X += triangle.v1.X;
120 _centroid.Y += triangle.v1.Y;
121 _centroid.Z += triangle.v1.Z;
124 if (!m_vertices.ContainsKey(triangle.
v2))
126 m_vertices[triangle.v2] = m_vertices.Count;
127 _centroid.X += triangle.v2.X;
128 _centroid.Y += triangle.v2.Y;
129 _centroid.Z += triangle.v2.Z;
132 if (!m_vertices.ContainsKey(triangle.
v3))
134 m_vertices[triangle.v3] = m_vertices.Count;
135 _centroid.X += triangle.v3.X;
136 _centroid.Y += triangle.v3.Y;
137 _centroid.Z += triangle.v3.Z;
140 m_triangles.Add(triangle);
145 if (_centroidDiv > 0)
146 return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
154 return new Vector3(0.5f, 0.5f, 0.5f);
159 int iTriangles = m_triangles.Count;
161 this.m_normals =
new float[iTriangles * 3];
198 nx = e1y * e2z - e1z * e2y;
199 ny = e1z * e2x - e1x * e2z;
200 nz = e1x * e2y - e1y * e2x;
203 float l = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz);
204 float lReciprocal = 1.0f / l;
211 m_normals[i] = nx * lReciprocal;
212 m_normals[i + 1] = ny * lReciprocal;
213 m_normals[i + 2] = nz * lReciprocal;
221 List<Vector3> result =
new List<Vector3>();
222 foreach (
Vertex v
in m_vertices.Keys)
224 result.Add(
new Vector3(v.
X, v.
Y, v.
Z));
231 if (m_vertices == null)
232 throw new NotSupportedException();
233 float[] result =
new float[m_vertices.Count * 3];
234 foreach (KeyValuePair<Vertex, int> kvp
in m_vertices)
238 result[3 * i + 0] = v.X;
239 result[3 * i + 1] = v.Y;
240 result[3 * i + 2] = v.Z;
247 if (m_pinnedVertexes.IsAllocated)
248 return (
float[])(m_pinnedVertexes.Target);
250 float[] result = getVertexListAsFloat();
251 m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned);
254 GC.AddMemoryPressure(Buffer.ByteLength(result));
263 vertexStride = 3 *
sizeof(float);
266 if (m_verticesPtr == IntPtr.Zero)
268 float[] vertexList = getVertexListAsFloat();
270 m_vertexCount = vertexList.Length / 3;
271 int byteCount = m_vertexCount * vertexStride;
272 m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
273 System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3);
275 vertices = m_verticesPtr;
276 vertexCount = m_vertexCount;
281 if (m_triangles == null)
282 throw new NotSupportedException();
283 int[] result =
new int[m_triangles.Count * 3];
284 for (
int i = 0; i < m_triangles.Count; i++)
287 result[3 * i + 0] = m_vertices[t.v1];
288 result[3 * i + 1] = m_vertices[t.v2];
289 result[3 * i + 2] = m_vertices[t.v3];
300 if (m_pinnedIndex.IsAllocated)
301 return (
int[])(m_pinnedIndex.Target);
303 int[] result = getIndexListAsInt();
304 m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
307 GC.AddMemoryPressure(Buffer.ByteLength(result));
315 if (m_indicesPtr == IntPtr.Zero)
317 int[] indexList = getIndexListAsInt();
318 m_indexCount = indexList.Length;
319 int byteCount = m_indexCount *
sizeof(int);
320 m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
321 System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount);
324 triStride = 3 *
sizeof(int);
325 indices = m_indicesPtr;
326 indexCount = m_indexCount;
331 if (m_pinnedVertexes.IsAllocated)
332 m_pinnedVertexes.Free();
333 if (m_pinnedIndex.IsAllocated)
334 m_pinnedIndex.Free();
335 if (m_verticesPtr != IntPtr.Zero)
337 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr);
338 m_verticesPtr = IntPtr.Zero;
340 if (m_indicesPtr != IntPtr.Zero)
342 System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr);
343 m_indicesPtr = IntPtr.Zero;
358 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
359 throw new NotSupportedException(
"Attempt to Append to a pinned Mesh");
361 if (!(newMesh is
Mesh))
371 if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
372 throw new NotSupportedException(
"Attempt to TransformLinear a pinned Mesh");
374 foreach (
Vertex v
in m_vertices.Keys)
379 x = v.X*matrix[0, 0] + v.Y*matrix[1, 0] + v.Z*matrix[2, 0];
380 y = v.X*matrix[0, 1] + v.Y*matrix[1, 1] + v.Z*matrix[2, 1];
381 z = v.X*matrix[0, 2] + v.Y*matrix[1, 2] + v.Z*matrix[2, 2];
388 public void DumpRaw(String path, String name, String title)
392 String fileName = name +
"_" + title +
".raw";
393 String completePath = System.IO.Path.Combine(path, fileName);
394 StreamWriter sw =
new StreamWriter(completePath);
397 String s = t.ToStringRaw();
405 m_triangles.TrimExcess();
int[] getIndexListAsInt()
void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
void TransformLinear(float[,] matrix, float[] offset)
List< Vector3 > getVertexList()
void Add(Triangle triangle)
float[] getVertexListAsFloat()
void Append(IMesh newMesh)
void releaseSourceMeshData()
frees up the source mesh data to minimize memory - call this method after calling get*Locked() functi...
int[] getIndexListAsIntLocked()
creates a list of index values that defines triangle faces. THIS METHOD FREES ALL NON-PINNED MESH DAT...
void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount)
void DumpRaw(String path, String name, String title)
float[] getVertexListAsFloatLocked()
Interactive OpenSim region server