29 using System.Collections.Generic;
31 using System.Runtime.InteropServices;
32 using OpenSim.Region.PhysicsModules.SharedBase;
35 using System.Runtime.Serialization;
36 using System.Runtime.Serialization.Formatters.Binary;
38 namespace OpenSim.Region.PhysicsModule.ubODEMeshing
68 IntPtr m_verticesPtr = IntPtr.Zero;
70 IntPtr m_indicesPtr = IntPtr.Zero;
72 int m_vertexCount = 0;
76 public int RefCount {
get; set; }
79 private class vertexcomp : IEqualityComparer<Vertex>
83 if (v1.
X == v2.
X && v1.
Y == v2.
Y && v1.
Z == v2.
Z)
88 public int GetHashCode(
Vertex v)
90 int a = v.X.GetHashCode();
91 int b = v.Y.GetHashCode();
92 int c = v.Z.GetHashCode();
93 return (a << 16) ^ (b << 8) ^ c;
99 vertexcomp vcomp =
new vertexcomp();
102 m_bdata.m_vertices =
new Dictionary<Vertex, int>(vcomp);
103 m_bdata.m_triangles =
new List<Triangle>();
104 m_bdata.m_centroid = Vector3.Zero;
105 m_bdata.m_centroidDiv = 0;
106 m_bdata.m_obbXmin = float.MaxValue;
107 m_bdata.m_obbXmax = float.MinValue;
108 m_bdata.m_obbYmin = float.MaxValue;
109 m_bdata.m_obbYmax = 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;
119 if (m_verticesPtr == null || m_indicesPtr == null)
132 result.m_obb.X = tmp;
137 result.m_obb.Y = tmp;
142 result.m_obb.Z = tmp;
144 result.m_obboffset.X = m_obboffset.X * x;
145 result.m_obboffset.Y = m_obboffset.Y * y;
146 result.m_obboffset.Z = m_obboffset.Z * z;
148 result.vertices =
new float[vertices.Length];
150 for (
int i = 0; i < m_vertexCount; i++)
152 result.vertices[j] = vertices[j] * x;
154 result.vertices[j] = vertices[j] * y;
156 result.vertices[j] = vertices[j] * z;
160 result.indexes =
new int[indexes.Length];
161 indexes.CopyTo(result.indexes,0);
175 foreach (
Triangle t
in m_bdata.m_triangles)
179 result.m_bdata.m_centroid = m_bdata.m_centroid;
180 result.m_bdata.m_centroidDiv = m_bdata.m_centroidDiv;
181 result.m_bdata.m_obbXmin = m_bdata.m_obbXmin;
182 result.m_bdata.m_obbXmax = m_bdata.m_obbXmax;
183 result.m_bdata.m_obbYmin = m_bdata.m_obbYmin;
184 result.m_bdata.m_obbYmax = m_bdata.m_obbYmax;
185 result.m_bdata.m_obbZmin = m_bdata.m_obbZmin;
186 result.m_bdata.m_obbZmax = m_bdata.m_obbZmax;
188 result.m_obb = m_obb;
189 result.m_obboffset = m_obboffset;
199 m_bdata.m_centroid.X += x;
200 m_bdata.m_centroid.Y += y;
201 m_bdata.m_centroid.Z += z;
202 m_bdata.m_centroidDiv++;
204 if (x > m_bdata.m_obbXmax)
205 m_bdata.m_obbXmax = x;
206 if (x < m_bdata.m_obbXmin)
207 m_bdata.m_obbXmin = x;
209 if (y > m_bdata.m_obbYmax)
210 m_bdata.m_obbYmax = y;
211 if (y < m_bdata.m_obbYmin)
212 m_bdata.m_obbYmin = y;
214 if (z > m_bdata.m_obbZmax)
215 m_bdata.m_obbZmax = z;
216 if (z < m_bdata.m_obbZmin)
217 m_bdata.m_obbZmin = z;
223 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
224 throw new NotSupportedException(
"Attempt to Add to a pinned Mesh");
227 triangle.v1.X = (float)Math.Round(triangle.
v1.
X, 6);
228 triangle.v1.Y = (float)Math.Round(triangle.
v1.
Y, 6);
229 triangle.v1.Z = (float)Math.Round(triangle.
v1.
Z, 6);
230 triangle.v2.X = (float)Math.Round(triangle.
v2.
X, 6);
231 triangle.v2.Y = (float)Math.Round(triangle.
v2.
Y, 6);
232 triangle.v2.Z = (float)Math.Round(triangle.
v2.
Z, 6);
233 triangle.v3.X = (float)Math.Round(triangle.
v3.
X, 6);
234 triangle.v3.Y = (float)Math.Round(triangle.
v3.
Y, 6);
235 triangle.v3.Z = (float)Math.Round(triangle.
v3.
Z, 6);
237 if ((triangle.
v1.
X == triangle.
v2.
X && triangle.
v1.
Y == triangle.
v2.
Y && triangle.
v1.
Z ==
239 || (triangle.
v1.
X == triangle.
v3.
X && triangle.
v1.
Y == triangle.
v3.
Y && triangle.
v1.
Z ==
241 || (triangle.
v2.
X == triangle.
v3.
X && triangle.
v2.
Y == triangle.
v3.
Y && triangle.
v2.
Z ==
248 if (m_bdata.m_vertices.Count == 0)
250 m_bdata.m_centroidDiv = 0;
251 m_bdata.m_centroid = Vector3.Zero;
254 if (!m_bdata.m_vertices.ContainsKey(triangle.
v1))
256 m_bdata.m_vertices[triangle.v1] = m_bdata.m_vertices.Count;
257 addVertexLStats(triangle.
v1);
259 if (!m_bdata.m_vertices.ContainsKey(triangle.
v2))
261 m_bdata.m_vertices[triangle.v2] = m_bdata.m_vertices.Count;
262 addVertexLStats(triangle.
v2);
264 if (!m_bdata.m_vertices.ContainsKey(triangle.
v3))
266 m_bdata.m_vertices[triangle.v3] = m_bdata.m_vertices.Count;
267 addVertexLStats(triangle.
v3);
269 m_bdata.m_triangles.Add(triangle);
301 return m_bdata.m_vertices.Count;
306 return m_bdata.m_triangles.Count;
311 List<Vector3> result =
new List<Vector3>();
312 foreach (
Vertex v
in m_bdata.m_vertices.Keys)
314 result.Add(
new Vector3(v.
X, v.
Y, v.
Z));
321 if (m_bdata.m_vertices == null)
322 throw new NotSupportedException();
323 float[] result =
new float[m_bdata.m_vertices.Count * 3];
324 foreach (KeyValuePair<Vertex, int> kvp
in m_bdata.m_vertices)
328 result[3 * i + 0] = v.X;
329 result[3 * i + 1] = v.Y;
330 result[3 * i + 2] = v.Z;
343 vertexStride = 3 *
sizeof(float);
346 if (m_verticesPtr == IntPtr.Zero && m_bdata != null)
348 vertices = getVertexListAsFloat();
350 m_vertexCount = vertices.Length / 3;
351 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
352 m_verticesPtr = vhandler.AddrOfPinnedObject();
353 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
355 _vertices = m_verticesPtr;
356 vertexCount = m_vertexCount;
361 if (m_bdata.m_triangles == null)
362 throw new NotSupportedException();
363 int[] result =
new int[m_bdata.m_triangles.Count * 3];
364 for (
int i = 0; i < m_bdata.m_triangles.Count; i++)
366 Triangle t = m_bdata.m_triangles[i];
367 result[3 * i + 0] = m_bdata.m_vertices[t.v1];
368 result[3 * i + 1] = m_bdata.m_vertices[t.v2];
369 result[3 * i + 2] = m_bdata.m_vertices[t.v3];
386 if (m_indicesPtr == IntPtr.Zero && m_bdata != null)
388 indexes = getIndexListAsInt();
389 m_indexCount = indexes.Length;
390 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
391 m_indicesPtr = ihandler.AddrOfPinnedObject();
392 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
395 triStride = 3 *
sizeof(int);
396 indices = m_indicesPtr;
397 indexCount = m_indexCount;
402 if (m_verticesPtr != IntPtr.Zero)
405 GC.RemoveMemoryPressure(Buffer.ByteLength(vertices));
407 m_verticesPtr = IntPtr.Zero;
409 if (m_indicesPtr != IntPtr.Zero)
412 GC.RemoveMemoryPressure(Buffer.ByteLength(indexes));
414 m_indicesPtr = IntPtr.Zero;
425 m_bdata.m_triangles = null;
426 m_bdata.m_vertices = null;
434 m_bdata.m_triangles = null;
435 m_bdata.m_vertices = null;
442 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
443 throw new NotSupportedException(
"Attempt to Append to a pinned Mesh");
445 if (!(newMesh is
Mesh))
448 foreach (
Triangle t
in ((
Mesh)newMesh).m_bdata.m_triangles)
455 if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
456 throw new NotSupportedException(
"Attempt to TransformLinear a pinned Mesh");
458 foreach (
Vertex v
in m_bdata.m_vertices.Keys)
463 x = v.X*matrix[0, 0] + v.Y*matrix[1, 0] + v.Z*matrix[2, 0];
464 y = v.X*matrix[0, 1] + v.Y*matrix[1, 1] + v.Z*matrix[2, 1];
465 z = v.X*matrix[0, 2] + v.Y*matrix[1, 2] + v.Z*matrix[2, 2];
472 public void DumpRaw(String path, String name, String title)
478 String fileName = name +
"_" + title +
".raw";
479 String completePath = System.IO.Path.Combine(path, fileName);
480 StreamWriter sw =
new StreamWriter(completePath);
481 foreach (
Triangle t
in m_bdata.m_triangles)
483 String s = t.ToStringRaw();
491 m_bdata.m_triangles.TrimExcess();
496 m_vertexCount = vertices.Length / 3;
497 vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
498 m_verticesPtr = vhandler.AddrOfPinnedObject();
499 GC.AddMemoryPressure(Buffer.ByteLength(vertices));
501 m_indexCount = indexes.Length;
502 ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
503 m_indicesPtr = ihandler.AddrOfPinnedObject();
504 GC.AddMemoryPressure(Buffer.ByteLength(indexes));
510 if (m_verticesPtr == IntPtr.Zero)
511 vertices = getVertexListAsFloat();
514 if (m_indicesPtr == IntPtr.Zero)
515 indexes = getIndexListAsInt();
521 if (m_bdata.m_centroidDiv > 0)
523 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);
524 x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
527 y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
530 z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
537 m_obboffset = Vector3.Zero;
543 m_obb =
new Vector3(x, y, z);
545 releaseBuildingMeshData();
549 if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero)
552 BinaryWriter bw =
new BinaryWriter(st);
558 bw.Write(m_vertexCount);
559 bw.Write(m_indexCount);
561 for (
int i = 0; i < 3 * m_vertexCount; i++)
562 bw.Write(vertices[i]);
563 for (
int i = 0; i < m_indexCount; i++)
564 bw.Write(indexes[i]);
568 bw.Write(m_obboffset.X);
569 bw.Write(m_obboffset.Y);
570 bw.Write(m_obboffset.Z);
589 mesh.releaseBuildingMeshData();
591 BinaryReader br =
new BinaryReader(st);
596 mesh.m_vertexCount = br.ReadInt32();
597 mesh.m_indexCount = br.ReadInt32();
599 int n = 3 * mesh.m_vertexCount;
600 mesh.vertices =
new float[n];
601 for (
int i = 0; i < n; i++)
602 mesh.vertices[i] = br.ReadSingle();
604 mesh.indexes =
new int[mesh.m_indexCount];
605 for (
int i = 0; i < mesh.m_indexCount; i++)
606 mesh.indexes[i] = br.ReadInt32();
608 mesh.m_obb.X = br.ReadSingle();
609 mesh.m_obb.Y = br.ReadSingle();
610 mesh.m_obb.Z = br.ReadSingle();
612 mesh.m_obboffset.X = br.ReadSingle();
613 mesh.m_obboffset.Y = br.ReadSingle();
614 mesh.m_obboffset.Z = br.ReadSingle();
633 mesh.vertices = null;
List< Triangle > m_triangles
Mesh Scale(Vector3 scale)
void Add(Triangle triangle)
void releaseSourceMeshData()
frees up the source mesh data to minimize memory - call this method after calling get*Locked() functi...
void DumpRaw(String path, String name, String title)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
float[] getVertexListAsFloatLocked()
void releaseBuildingMeshData()
static Mesh FromStream(Stream st, AMeshKey key)
void addVertexLStats(Vertex v)
void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
Interactive OpenSim region server
int[] getIndexListAsIntLocked()
creates a list of index values that defines triangle faces. THIS METHOD FREES ALL NON-PINNED MESH DAT...
Dictionary< Vertex, int > m_vertices
void TransformLinear(float[,] matrix, float[] offset)
int[] getIndexListAsInt()
float[] getVertexListAsFloat()
void Append(IMesh newMesh)
List< Vector3 > getVertexList()
void getVertexListAsPtrToFloatArray(out IntPtr _vertices, out int vertexStride, out int vertexCount)