Merge branch 'ubitwork' of ssh://3dhosting.de/var/git/careminster into ubitwork
commit
77b170f1f6
|
@ -32,30 +32,49 @@ using System.Runtime.InteropServices;
|
|||
using OpenSim.Region.Physics.Manager;
|
||||
using PrimMesher;
|
||||
using OpenMetaverse;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace OpenSim.Region.Physics.Meshing
|
||||
{
|
||||
public class MeshBuildingData
|
||||
{
|
||||
public Dictionary<Vertex, int> m_vertices;
|
||||
public List<Triangle> m_triangles;
|
||||
public float m_obbXmin;
|
||||
public float m_obbXmax;
|
||||
public float m_obbYmin;
|
||||
public float m_obbYmax;
|
||||
public float m_obbZmin;
|
||||
public float m_obbZmax;
|
||||
public Vector3 m_centroid;
|
||||
public int m_centroidDiv;
|
||||
}
|
||||
|
||||
[Serializable()]
|
||||
public class Mesh : IMesh
|
||||
{
|
||||
|
||||
private Dictionary<Vertex, int> m_vertices;
|
||||
private List<Triangle> m_triangles;
|
||||
GCHandle m_pinnedVertexes;
|
||||
GCHandle m_pinnedIndex;
|
||||
float[] vertices;
|
||||
int[] indexes;
|
||||
Vector3 m_obb;
|
||||
Vector3 m_obboffset;
|
||||
[NonSerialized()]
|
||||
MeshBuildingData m_bdata;
|
||||
[NonSerialized()]
|
||||
GCHandle vhandler;
|
||||
[NonSerialized()]
|
||||
GCHandle ihandler;
|
||||
[NonSerialized()]
|
||||
IntPtr m_verticesPtr = IntPtr.Zero;
|
||||
int m_vertexCount = 0;
|
||||
[NonSerialized()]
|
||||
IntPtr m_indicesPtr = IntPtr.Zero;
|
||||
[NonSerialized()]
|
||||
int m_vertexCount = 0;
|
||||
[NonSerialized()]
|
||||
int m_indexCount = 0;
|
||||
public float[] m_normals;
|
||||
Vector3 m_centroid;
|
||||
float m_obbXmin;
|
||||
float m_obbXmax;
|
||||
float m_obbYmin;
|
||||
float m_obbYmax;
|
||||
float m_obbZmin;
|
||||
float m_obbZmax;
|
||||
|
||||
int m_centroidDiv;
|
||||
public int RefCount { get; set; }
|
||||
public AMeshKey Key { get; set; }
|
||||
|
||||
private class vertexcomp : IEqualityComparer<Vertex>
|
||||
{
|
||||
|
@ -79,42 +98,82 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
vertexcomp vcomp = new vertexcomp();
|
||||
|
||||
m_vertices = new Dictionary<Vertex, int>(vcomp);
|
||||
m_triangles = new List<Triangle>();
|
||||
m_centroid = Vector3.Zero;
|
||||
m_centroidDiv = 0;
|
||||
m_obbXmin = float.MaxValue;
|
||||
m_obbXmax = float.MinValue;
|
||||
m_obbYmin = float.MaxValue;
|
||||
m_obbYmax = float.MinValue;
|
||||
m_obbZmin = float.MaxValue;
|
||||
m_obbZmax = float.MinValue;
|
||||
m_bdata = new MeshBuildingData();
|
||||
m_bdata.m_vertices = new Dictionary<Vertex, int>(vcomp);
|
||||
m_bdata.m_triangles = new List<Triangle>();
|
||||
m_bdata.m_centroid = Vector3.Zero;
|
||||
m_bdata.m_centroidDiv = 0;
|
||||
m_bdata.m_obbXmin = float.MaxValue;
|
||||
m_bdata.m_obbXmax = float.MinValue;
|
||||
m_bdata.m_obbYmin = float.MaxValue;
|
||||
m_bdata.m_obbYmax = float.MinValue;
|
||||
m_bdata.m_obbZmin = float.MaxValue;
|
||||
m_bdata.m_obbZmax = float.MinValue;
|
||||
m_obb = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
m_obboffset = Vector3.Zero;
|
||||
}
|
||||
|
||||
public int RefCount { get; set; }
|
||||
|
||||
public AMeshKey Key { get; set; }
|
||||
|
||||
public void Scale(Vector3 scale)
|
||||
public Mesh Scale(Vector3 scale)
|
||||
{
|
||||
if (m_verticesPtr == null || m_indicesPtr == null)
|
||||
return null;
|
||||
|
||||
Mesh result = new Mesh();
|
||||
|
||||
float x = scale.X;
|
||||
float y = scale.Y;
|
||||
float z = scale.Z;
|
||||
|
||||
result.m_obb.X = m_obb.X * x;
|
||||
result.m_obb.Y = m_obb.Y * y;
|
||||
result.m_obb.Z = m_obb.Z * z;
|
||||
result.m_obboffset.X = m_obboffset.X * x;
|
||||
result.m_obboffset.Y = m_obboffset.Y * y;
|
||||
result.m_obboffset.Z = m_obboffset.Z * z;
|
||||
|
||||
result.vertices = new float[vertices.Length];
|
||||
int j = 0;
|
||||
for (int i = 0; i < m_vertexCount; i++)
|
||||
{
|
||||
result.vertices[j] = vertices[j] * x;
|
||||
j++;
|
||||
result.vertices[j] = vertices[j] * y;
|
||||
j++;
|
||||
result.vertices[j] = vertices[j] * z;
|
||||
j++;
|
||||
}
|
||||
|
||||
result.indexes = new int[indexes.Length];
|
||||
indexes.CopyTo(result.indexes,0);
|
||||
|
||||
result.pinMemory();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Mesh Clone()
|
||||
{
|
||||
Mesh result = new Mesh();
|
||||
|
||||
foreach (Triangle t in m_triangles)
|
||||
if (m_bdata != null)
|
||||
{
|
||||
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||
result.m_bdata = new MeshBuildingData();
|
||||
foreach (Triangle t in m_bdata.m_triangles)
|
||||
{
|
||||
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
|
||||
}
|
||||
result.m_bdata.m_centroid = m_bdata.m_centroid;
|
||||
result.m_bdata.m_centroidDiv = m_bdata.m_centroidDiv;
|
||||
result.m_bdata.m_obbXmin = m_bdata.m_obbXmin;
|
||||
result.m_bdata.m_obbXmax = m_bdata.m_obbXmax;
|
||||
result.m_bdata.m_obbYmin = m_bdata.m_obbYmin;
|
||||
result.m_bdata.m_obbYmax = m_bdata.m_obbYmax;
|
||||
result.m_bdata.m_obbZmin = m_bdata.m_obbZmin;
|
||||
result.m_bdata.m_obbZmax = m_bdata.m_obbZmax;
|
||||
}
|
||||
result.m_centroid = m_centroid;
|
||||
result.m_centroidDiv = m_centroidDiv;
|
||||
result.m_obbXmin = m_obbXmin;
|
||||
result.m_obbXmax = m_obbXmax;
|
||||
result.m_obbYmin = m_obbYmin;
|
||||
result.m_obbYmax = m_obbYmax;
|
||||
result.m_obbZmin = m_obbZmin;
|
||||
result.m_obbZmax = m_obbZmax;
|
||||
result.m_obb = m_obb;
|
||||
result.m_obboffset = m_obboffset;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -124,37 +183,34 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
float y = v.Y;
|
||||
float z = v.Z;
|
||||
|
||||
m_centroid.X += x;
|
||||
m_centroid.Y += y;
|
||||
m_centroid.Z += z;
|
||||
m_centroidDiv++;
|
||||
m_bdata.m_centroid.X += x;
|
||||
m_bdata.m_centroid.Y += y;
|
||||
m_bdata.m_centroid.Z += z;
|
||||
m_bdata.m_centroidDiv++;
|
||||
|
||||
if (x > m_obbXmax)
|
||||
m_obbXmax = x;
|
||||
else if (x < m_obbXmin)
|
||||
m_obbXmin = x;
|
||||
if (x > m_bdata.m_obbXmax)
|
||||
m_bdata.m_obbXmax = x;
|
||||
else if (x < m_bdata.m_obbXmin)
|
||||
m_bdata.m_obbXmin = x;
|
||||
|
||||
if (y > m_obbYmax)
|
||||
m_obbYmax = y;
|
||||
else if (y < m_obbYmin)
|
||||
m_obbYmin = y;
|
||||
if (y > m_bdata.m_obbYmax)
|
||||
m_bdata.m_obbYmax = y;
|
||||
else if (y < m_bdata.m_obbYmin)
|
||||
m_bdata.m_obbYmin = y;
|
||||
|
||||
if (z > m_obbZmax)
|
||||
m_obbZmax = z;
|
||||
else if (z < m_obbZmin)
|
||||
m_obbZmin = z;
|
||||
if (z > m_bdata.m_obbZmax)
|
||||
m_bdata.m_obbZmax = z;
|
||||
else if (z < m_bdata.m_obbZmin)
|
||||
m_bdata.m_obbZmin = z;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void Add(Triangle triangle)
|
||||
{
|
||||
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
|
||||
// If a vertex of the triangle is not yet in the vertices list,
|
||||
// add it and set its index to the current index count
|
||||
// vertex == seems broken
|
||||
// skip colapsed triangles
|
||||
|
||||
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|
||||
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|
||||
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
|
||||
|
@ -163,46 +219,45 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_vertices.Count == 0)
|
||||
if (m_bdata.m_vertices.Count == 0)
|
||||
{
|
||||
m_centroidDiv = 0;
|
||||
m_centroid = Vector3.Zero;
|
||||
m_bdata.m_centroidDiv = 0;
|
||||
m_bdata.m_centroid = Vector3.Zero;
|
||||
}
|
||||
|
||||
if (!m_vertices.ContainsKey(triangle.v1))
|
||||
if (!m_bdata.m_vertices.ContainsKey(triangle.v1))
|
||||
{
|
||||
m_vertices[triangle.v1] = m_vertices.Count;
|
||||
m_bdata.m_vertices[triangle.v1] = m_bdata.m_vertices.Count;
|
||||
addVertexLStats(triangle.v1);
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v2))
|
||||
if (!m_bdata.m_vertices.ContainsKey(triangle.v2))
|
||||
{
|
||||
m_vertices[triangle.v2] = m_vertices.Count;
|
||||
m_bdata.m_vertices[triangle.v2] = m_bdata.m_vertices.Count;
|
||||
addVertexLStats(triangle.v2);
|
||||
}
|
||||
if (!m_vertices.ContainsKey(triangle.v3))
|
||||
if (!m_bdata.m_vertices.ContainsKey(triangle.v3))
|
||||
{
|
||||
m_vertices[triangle.v3] = m_vertices.Count;
|
||||
m_bdata.m_vertices[triangle.v3] = m_bdata.m_vertices.Count;
|
||||
addVertexLStats(triangle.v3);
|
||||
}
|
||||
m_triangles.Add(triangle);
|
||||
m_bdata.m_triangles.Add(triangle);
|
||||
}
|
||||
|
||||
public Vector3 GetCentroid()
|
||||
{
|
||||
if (m_centroidDiv > 0)
|
||||
return new Vector3(m_centroid.X / m_centroidDiv, m_centroid.Y / m_centroidDiv, m_centroid.Z / m_centroidDiv);
|
||||
else
|
||||
return Vector3.Zero;
|
||||
return m_obboffset;
|
||||
|
||||
}
|
||||
|
||||
public Vector3 GetOBB()
|
||||
{
|
||||
return m_obb;
|
||||
float x, y, z;
|
||||
if (m_centroidDiv > 0)
|
||||
if (m_bdata.m_centroidDiv > 0)
|
||||
{
|
||||
x = (m_obbXmax - m_obbXmin) * 0.5f;
|
||||
y = (m_obbYmax - m_obbYmin) * 0.5f;
|
||||
z = (m_obbZmax - m_obbZmin) * 0.5f;
|
||||
x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
|
||||
y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
|
||||
z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
|
||||
}
|
||||
else // ??
|
||||
{
|
||||
|
@ -213,72 +268,10 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
return new Vector3(x, y, z);
|
||||
}
|
||||
|
||||
public void CalcNormals()
|
||||
{
|
||||
int iTriangles = m_triangles.Count;
|
||||
|
||||
this.m_normals = new float[iTriangles * 3];
|
||||
|
||||
int i = 0;
|
||||
foreach (Triangle t in m_triangles)
|
||||
{
|
||||
float ux, uy, uz;
|
||||
float vx, vy, vz;
|
||||
float wx, wy, wz;
|
||||
|
||||
ux = t.v1.X;
|
||||
uy = t.v1.Y;
|
||||
uz = t.v1.Z;
|
||||
|
||||
vx = t.v2.X;
|
||||
vy = t.v2.Y;
|
||||
vz = t.v2.Z;
|
||||
|
||||
wx = t.v3.X;
|
||||
wy = t.v3.Y;
|
||||
wz = t.v3.Z;
|
||||
|
||||
|
||||
// Vectors for edges
|
||||
float e1x, e1y, e1z;
|
||||
float e2x, e2y, e2z;
|
||||
|
||||
e1x = ux - vx;
|
||||
e1y = uy - vy;
|
||||
e1z = uz - vz;
|
||||
|
||||
e2x = ux - wx;
|
||||
e2y = uy - wy;
|
||||
e2z = uz - wz;
|
||||
|
||||
|
||||
// Cross product for normal
|
||||
float nx, ny, nz;
|
||||
nx = e1y * e2z - e1z * e2y;
|
||||
ny = e1z * e2x - e1x * e2z;
|
||||
nz = e1x * e2y - e1y * e2x;
|
||||
|
||||
// Length
|
||||
float l = (float)Math.Sqrt(nx * nx + ny * ny + nz * nz);
|
||||
float lReciprocal = 1.0f / l;
|
||||
|
||||
// Normalized "normal"
|
||||
//nx /= l;
|
||||
//ny /= l;
|
||||
//nz /= l;
|
||||
|
||||
m_normals[i] = nx * lReciprocal;
|
||||
m_normals[i + 1] = ny * lReciprocal;
|
||||
m_normals[i + 2] = nz * lReciprocal;
|
||||
|
||||
i += 3;
|
||||
}
|
||||
}
|
||||
|
||||
public List<Vector3> getVertexList()
|
||||
{
|
||||
List<Vector3> result = new List<Vector3>();
|
||||
foreach (Vertex v in m_vertices.Keys)
|
||||
foreach (Vertex v in m_bdata.m_vertices.Keys)
|
||||
{
|
||||
result.Add(new Vector3(v.X, v.Y, v.Z));
|
||||
}
|
||||
|
@ -287,10 +280,10 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
private float[] getVertexListAsFloat()
|
||||
{
|
||||
if (m_vertices == null)
|
||||
if (m_bdata.m_vertices == null)
|
||||
throw new NotSupportedException();
|
||||
float[] result = new float[m_vertices.Count * 3];
|
||||
foreach (KeyValuePair<Vertex, int> kvp in m_vertices)
|
||||
float[] result = new float[m_bdata.m_vertices.Count * 3];
|
||||
foreach (KeyValuePair<Vertex, int> kvp in m_bdata.m_vertices)
|
||||
{
|
||||
Vertex v = kvp.Key;
|
||||
int i = kvp.Value;
|
||||
|
@ -303,74 +296,39 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
public float[] getVertexListAsFloatLocked()
|
||||
{
|
||||
if (m_pinnedVertexes.IsAllocated)
|
||||
return (float[])(m_pinnedVertexes.Target);
|
||||
|
||||
float[] result = getVertexListAsFloat();
|
||||
m_pinnedVertexes = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||
// Inform the garbage collector of this unmanaged allocation so it can schedule
|
||||
// the next GC round more intelligently
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(result));
|
||||
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void PrepForOde()
|
||||
{
|
||||
// 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 * 3 * sizeof(float);
|
||||
m_verticesPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(byteCount);
|
||||
System.Runtime.InteropServices.Marshal.Copy(vertexList, 0, m_verticesPtr, m_vertexCount * 3);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
releaseSourceMeshData();
|
||||
}
|
||||
|
||||
public void getVertexListAsPtrToFloatArray(out IntPtr vertices, out int vertexStride, out int vertexCount)
|
||||
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)
|
||||
if (m_verticesPtr == IntPtr.Zero && m_bdata != null)
|
||||
{
|
||||
float[] vertexList = getVertexListAsFloat();
|
||||
vertices = 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);
|
||||
m_vertexCount = vertices.Length / 3;
|
||||
vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
|
||||
m_verticesPtr = vhandler.AddrOfPinnedObject();
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(vertices));
|
||||
}
|
||||
vertices = m_verticesPtr;
|
||||
_vertices = m_verticesPtr;
|
||||
vertexCount = m_vertexCount;
|
||||
}
|
||||
|
||||
public int[] getIndexListAsInt()
|
||||
{
|
||||
if (m_triangles == null)
|
||||
if (m_bdata.m_triangles == null)
|
||||
throw new NotSupportedException();
|
||||
int[] result = new int[m_triangles.Count * 3];
|
||||
for (int i = 0; i < m_triangles.Count; i++)
|
||||
int[] result = new int[m_bdata.m_triangles.Count * 3];
|
||||
for (int i = 0; i < m_bdata.m_triangles.Count; i++)
|
||||
{
|
||||
Triangle t = m_triangles[i];
|
||||
result[3 * i + 0] = m_vertices[t.v1];
|
||||
result[3 * i + 1] = m_vertices[t.v2];
|
||||
result[3 * i + 2] = m_vertices[t.v3];
|
||||
Triangle t = m_bdata.m_triangles[i];
|
||||
result[3 * i + 0] = m_bdata.m_vertices[t.v1];
|
||||
result[3 * i + 1] = m_bdata.m_vertices[t.v2];
|
||||
result[3 * i + 2] = m_bdata.m_vertices[t.v3];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -381,28 +339,19 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <returns></returns>
|
||||
public int[] getIndexListAsIntLocked()
|
||||
{
|
||||
if (m_pinnedIndex.IsAllocated)
|
||||
return (int[])(m_pinnedIndex.Target);
|
||||
|
||||
int[] result = getIndexListAsInt();
|
||||
m_pinnedIndex = GCHandle.Alloc(result, GCHandleType.Pinned);
|
||||
// Inform the garbage collector of this unmanaged allocation so it can schedule
|
||||
// the next GC round more intelligently
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(result));
|
||||
|
||||
return result;
|
||||
return null;
|
||||
}
|
||||
|
||||
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)
|
||||
if (m_indicesPtr == IntPtr.Zero && m_bdata != null)
|
||||
{
|
||||
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);
|
||||
indexes = getIndexListAsInt();
|
||||
m_indexCount = indexes.Length;
|
||||
ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
|
||||
m_indicesPtr = ihandler.AddrOfPinnedObject();
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(indexes));
|
||||
}
|
||||
// A triangle is 3 ints (indices)
|
||||
triStride = 3 * sizeof(int);
|
||||
|
@ -412,18 +361,16 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
public void releasePinned()
|
||||
{
|
||||
if (m_pinnedVertexes.IsAllocated)
|
||||
m_pinnedVertexes.Free();
|
||||
if (m_pinnedIndex.IsAllocated)
|
||||
m_pinnedIndex.Free();
|
||||
if (m_verticesPtr != IntPtr.Zero)
|
||||
{
|
||||
System.Runtime.InteropServices.Marshal.FreeHGlobal(m_verticesPtr);
|
||||
vhandler.Free();
|
||||
vertices = null;
|
||||
m_verticesPtr = IntPtr.Zero;
|
||||
}
|
||||
if (m_indicesPtr != IntPtr.Zero)
|
||||
{
|
||||
System.Runtime.InteropServices.Marshal.FreeHGlobal(m_indicesPtr);
|
||||
ihandler.Free();
|
||||
indexes = null;
|
||||
m_indicesPtr = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -433,29 +380,42 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// </summary>
|
||||
public void releaseSourceMeshData()
|
||||
{
|
||||
m_triangles = null;
|
||||
m_vertices = null;
|
||||
if (m_bdata != null)
|
||||
{
|
||||
m_bdata.m_triangles = null;
|
||||
m_bdata.m_vertices = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void releaseBuildingMeshData()
|
||||
{
|
||||
if (m_bdata != null)
|
||||
{
|
||||
m_bdata.m_triangles = null;
|
||||
m_bdata.m_vertices = null;
|
||||
m_bdata = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Append(IMesh newMesh)
|
||||
{
|
||||
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
throw new NotSupportedException("Attempt to Append to a pinned Mesh");
|
||||
|
||||
if (!(newMesh is Mesh))
|
||||
return;
|
||||
|
||||
foreach (Triangle t in ((Mesh)newMesh).m_triangles)
|
||||
foreach (Triangle t in ((Mesh)newMesh).m_bdata.m_triangles)
|
||||
Add(t);
|
||||
}
|
||||
|
||||
// Do a linear transformation of mesh.
|
||||
public void TransformLinear(float[,] matrix, float[] offset)
|
||||
{
|
||||
if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
if (m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero)
|
||||
throw new NotSupportedException("Attempt to TransformLinear a pinned Mesh");
|
||||
|
||||
foreach (Vertex v in m_vertices.Keys)
|
||||
|
||||
foreach (Vertex v in m_bdata.m_vertices.Keys)
|
||||
{
|
||||
if (v == null)
|
||||
continue;
|
||||
|
@ -473,10 +433,12 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
if (path == null)
|
||||
return;
|
||||
if (m_bdata == null)
|
||||
return;
|
||||
String fileName = name + "_" + title + ".raw";
|
||||
String completePath = System.IO.Path.Combine(path, fileName);
|
||||
StreamWriter sw = new StreamWriter(completePath);
|
||||
foreach (Triangle t in m_triangles)
|
||||
foreach (Triangle t in m_bdata.m_triangles)
|
||||
{
|
||||
String s = t.ToStringRaw();
|
||||
sw.WriteLine(s);
|
||||
|
@ -486,7 +448,144 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
public void TrimExcess()
|
||||
{
|
||||
m_triangles.TrimExcess();
|
||||
m_bdata.m_triangles.TrimExcess();
|
||||
}
|
||||
|
||||
public void pinMemory()
|
||||
{
|
||||
m_vertexCount = vertices.Length / 3;
|
||||
vhandler = GCHandle.Alloc(vertices, GCHandleType.Pinned);
|
||||
m_verticesPtr = vhandler.AddrOfPinnedObject();
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(vertices));
|
||||
|
||||
m_indexCount = indexes.Length;
|
||||
ihandler = GCHandle.Alloc(indexes, GCHandleType.Pinned);
|
||||
m_indicesPtr = ihandler.AddrOfPinnedObject();
|
||||
GC.AddMemoryPressure(Buffer.ByteLength(indexes));
|
||||
}
|
||||
|
||||
public void PrepForOde()
|
||||
{
|
||||
// If there isn't an unmanaged array allocated yet, do it now
|
||||
if (m_verticesPtr == IntPtr.Zero)
|
||||
vertices = getVertexListAsFloat();
|
||||
|
||||
// If there isn't an unmanaged array allocated yet, do it now
|
||||
if (m_indicesPtr == IntPtr.Zero)
|
||||
indexes = getIndexListAsInt();
|
||||
|
||||
pinMemory();
|
||||
|
||||
float x, y, z;
|
||||
|
||||
if (m_bdata.m_centroidDiv > 0)
|
||||
{
|
||||
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);
|
||||
x = (m_bdata.m_obbXmax - m_bdata.m_obbXmin) * 0.5f;
|
||||
y = (m_bdata.m_obbYmax - m_bdata.m_obbYmin) * 0.5f;
|
||||
z = (m_bdata.m_obbZmax - m_bdata.m_obbZmin) * 0.5f;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
m_obboffset = Vector3.Zero;
|
||||
x = 0.5f;
|
||||
y = 0.5f;
|
||||
z = 0.5f;
|
||||
}
|
||||
m_obb = new Vector3(x, y, z);
|
||||
|
||||
releaseBuildingMeshData();
|
||||
}
|
||||
public bool ToStream(Stream st)
|
||||
{
|
||||
if (m_indicesPtr == IntPtr.Zero || m_verticesPtr == IntPtr.Zero)
|
||||
return false;
|
||||
|
||||
BinaryWriter bw = new BinaryWriter(st);
|
||||
bool ok = true;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
bw.Write(m_vertexCount);
|
||||
bw.Write(m_indexCount);
|
||||
|
||||
for (int i = 0; i < 3 * m_vertexCount; i++)
|
||||
bw.Write(vertices[i]);
|
||||
for (int i = 0; i < m_indexCount; i++)
|
||||
bw.Write(indexes[i]);
|
||||
bw.Write(m_obb.X);
|
||||
bw.Write(m_obb.Y);
|
||||
bw.Write(m_obb.Z);
|
||||
bw.Write(m_obboffset.X);
|
||||
bw.Write(m_obboffset.Y);
|
||||
bw.Write(m_obboffset.Z);
|
||||
}
|
||||
catch
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (bw != null)
|
||||
{
|
||||
bw.Flush();
|
||||
bw.Close();
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
public static Mesh FromStream(Stream st, AMeshKey key)
|
||||
{
|
||||
Mesh mesh = new Mesh();
|
||||
mesh.releaseBuildingMeshData();
|
||||
|
||||
BinaryReader br = new BinaryReader(st);
|
||||
|
||||
bool ok = true;
|
||||
try
|
||||
{
|
||||
mesh.m_vertexCount = br.ReadInt32();
|
||||
mesh.m_indexCount = br.ReadInt32();
|
||||
|
||||
int n = 3 * mesh.m_vertexCount;
|
||||
mesh.vertices = new float[n];
|
||||
for (int i = 0; i < n; i++)
|
||||
mesh.vertices[i] = br.ReadSingle();
|
||||
|
||||
mesh.indexes = new int[mesh.m_indexCount];
|
||||
for (int i = 0; i < mesh.m_indexCount; i++)
|
||||
mesh.indexes[i] = br.ReadInt32();
|
||||
|
||||
mesh.m_obb.X = br.ReadSingle();
|
||||
mesh.m_obb.Y = br.ReadSingle();
|
||||
mesh.m_obb.Z = br.ReadSingle();
|
||||
|
||||
mesh.m_obboffset.X = br.ReadSingle();
|
||||
mesh.m_obboffset.Y = br.ReadSingle();
|
||||
mesh.m_obboffset.Z = br.ReadSingle();
|
||||
}
|
||||
catch
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
|
||||
br.Close();
|
||||
|
||||
if (ok)
|
||||
{
|
||||
mesh.pinMemory();
|
||||
|
||||
mesh.Key = key;
|
||||
mesh.RefCount = 1;
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
mesh.vertices = null;
|
||||
mesh.indexes = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ using System.Reflection;
|
|||
using System.IO;
|
||||
using ComponentAce.Compression.Libs.zlib;
|
||||
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
|
||||
namespace OpenSim.Region.Physics.Meshing
|
||||
{
|
||||
|
@ -68,18 +70,20 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
// Setting baseDir to a path will enable the dumping of raw files
|
||||
// raw files can be imported by blender so a visual inspection of the results can be done
|
||||
#if SPAM
|
||||
const string baseDir = "rawFiles";
|
||||
#else
|
||||
|
||||
public object diskLock = new object();
|
||||
|
||||
public bool doMeshFileCache = true;
|
||||
|
||||
public string cachePath = "MeshCache";
|
||||
|
||||
// const string baseDir = "rawFiles";
|
||||
private const string baseDir = null; //"rawFiles";
|
||||
#endif
|
||||
|
||||
private bool useMeshiesPhysicsMesh = false;
|
||||
|
||||
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
||||
|
||||
// private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
||||
// private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>();
|
||||
private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
|
||||
private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
|
||||
|
||||
|
@ -89,8 +93,16 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
IConfig mesh_config = config.Configs["Mesh"];
|
||||
|
||||
if(mesh_config != null)
|
||||
{
|
||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||
|
||||
if(useMeshiesPhysicsMesh)
|
||||
{
|
||||
doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
|
||||
cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
|
||||
}
|
||||
else
|
||||
doMeshFileCache = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -188,7 +200,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <param name="size">Size of entire object</param>
|
||||
/// <param name="coords"></param>
|
||||
/// <param name="faces"></param>
|
||||
private void AddSubMesh(OSDMap subMeshData, Vector3 size, List<Coord> coords, List<Face> faces)
|
||||
private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces)
|
||||
{
|
||||
// Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
|
||||
|
||||
|
@ -221,9 +233,9 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);
|
||||
|
||||
Coord c = new Coord(
|
||||
Utils.UInt16ToFloat(uX, posMin.X, posMax.X) * size.X,
|
||||
Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y) * size.Y,
|
||||
Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z) * size.Z);
|
||||
Utils.UInt16ToFloat(uX, posMin.X, posMax.X),
|
||||
Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y),
|
||||
Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z));
|
||||
|
||||
coords.Add(c);
|
||||
}
|
||||
|
@ -247,7 +259,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <param name="size"></param>
|
||||
/// <param name="lod"></param>
|
||||
/// <returns></returns>
|
||||
private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool convex)
|
||||
private Mesh CreateMeshFromPrimMesher(string primName, PrimitiveBaseShape primShape, float lod, bool convex)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[MESH]: Creating physics proxy for {0}, shape {1}",
|
||||
|
@ -263,18 +275,18 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
if (!useMeshiesPhysicsMesh)
|
||||
return null;
|
||||
|
||||
if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, size, out coords, out faces, convex))
|
||||
if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
|
||||
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
|
||||
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, out coords, out faces))
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -309,7 +321,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <param name="faces">Faces are added to this list by the method.</param>
|
||||
/// <returns>true if coords and faces were successfully generated, false if not</returns>
|
||||
private bool GenerateCoordsAndFacesFromPrimMeshData(
|
||||
string primName, PrimitiveBaseShape primShape, Vector3 size, out List<Coord> coords, out List<Face> faces, bool convex)
|
||||
string primName, PrimitiveBaseShape primShape, out List<Coord> coords, out List<Face> faces, bool convex)
|
||||
{
|
||||
// m_log.DebugFormat("[MESH]: experimental mesh proxy generation for {0}", primName);
|
||||
|
||||
|
@ -382,7 +394,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
OSD decodedMeshOsd = new OSD();
|
||||
byte[] meshBytes = new byte[physSize];
|
||||
System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
|
||||
// byte[] decompressed = new byte[physSize * 5];
|
||||
|
||||
try
|
||||
{
|
||||
using (MemoryStream inMs = new MemoryStream(meshBytes))
|
||||
|
@ -420,13 +432,13 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
// physics_shape is an array of OSDMaps, one for each submesh
|
||||
if (decodedMeshOsd is OSDArray)
|
||||
{
|
||||
// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
|
||||
// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
|
||||
|
||||
decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
|
||||
foreach (OSD subMeshOsd in decodedMeshOsdArray)
|
||||
{
|
||||
if (subMeshOsd is OSDMap)
|
||||
AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
|
||||
AddSubMesh(subMeshOsd as OSDMap, coords, faces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -498,9 +510,9 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
t3 = data[ptr++];
|
||||
t3 += data[ptr++] << 8;
|
||||
|
||||
f3 = new float3((t1 * range.X + min.X) * size.X,
|
||||
(t2 * range.Y + min.Y) * size.Y,
|
||||
(t3 * range.Z + min.Z) * size.Z);
|
||||
f3 = new float3((t1 * range.X + min.X),
|
||||
(t2 * range.Y + min.Y),
|
||||
(t3 * range.Z + min.Z));
|
||||
vs.Add(f3);
|
||||
}
|
||||
|
||||
|
@ -597,9 +609,9 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
t3 = data[i++];
|
||||
t3 += data[i++] << 8;
|
||||
|
||||
f3 = new float3((t1 * range.X + min.X) * size.X,
|
||||
(t2 * range.Y + min.Y) * size.Y,
|
||||
(t3 * range.Z + min.Z) * size.Z);
|
||||
f3 = new float3((t1 * range.X + min.X),
|
||||
(t2 * range.Y + min.Y),
|
||||
(t3 * range.Z + min.Z));
|
||||
vs.Add(f3);
|
||||
}
|
||||
|
||||
|
@ -687,7 +699,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <param name="faces">Faces are added to this list by the method.</param>
|
||||
/// <returns>true if coords and faces were successfully generated, false if not</returns>
|
||||
private bool GenerateCoordsAndFacesFromPrimSculptData(
|
||||
string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
|
||||
string primName, PrimitiveBaseShape primShape, float lod, out List<Coord> coords, out List<Face> faces)
|
||||
{
|
||||
coords = new List<Coord>();
|
||||
faces = new List<Face>();
|
||||
|
@ -757,9 +769,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
|
||||
idata.Dispose();
|
||||
|
||||
sculptMesh.DumpRaw(baseDir, primName, "primMesh");
|
||||
|
||||
sculptMesh.Scale(size.X, size.Y, size.Z);
|
||||
// sculptMesh.DumpRaw(baseDir, primName, "primMesh");
|
||||
|
||||
coords = sculptMesh.coords;
|
||||
faces = sculptMesh.faces;
|
||||
|
@ -777,7 +787,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
/// <param name="faces">Faces are added to this list by the method.</param>
|
||||
/// <returns>true if coords and faces were successfully generated, false if not</returns>
|
||||
private bool GenerateCoordsAndFacesFromPrimShapeData(
|
||||
string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List<Coord> coords, out List<Face> faces)
|
||||
string primName, PrimitiveBaseShape primShape, float lod, out List<Coord> coords, out List<Face> faces)
|
||||
{
|
||||
PrimMesh primMesh;
|
||||
coords = new List<Coord>();
|
||||
|
@ -912,9 +922,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
}
|
||||
}
|
||||
|
||||
primMesh.DumpRaw(baseDir, primName, "primMesh");
|
||||
|
||||
primMesh.Scale(size.X, size.Y, size.Z);
|
||||
// primMesh.DumpRaw(baseDir, primName, "primMesh");
|
||||
|
||||
coords = primMesh.coords;
|
||||
faces = primMesh.faces;
|
||||
|
@ -934,6 +942,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
key.uuid = primShape.SculptTexture;
|
||||
key.hashB = mdjb2(key.hashB, primShape.SculptType);
|
||||
key.hashB = mdjb2(key.hashB, primShape.PCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -956,6 +965,7 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
hash = mdjb2(hash, primShape.ProfileBegin);
|
||||
hash = mdjb2(hash, primShape.ProfileEnd);
|
||||
hash = mdjb2(hash, primShape.ProfileHollow);
|
||||
hash = mdjb2(hash, primShape.PCode);
|
||||
key.hashA = hash;
|
||||
}
|
||||
|
||||
|
@ -1001,8 +1011,6 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
return CreateMesh(primName, primShape, size, lod, false,false,false);
|
||||
}
|
||||
|
||||
private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
|
||||
|
||||
public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
|
||||
{
|
||||
Mesh mesh = null;
|
||||
|
@ -1031,7 +1039,13 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
m_uniqueReleasedMeshes.Remove(key);
|
||||
lock (m_uniqueMeshes)
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
{
|
||||
try
|
||||
{
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
mesh.RefCount = 1;
|
||||
return mesh;
|
||||
}
|
||||
|
@ -1039,6 +1053,8 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
return null;
|
||||
}
|
||||
|
||||
private static Vector3 m_MeshUnitSize = new Vector3(1.0f, 1.0f, 1.0f);
|
||||
|
||||
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde)
|
||||
{
|
||||
#if SPAM
|
||||
|
@ -1074,41 +1090,78 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
{
|
||||
m_uniqueReleasedMeshes.Remove(key);
|
||||
lock (m_uniqueMeshes)
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
{
|
||||
try
|
||||
{
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
mesh.RefCount = 1;
|
||||
return mesh;
|
||||
}
|
||||
}
|
||||
|
||||
mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
|
||||
Mesh UnitMesh = null;
|
||||
AMeshKey unitKey = GetMeshUniqueKey(primShape, m_MeshUnitSize, (byte)lod, convex);
|
||||
|
||||
if (mesh != null)
|
||||
lock (m_uniqueReleasedMeshes)
|
||||
{
|
||||
if ((!isPhysical) && size.X < minSizeForComplexMesh && size.Y < minSizeForComplexMesh && size.Z < minSizeForComplexMesh)
|
||||
m_uniqueReleasedMeshes.TryGetValue(unitKey, out UnitMesh);
|
||||
if (UnitMesh != null)
|
||||
{
|
||||
#if SPAM
|
||||
m_log.Debug("Meshmerizer: prim " + primName + " has a size of " + size.ToString() + " which is below threshold of " +
|
||||
minSizeForComplexMesh.ToString() + " - creating simple bounding box");
|
||||
#endif
|
||||
mesh = CreateBoundingBoxMesh(mesh);
|
||||
mesh.DumpRaw(baseDir, primName, "Z extruded");
|
||||
UnitMesh.RefCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (UnitMesh == null && primShape.SculptEntry && doMeshFileCache)
|
||||
UnitMesh = GetFromFileCache(unitKey);
|
||||
|
||||
if (UnitMesh == null)
|
||||
{
|
||||
UnitMesh = CreateMeshFromPrimMesher(primName, primShape, lod, convex);
|
||||
|
||||
if (UnitMesh == null)
|
||||
return null;
|
||||
|
||||
UnitMesh.DumpRaw(baseDir, unitKey.ToString(), "Z");
|
||||
|
||||
if (forOde)
|
||||
{
|
||||
// force pinned mem allocation
|
||||
mesh.PrepForOde();
|
||||
UnitMesh.PrepForOde();
|
||||
}
|
||||
else
|
||||
mesh.TrimExcess();
|
||||
UnitMesh.TrimExcess();
|
||||
|
||||
mesh.Key = key;
|
||||
mesh.RefCount = 1;
|
||||
UnitMesh.Key = unitKey;
|
||||
UnitMesh.RefCount = 1;
|
||||
|
||||
lock(m_uniqueMeshes)
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
if (doMeshFileCache && primShape.SculptEntry)
|
||||
StoreToFileCache(unitKey, UnitMesh);
|
||||
|
||||
lock (m_uniqueReleasedMeshes)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_uniqueReleasedMeshes.Add(unitKey, UnitMesh);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
mesh = UnitMesh.Scale(size);
|
||||
mesh.Key = key;
|
||||
mesh.RefCount = 1;
|
||||
lock (m_uniqueMeshes)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_uniqueMeshes.Add(key, mesh);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
@ -1133,7 +1186,13 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
mesh.RefCount = 0;
|
||||
m_uniqueMeshes.Remove(mesh.Key);
|
||||
lock (m_uniqueReleasedMeshes)
|
||||
m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
|
||||
{
|
||||
try
|
||||
{
|
||||
m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1160,10 +1219,102 @@ namespace OpenSim.Region.Physics.Meshing
|
|||
foreach (Mesh m in meshstodelete)
|
||||
{
|
||||
m_uniqueReleasedMeshes.Remove(m.Key);
|
||||
m.releaseSourceMeshData();
|
||||
m.releaseBuildingMeshData();
|
||||
m.releasePinned();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void FileNames(AMeshKey key, out string dir,out string fullFileName)
|
||||
{
|
||||
string id = key.ToString();
|
||||
string init = id.Substring(0, 1);
|
||||
dir = System.IO.Path.Combine(cachePath, init);
|
||||
fullFileName = System.IO.Path.Combine(dir, id);
|
||||
}
|
||||
|
||||
public string FullFileName(AMeshKey key)
|
||||
{
|
||||
string id = key.ToString();
|
||||
string init = id.Substring(0,1);
|
||||
id = System.IO.Path.Combine(init, id);
|
||||
id = System.IO.Path.Combine(cachePath, id);
|
||||
return id;
|
||||
}
|
||||
|
||||
private Mesh GetFromFileCache(AMeshKey key)
|
||||
{
|
||||
Mesh mesh = null;
|
||||
string filename = FullFileName(key);
|
||||
bool ok = true;
|
||||
|
||||
lock (diskLock)
|
||||
{
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
FileStream stream = null;
|
||||
try
|
||||
{
|
||||
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
BinaryFormatter bformatter = new BinaryFormatter();
|
||||
|
||||
mesh = Mesh.FromStream(stream, key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ok = false;
|
||||
m_log.ErrorFormat(
|
||||
"[MESH CACHE]: Failed to get file {0}. Exception {1} {2}",
|
||||
filename, e.Message, e.StackTrace);
|
||||
}
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
|
||||
if (mesh == null || !ok)
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
private void StoreToFileCache(AMeshKey key, Mesh mesh)
|
||||
{
|
||||
Stream stream = null;
|
||||
bool ok = false;
|
||||
|
||||
// Make sure the target cache directory exists
|
||||
string dir = String.Empty;
|
||||
string filename = String.Empty;
|
||||
|
||||
FileNames(key, out dir, out filename);
|
||||
|
||||
lock (diskLock)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
stream = File.Open(filename, FileMode.Create);
|
||||
ok = mesh.ToStream(stream);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[MESH CACHE]: Failed to write file {0}. Exception {1} {2}.",
|
||||
filename, e.Message, e.StackTrace);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (stream != null)
|
||||
stream.Close();
|
||||
|
||||
if (!ok && File.Exists(filename))
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -718,7 +718,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
|
||||
return;
|
||||
|
||||
/*
|
||||
// debug
|
||||
PhysicsActor dp2;
|
||||
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
|
||||
|
@ -742,7 +742,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
//
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if(d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
|
||||
|
|
Loading…
Reference in New Issue