Merge branch 'master' into vehicles
commit
8d5a40aad0
|
@ -47,6 +47,8 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
int[] getIndexListAsInt();
|
int[] getIndexListAsInt();
|
||||||
int[] getIndexListAsIntLocked();
|
int[] getIndexListAsIntLocked();
|
||||||
float[] getVertexListAsFloatLocked();
|
float[] getVertexListAsFloatLocked();
|
||||||
|
void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount);
|
||||||
|
void getVertexListAsPtrToFloatArray( out IntPtr vertexList, out int vertexStride, out int vertexCount );
|
||||||
void releaseSourceMeshData();
|
void releaseSourceMeshData();
|
||||||
void releasePinned();
|
void releasePinned();
|
||||||
void Append(IMesh newMesh);
|
void Append(IMesh newMesh);
|
||||||
|
|
|
@ -36,23 +36,27 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
{
|
{
|
||||||
public class Mesh : IMesh
|
public class Mesh : IMesh
|
||||||
{
|
{
|
||||||
private Dictionary<Vertex, int> vertices;
|
private Dictionary<Vertex, int> m_vertices;
|
||||||
private List<Triangle> triangles;
|
private List<Triangle> m_triangles;
|
||||||
GCHandle pinnedVirtexes;
|
GCHandle m_pinnedVertexes;
|
||||||
GCHandle pinnedIndex;
|
GCHandle m_pinnedIndex;
|
||||||
public float[] normals;
|
IntPtr m_verticesPtr = IntPtr.Zero;
|
||||||
|
int m_vertexCount = 0;
|
||||||
|
IntPtr m_indicesPtr = IntPtr.Zero;
|
||||||
|
int m_indexCount = 0;
|
||||||
|
public float[] m_normals;
|
||||||
|
|
||||||
public Mesh()
|
public Mesh()
|
||||||
{
|
{
|
||||||
vertices = new Dictionary<Vertex, int>();
|
m_vertices = new Dictionary<Vertex, int>();
|
||||||
triangles = new List<Triangle>();
|
m_triangles = new List<Triangle>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Mesh Clone()
|
public Mesh Clone()
|
||||||
{
|
{
|
||||||
Mesh result = new Mesh();
|
Mesh result = new Mesh();
|
||||||
|
|
||||||
foreach (Triangle t in triangles)
|
foreach (Triangle t in m_triangles)
|
||||||
{
|
{
|
||||||
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||||
}
|
}
|
||||||
|
@ -62,27 +66,27 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
public void Add(Triangle triangle)
|
public void Add(Triangle triangle)
|
||||||
{
|
{
|
||||||
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||||
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||||
// If a vertex of the triangle is not yet in the vertices list,
|
// If a vertex of the triangle is not yet in the vertices list,
|
||||||
// add it and set its index to the current index count
|
// add it and set its index to the current index count
|
||||||
if (!vertices.ContainsKey(triangle.v1))
|
if( !m_vertices.ContainsKey(triangle.v1) )
|
||||||
vertices[triangle.v1] = vertices.Count;
|
m_vertices[triangle.v1] = m_vertices.Count;
|
||||||
if (!vertices.ContainsKey(triangle.v2))
|
if (!m_vertices.ContainsKey(triangle.v2))
|
||||||
vertices[triangle.v2] = vertices.Count;
|
m_vertices[triangle.v2] = m_vertices.Count;
|
||||||
if (!vertices.ContainsKey(triangle.v3))
|
if (!m_vertices.ContainsKey(triangle.v3))
|
||||||
vertices[triangle.v3] = vertices.Count;
|
m_vertices[triangle.v3] = m_vertices.Count;
|
||||||
triangles.Add(triangle);
|
m_triangles.Add(triangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalcNormals()
|
public void CalcNormals()
|
||||||
{
|
{
|
||||||
int iTriangles = triangles.Count;
|
int iTriangles = m_triangles.Count;
|
||||||
|
|
||||||
this.normals = new float[iTriangles * 3];
|
this.m_normals = new float[iTriangles * 3];
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
foreach (Triangle t in triangles)
|
foreach (Triangle t in m_triangles)
|
||||||
{
|
{
|
||||||
float ux, uy, uz;
|
float ux, uy, uz;
|
||||||
float vx, vy, vz;
|
float vx, vy, vz;
|
||||||
|
@ -129,9 +133,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
//ny /= l;
|
//ny /= l;
|
||||||
//nz /= l;
|
//nz /= l;
|
||||||
|
|
||||||
normals[i] = nx * lReciprocal;
|
m_normals[i] = nx * lReciprocal;
|
||||||
normals[i + 1] = ny * lReciprocal;
|
m_normals[i + 1] = ny * lReciprocal;
|
||||||
normals[i + 2] = nz * lReciprocal;
|
m_normals[i + 2] = nz * lReciprocal;
|
||||||
|
|
||||||
i += 3;
|
i += 3;
|
||||||
}
|
}
|
||||||
|
@ -140,45 +144,70 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
public List<PhysicsVector> getVertexList()
|
public List<PhysicsVector> getVertexList()
|
||||||
{
|
{
|
||||||
List<PhysicsVector> result = new List<PhysicsVector>();
|
List<PhysicsVector> result = new List<PhysicsVector>();
|
||||||
foreach (Vertex v in vertices.Keys)
|
foreach (Vertex v in m_vertices.Keys)
|
||||||
{
|
{
|
||||||
result.Add(v);
|
result.Add(v);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getVertexListAsFloatLocked()
|
private float[] getVertexListAsFloat()
|
||||||
{
|
{
|
||||||
if (pinnedVirtexes.IsAllocated)
|
if(m_vertices == null)
|
||||||
return (float[])(pinnedVirtexes.Target);
|
throw new NotSupportedException();
|
||||||
float[] result;
|
float[] result = new float[m_vertices.Count * 3];
|
||||||
|
foreach (KeyValuePair<Vertex, int> kvp in m_vertices)
|
||||||
//m_log.WarnFormat("vertices.Count = {0}", vertices.Count);
|
|
||||||
result = new float[vertices.Count * 3];
|
|
||||||
foreach (KeyValuePair<Vertex, int> kvp in vertices)
|
|
||||||
{
|
{
|
||||||
Vertex v = kvp.Key;
|
Vertex v = kvp.Key;
|
||||||
int i = kvp.Value;
|
int i = kvp.Value;
|
||||||
//m_log.WarnFormat("kvp.Value = {0}", i);
|
|
||||||
result[3 * i + 0] = v.X;
|
result[3 * i + 0] = v.X;
|
||||||
result[3 * i + 1] = v.Y;
|
result[3 * i + 1] = v.Y;
|
||||||
result[3 * i + 2] = v.Z;
|
result[3 * i + 2] = v.Z;
|
||||||
}
|
}
|
||||||
pinnedVirtexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float[] getVertexListAsFloatLocked()
|
||||||
|
{
|
||||||
|
if( m_pinnedVertexes.IsAllocated )
|
||||||
|
return (float[])(m_pinnedVertexes.Target);
|
||||||
|
|
||||||
|
float[] result = getVertexListAsFloat();
|
||||||
|
m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount)
|
||||||
|
{
|
||||||
|
// A vertex is 3 floats
|
||||||
|
vertexStride = 3 * sizeof(float);
|
||||||
|
|
||||||
|
// If there isn't an unmanaged array allocated yet, do it now
|
||||||
|
if (m_verticesPtr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
float[] vertexList = getVertexListAsFloat();
|
||||||
|
// Each vertex is 3 elements (floats)
|
||||||
|
m_vertexCount = vertexList.Length / 3;
|
||||||
|
int byteCount = m_vertexCount * vertexStride;
|
||||||
|
m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3);
|
||||||
|
}
|
||||||
|
vertices = m_verticesPtr;
|
||||||
|
vertexCount = m_vertexCount;
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getIndexListAsInt()
|
public int[] getIndexListAsInt()
|
||||||
{
|
{
|
||||||
int[] result;
|
if (m_triangles == null)
|
||||||
|
throw new NotSupportedException();
|
||||||
result = new int[triangles.Count * 3];
|
int[] result = new int[m_triangles.Count * 3];
|
||||||
for (int i = 0; i < triangles.Count; i++)
|
for (int i = 0; i < m_triangles.Count; i++)
|
||||||
{
|
{
|
||||||
Triangle t = triangles[i];
|
Triangle t = m_triangles[i];
|
||||||
result[3 * i + 0] = vertices[t.v1];
|
result[3 * i + 0] = m_vertices[t.v1];
|
||||||
result[3 * i + 1] = vertices[t.v2];
|
result[3 * i + 1] = m_vertices[t.v2];
|
||||||
result[3 * i + 2] = vertices[t.v3];
|
result[3 * i + 2] = m_vertices[t.v3];
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -189,19 +218,48 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public int[] getIndexListAsIntLocked()
|
public int[] getIndexListAsIntLocked()
|
||||||
{
|
{
|
||||||
if (pinnedIndex.IsAllocated)
|
if (m_pinnedIndex.IsAllocated)
|
||||||
return (int[])(pinnedIndex.Target);
|
return (int[])(m_pinnedIndex.Target);
|
||||||
|
|
||||||
int[] result = getIndexListAsInt();
|
int[] result = getIndexListAsInt();
|
||||||
pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
|
m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getIndexListAsPtrToIntArray(out IntPtr indices, out int triStride, out int indexCount)
|
||||||
|
{
|
||||||
|
// If there isn't an unmanaged array allocated yet, do it now
|
||||||
|
if (m_indicesPtr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
int[] indexList = getIndexListAsInt();
|
||||||
|
m_indexCount = indexList.Length;
|
||||||
|
int byteCount = m_indexCount * sizeof(int);
|
||||||
|
m_indicesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
|
||||||
|
System.Runtime.InteropServices.Marshal.Copy(indexList, 0, m_indicesPtr, m_indexCount);
|
||||||
|
}
|
||||||
|
// A triangle is 3 ints (indices)
|
||||||
|
triStride = 3 * sizeof(int);
|
||||||
|
indices = m_indicesPtr;
|
||||||
|
indexCount = m_indexCount;
|
||||||
|
}
|
||||||
|
|
||||||
public void releasePinned()
|
public void releasePinned()
|
||||||
{
|
{
|
||||||
pinnedVirtexes.Free();
|
if (m_pinnedVertexes.IsAllocated)
|
||||||
pinnedIndex.Free();
|
m_pinnedVertexes.Free();
|
||||||
|
if (m_pinnedIndex.IsAllocated)
|
||||||
|
m_pinnedIndex.Free();
|
||||||
|
if (m_verticesPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr);
|
||||||
|
m_verticesPtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
if (m_indicesPtr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr);
|
||||||
|
m_indicesPtr = IntPtr.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -209,29 +267,29 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void releaseSourceMeshData()
|
public void releaseSourceMeshData()
|
||||||
{
|
{
|
||||||
triangles = null;
|
m_triangles = null;
|
||||||
vertices = null;
|
m_vertices = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Append(IMesh newMesh)
|
public void Append(IMesh newMesh)
|
||||||
{
|
{
|
||||||
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||||
throw new NotSupportedException("Attempt to Append to a pinned Mesh");
|
throw new NotSupportedException("Attempt to Append to a pinned Mesh");
|
||||||
|
|
||||||
if (!(newMesh is Mesh))
|
if (!(newMesh is Mesh))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (Triangle t in ((Mesh)newMesh).triangles)
|
foreach (Triangle t in ((Mesh)newMesh).m_triangles)
|
||||||
Add(t);
|
Add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do a linear transformation of mesh.
|
// Do a linear transformation of mesh.
|
||||||
public void TransformLinear(float[,] matrix, float[] offset)
|
public void TransformLinear(float[,] matrix, float[] offset)
|
||||||
{
|
{
|
||||||
if (pinnedIndex.IsAllocated || pinnedVirtexes.IsAllocated)
|
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||||
throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
|
throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
|
||||||
|
|
||||||
foreach (Vertex v in vertices.Keys)
|
foreach (Vertex v in m_vertices.Keys)
|
||||||
{
|
{
|
||||||
if (v == null)
|
if (v == null)
|
||||||
continue;
|
continue;
|
||||||
|
@ -252,7 +310,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
String fileName = name + "_" + title + ".raw";
|
String fileName = name + "_" + title + ".raw";
|
||||||
String completePath = Path.Combine(path, fileName);
|
String completePath = Path.Combine(path, fileName);
|
||||||
StreamWriter sw = new StreamWriter(completePath);
|
StreamWriter sw = new StreamWriter(completePath);
|
||||||
foreach (Triangle t in triangles)
|
foreach (Triangle t in m_triangles)
|
||||||
{
|
{
|
||||||
String s = t.ToStringRaw();
|
String s = t.ToStringRaw();
|
||||||
sw.WriteLine(s);
|
sw.WriteLine(s);
|
||||||
|
@ -262,7 +320,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
public void TrimExcess()
|
public void TrimExcess()
|
||||||
{
|
{
|
||||||
triangles.TrimExcess();
|
m_triangles.TrimExcess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -498,12 +498,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
// If this mesh has been created already, return it instead of creating another copy
|
// If this mesh has been created already, return it instead of creating another copy
|
||||||
// For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
|
// For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
|
||||||
|
|
||||||
if (! primShape.SculptEntry)
|
key = GetMeshKey(primShape, size, lod);
|
||||||
{
|
if (m_uniqueMeshes.TryGetValue(key, out mesh))
|
||||||
key = GetMeshKey(primShape, size, lod);
|
return mesh;
|
||||||
if (m_uniqueMeshes.TryGetValue(key, out mesh))
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size.X < 0.01f) size.X = 0.01f;
|
if (size.X < 0.01f) size.X = 0.01f;
|
||||||
if (size.Y < 0.01f) size.Y = 0.01f;
|
if (size.Y < 0.01f) size.Y = 0.01f;
|
||||||
|
@ -525,10 +522,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
// trim the vertex and triangle lists to free up memory
|
// trim the vertex and triangle lists to free up memory
|
||||||
mesh.TrimExcess();
|
mesh.TrimExcess();
|
||||||
}
|
|
||||||
|
|
||||||
if (!primShape.SculptEntry)
|
|
||||||
m_uniqueMeshes.Add(key, mesh);
|
m_uniqueMeshes.Add(key, mesh);
|
||||||
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,18 +824,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
|
IntPtr vertices, indices;
|
||||||
int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
|
int vertexCount, indexCount;
|
||||||
|
int vertexStride, triStride;
|
||||||
|
mesh.getVertexListAsPtrToFloatArray( out vertices, out vertexStride, out vertexCount ); // Note, that vertices are fixed in unmanaged heap
|
||||||
|
mesh.getIndexListAsPtrToIntArray( out indices, out triStride, out indexCount ); // Also fixed, needs release after usage
|
||||||
|
|
||||||
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
|
||||||
|
|
||||||
int VertexCount = vertexList.GetLength(0)/3;
|
|
||||||
int IndexCount = indexList.GetLength(0);
|
|
||||||
|
|
||||||
_triMeshData = d.GeomTriMeshDataCreate();
|
_triMeshData = d.GeomTriMeshDataCreate();
|
||||||
|
|
||||||
d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
|
d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
|
||||||
3*sizeof (int));
|
|
||||||
d.GeomTriMeshDataPreprocess(_triMeshData);
|
d.GeomTriMeshDataPreprocess(_triMeshData);
|
||||||
|
|
||||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||||
|
|
Loading…
Reference in New Issue