From 7137b234b4e99d8d19e83dfb5268674c72f46479 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 3 Oct 2012 19:33:28 +0100 Subject: introduce a ODEMeshWorker class, should be pure cosmetic changes for now --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 40 +++++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 4c40175..44c8972 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -1061,6 +1061,42 @@ namespace OpenSim.Region.Physics.Meshing 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; + + if (size.X < 0.01f) size.X = 0.01f; + if (size.Y < 0.01f) size.Y = 0.01f; + if (size.Z < 0.01f) size.Z = 0.01f; + + AMeshKey key = GetMeshUniqueKey(primShape, size, (byte)lod, convex); + lock (m_uniqueMeshes) + { + m_uniqueMeshes.TryGetValue(key, out mesh); + + if (mesh != null) + { + mesh.RefCount++; + return mesh; + } + } + + // try to find a identical mesh on meshs recently released + lock (m_uniqueReleasedMeshes) + { + m_uniqueReleasedMeshes.TryGetValue(key, out mesh); + if (mesh != null) + { + m_uniqueReleasedMeshes.Remove(key); + lock (m_uniqueMeshes) + m_uniqueMeshes.Add(key, mesh); + mesh.RefCount = 1; + return mesh; + } + } + return null; + } + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) { #if SPAM @@ -1068,15 +1104,13 @@ namespace OpenSim.Region.Physics.Meshing #endif Mesh mesh = null; -// ulong key = 0; - if (size.X < 0.01f) size.X = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f; // try to find a identical mesh on meshs in use -// key = primShape.GetMeshKey(size, lod, convex); + AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex); lock (m_uniqueMeshes) -- cgit v1.1 From 51e1830f86cd0253879f4f60470a3b5fa2b3db7c Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 4 Oct 2012 04:55:53 +0100 Subject: more changes. Most code not in use --- OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 78 +++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index 98c0f0b..47e0cf4 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs @@ -48,8 +48,14 @@ namespace OpenSim.Region.Physics.Meshing int m_indexCount = 0; public float[] m_normals; Vector3 m_centroid; - int m_centroidDiv; + float m_obbXmin; + float m_obbXmax; + float m_obbYmin; + float m_obbYmax; + float m_obbZmin; + float m_obbZmax; + int m_centroidDiv; private class vertexcomp : IEqualityComparer { @@ -77,6 +83,14 @@ namespace OpenSim.Region.Physics.Meshing m_triangles = new List(); 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; + + } public int RefCount { get; set; } @@ -102,6 +116,35 @@ namespace OpenSim.Region.Physics.Meshing return result; } + public void addVertexLStats(Vertex v) + { + float x = v.X; + float y = v.Y; + float z = v.Z; + + m_centroid.X += x; + m_centroid.Y += y; + m_centroid.Z += z; + m_centroidDiv++; + + if (x > m_obbXmax) + m_obbXmax = x; + else if (x < m_obbXmin) + m_obbXmin = x; + + if (y > m_obbYmax) + m_obbYmax = y; + else if (y < m_obbYmin) + m_obbYmin = y; + + if (z > m_obbZmax) + m_obbZmax = z; + else if (z < m_obbZmin) + m_obbZmin = z; + + } + + public void Add(Triangle triangle) { if (m_pinnedIndex.IsAllocated || m_pinnedVertexes.IsAllocated || m_indicesPtr != IntPtr.Zero || m_verticesPtr != IntPtr.Zero) @@ -127,26 +170,17 @@ namespace OpenSim.Region.Physics.Meshing if (!m_vertices.ContainsKey(triangle.v1)) { m_vertices[triangle.v1] = m_vertices.Count; - m_centroid.X += triangle.v1.X; - m_centroid.Y += triangle.v1.Y; - m_centroid.Z += triangle.v1.Z; - m_centroidDiv++; + addVertexLStats(triangle.v1); } if (!m_vertices.ContainsKey(triangle.v2)) { m_vertices[triangle.v2] = m_vertices.Count; - m_centroid.X += triangle.v2.X; - m_centroid.Y += triangle.v2.Y; - m_centroid.Z += triangle.v2.Z; - m_centroidDiv++; + addVertexLStats(triangle.v2); } if (!m_vertices.ContainsKey(triangle.v3)) { m_vertices[triangle.v3] = m_vertices.Count; - m_centroid.X += triangle.v3.X; - m_centroid.Y += triangle.v3.Y; - m_centroid.Z += triangle.v3.Z; - m_centroidDiv++; + addVertexLStats(triangle.v3); } m_triangles.Add(triangle); } @@ -159,6 +193,24 @@ namespace OpenSim.Region.Physics.Meshing return Vector3.Zero; } + public Vector3 GetOBB() + { + float x, y, z; + if (m_centroidDiv > 0) + { + x = (m_obbXmax - m_obbXmin) * 0.5f; + y = (m_obbYmax - m_obbYmin) * 0.5f; + z = (m_obbZmax - m_obbZmin) * 0.5f; + } + else // ?? + { + x = 0.5f; + y = 0.5f; + z = 0.5f; + } + return new Vector3(x, y, z); + } + public void CalcNormals() { int iTriangles = m_triangles.Count; -- cgit v1.1 From 89d342b5ce9ac5d9fc4fd493eead8e050f99c91a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 4 Oct 2012 08:14:52 +0100 Subject: more changes and more non active code --- OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index 47e0cf4..c31ec08 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs @@ -89,8 +89,6 @@ namespace OpenSim.Region.Physics.Meshing m_obbYmax = float.MinValue; m_obbZmin = float.MaxValue; m_obbZmax = float.MinValue; - - } public int RefCount { get; set; } @@ -99,8 +97,6 @@ namespace OpenSim.Region.Physics.Meshing public void Scale(Vector3 scale) { - - } public Mesh Clone() @@ -113,6 +109,12 @@ namespace OpenSim.Region.Physics.Meshing } 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; return result; } -- cgit v1.1 From 78ce7a0a04dc5ce3212acfb0e88a3a5a1b876100 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 7 Oct 2012 01:20:52 +0100 Subject: [DANGER UNTESTED] ODE mesh assets. Other plugins will not do meshs/sculpts now --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 64 ++--------------------- 1 file changed, 3 insertions(+), 61 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 44c8972..2933d86 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -74,10 +74,6 @@ namespace OpenSim.Region.Physics.Meshing private const string baseDir = null; //"rawFiles"; #endif - private bool cacheSculptMaps = true; - private bool cacheSculptAlphaMaps = true; - - private string decodedSculptMapPath = null; private bool useMeshiesPhysicsMesh = false; private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh @@ -92,29 +88,9 @@ namespace OpenSim.Region.Physics.Meshing IConfig start_config = config.Configs["Startup"]; IConfig mesh_config = config.Configs["Mesh"]; - decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); - - cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); - - if (Environment.OSVersion.Platform == PlatformID.Unix) - { - cacheSculptAlphaMaps = false; - } - else - cacheSculptAlphaMaps = cacheSculptMaps; - if(mesh_config != null) useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); - try - { - if (!Directory.Exists(decodedSculptMapPath)) - Directory.CreateDirectory(decodedSculptMapPath); - } - catch (Exception e) - { - m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message); - } } /// @@ -444,7 +420,7 @@ 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) @@ -717,29 +693,7 @@ namespace OpenSim.Region.Physics.Meshing faces = new List(); PrimMesher.SculptMesh sculptMesh; Image idata = null; - string decodedSculptFileName = ""; - if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) - { - decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); - try - { - if (File.Exists(decodedSculptFileName)) - { - idata = Image.FromFile(decodedSculptFileName); - } - } - catch (Exception e) - { - m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); - - } - //if (idata != null) - // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); - } - - if (idata == null) - { if (primShape.SculptData == null || primShape.SculptData.Length == 0) return false; @@ -748,25 +702,15 @@ namespace OpenSim.Region.Physics.Meshing OpenMetaverse.Imaging.ManagedImage unusedData; OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); + unusedData = null; + if (idata == null) { // In some cases it seems that the decode can return a null bitmap without throwing // an exception m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName); - return false; } - - unusedData = null; - - //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); - - if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0))) - // don't cache images with alpha channel in linux since mono can't load them correctly) - { - try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } - catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } - } } catch (DllNotFoundException) { @@ -783,7 +727,6 @@ namespace OpenSim.Region.Physics.Meshing m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); return false; } - } PrimMesher.SculptMesh.SculptType sculptType; // remove mirror and invert bits @@ -1048,7 +991,6 @@ namespace OpenSim.Region.Physics.Meshing return ((hash << 5) + hash) + (ulong)(c >> 8); } - public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { return CreateMesh(primName, primShape, size, lod, false,false); -- cgit v1.1 From a1fcfe867786de121d0960e684252525781ac453 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 7 Oct 2012 23:54:15 +0100 Subject: a few changes/fix (?) --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 2933d86..fabadd3 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -1113,17 +1113,17 @@ namespace OpenSim.Region.Physics.Meshing Mesh mesh = (Mesh)imesh; - int curRefCount = mesh.RefCount; - curRefCount--; - - if (curRefCount > 0) - { - mesh.RefCount = curRefCount; - return; - } - lock (m_uniqueMeshes) { + int curRefCount = mesh.RefCount; + curRefCount--; + + if (curRefCount > 0) + { + mesh.RefCount = curRefCount; + return; + } + mesh.RefCount = 0; m_uniqueMeshes.Remove(mesh.Key); lock (m_uniqueReleasedMeshes) -- cgit v1.1 From 87175412882e8e4b7cd9d92d6a9be8546ec7e9e9 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 9 Oct 2012 04:31:50 +0100 Subject: force allocation of mesh data on creation ( messy code version ) --- OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 26 +++++++++++++++++++++++ OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 16 +++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index c31ec08..a0a18c4 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs @@ -315,6 +315,32 @@ namespace OpenSim.Region.Physics.Meshing return result; } + 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) { // A vertex is 3 floats diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index fabadd3..dec5eb7 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -993,12 +993,12 @@ namespace OpenSim.Region.Physics.Meshing public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) { - return CreateMesh(primName, primShape, size, lod, false,false); + return CreateMesh(primName, primShape, size, lod, false,false,false); } public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical) { - return CreateMesh(primName, primShape, size, lod, false,false); + return CreateMesh(primName, primShape, size, lod, false,false,false); } private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); @@ -1039,7 +1039,7 @@ namespace OpenSim.Region.Physics.Meshing return null; } - public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) + public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex, bool forOde) { #if SPAM m_log.DebugFormat("[MESH]: Creating mesh for {0}", primName); @@ -1094,8 +1094,14 @@ namespace OpenSim.Region.Physics.Meshing mesh.DumpRaw(baseDir, primName, "Z extruded"); } - // trim the vertex and triangle lists to free up memory - mesh.TrimExcess(); + if (forOde) + { + // force pinned mem allocation + mesh.PrepForOde(); + } + else + mesh.TrimExcess(); + mesh.Key = key; mesh.RefCount = 1; -- cgit v1.1 From 6e217965841d474ba7e19c99dcfa5e86c1c459da Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 12 Oct 2012 23:37:28 +0100 Subject: [TEST] disk cache meshs --- OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 551 +++++++++++++--------- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 259 +++++++--- 2 files changed, 530 insertions(+), 280 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index a0a18c4..1e9b8bc 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs @@ -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 Mesh : IMesh + public class MeshBuildingData { + public Dictionary m_vertices; + public List 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; + } - private Dictionary m_vertices; - private List m_triangles; - GCHandle m_pinnedVertexes; - GCHandle m_pinnedIndex; + [Serializable()] + public class Mesh : IMesh + { + 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 { @@ -79,42 +98,82 @@ namespace OpenSim.Region.Physics.Meshing { vertexcomp vcomp = new vertexcomp(); - m_vertices = new Dictionary(vcomp); - m_triangles = new List(); - 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(vcomp); + m_bdata.m_triangles = new List(); + 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 getVertexList() { List result = new List(); - 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 kvp in m_vertices) + float[] result = new float[m_bdata.m_vertices.Count * 3]; + foreach (KeyValuePair 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; - } - - 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(); + return null; } - 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 /// 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 /// 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; } } } diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index dec5eb7..952ecc8 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -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 m_uniqueMeshes = new Dictionary(); -// private Dictionary m_uniqueReleasedMeshes = new Dictionary(); private Dictionary m_uniqueMeshes = new Dictionary(); private Dictionary m_uniqueReleasedMeshes = new Dictionary(); @@ -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; + } } /// @@ -188,7 +200,7 @@ namespace OpenSim.Region.Physics.Meshing /// Size of entire object /// /// - private void AddSubMesh(OSDMap subMeshData, Vector3 size, List coords, List faces) + private void AddSubMesh(OSDMap subMeshData, List coords, List 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 /// /// /// - 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 /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimMeshData( - string primName, PrimitiveBaseShape primShape, Vector3 size, out List coords, out List faces, bool convex) + string primName, PrimitiveBaseShape primShape, out List coords, out List 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 /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimSculptData( - string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) + string primName, PrimitiveBaseShape primShape, float lod, out List coords, out List faces) { coords = new List(); faces = new List(); @@ -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 /// Faces are added to this list by the method. /// true if coords and faces were successfully generated, false if not private bool GenerateCoordsAndFacesFromPrimShapeData( - string primName, PrimitiveBaseShape primShape, Vector3 size, float lod, out List coords, out List faces) + string primName, PrimitiveBaseShape primShape, float lod, out List coords, out List faces) { PrimMesh primMesh; coords = new List(); @@ -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); + } + } } } -- cgit v1.1 From 9ada03bcdd8bff22fea162672b5a3dde88d4d0c5 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 13 Oct 2012 00:49:08 +0100 Subject: missing file (again) --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 952ecc8..2fe34e3 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -936,13 +936,14 @@ namespace OpenSim.Region.Physics.Meshing Byte[] someBytes; key.hashB = 5181; + key.hashC = 5181; ulong hash = 5381; if (primShape.SculptEntry) { key.uuid = primShape.SculptTexture; - key.hashB = mdjb2(key.hashB, primShape.SculptType); - key.hashB = mdjb2(key.hashB, primShape.PCode); + key.hashC = mdjb2(key.hashC, primShape.SculptType); + key.hashC = mdjb2(key.hashC, primShape.PCode); } else { @@ -954,6 +955,9 @@ namespace OpenSim.Region.Physics.Meshing hash = mdjb2(hash, primShape.PathScaleX); hash = mdjb2(hash, primShape.PathScaleY); hash = mdjb2(hash, primShape.PathShearX); + key.hashA = hash; + key.hashA |= 0xf000000000000000; + hash = key.hashB; hash = mdjb2(hash, primShape.PathShearY); hash = mdjb2(hash, (byte)primShape.PathTwist); hash = mdjb2(hash, (byte)primShape.PathTwistBegin); @@ -966,10 +970,10 @@ namespace OpenSim.Region.Physics.Meshing hash = mdjb2(hash, primShape.ProfileEnd); hash = mdjb2(hash, primShape.ProfileHollow); hash = mdjb2(hash, primShape.PCode); - key.hashA = hash; + key.hashB = hash; } - hash = key.hashB; + hash = key.hashC; someBytes = size.GetBytes(); for (int i = 0; i < someBytes.Length; i++) -- cgit v1.1 From 666fb744a36ca5497dc8868298f47c23cd72b1a8 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 13 Oct 2012 01:41:18 +0100 Subject: retouch mesh ids --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 2fe34e3..35eabd4 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -956,7 +956,6 @@ namespace OpenSim.Region.Physics.Meshing hash = mdjb2(hash, primShape.PathScaleY); hash = mdjb2(hash, primShape.PathShearX); key.hashA = hash; - key.hashA |= 0xf000000000000000; hash = key.hashB; hash = mdjb2(hash, primShape.PathShearY); hash = mdjb2(hash, (byte)primShape.PathTwist); @@ -975,21 +974,32 @@ namespace OpenSim.Region.Physics.Meshing hash = key.hashC; - someBytes = size.GetBytes(); - for (int i = 0; i < someBytes.Length; i++) - hash = mdjb2(hash, someBytes[i]); - hash = mdjb2(hash, lod); - - hash &= 0x3fffffffffffffff; + + if (size == m_MeshUnitSize) + { + hash = hash << 8; + hash |= 8; + } + else + { + someBytes = size.GetBytes(); + for (int i = 0; i < someBytes.Length; i++) + hash = mdjb2(hash, someBytes[i]); + hash = hash << 8; + } if (convex) - hash |= 0x4000000000000000; + hash |= 4; if (primShape.SculptEntry) - hash |= 0x8000000000000000; + { + hash |= 1; + if (primShape.SculptType == (byte)SculptType.Mesh) + hash |= 2; + } - key.hashB = hash; + key.hashC = hash; return key; } -- cgit v1.1 From 5986b4ee3980d27d6e8524c4b8f5ad4c9a701288 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sat, 13 Oct 2012 22:30:34 +0100 Subject: add mesh cache expire on region startup. Expires will be relative to previus expire (assumed done only once at startup). File 'cntr' on cache folder stores time. Deleting it will force a skip on expire. Default time is 48hours before previus startup to account for failed ones etc. --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 88 ++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 35eabd4..6550b66 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -76,6 +76,8 @@ namespace OpenSim.Region.Physics.Meshing public bool doMeshFileCache = true; public string cachePath = "MeshCache"; + public TimeSpan CacheExpire; + public bool doCacheExpire = true; // const string baseDir = "rawFiles"; private const string baseDir = null; //"rawFiles"; @@ -92,17 +94,29 @@ namespace OpenSim.Region.Physics.Meshing IConfig start_config = config.Configs["Startup"]; IConfig mesh_config = config.Configs["Mesh"]; + + float fcache = 48.0f; +// float fcache = 0.02f; + if(mesh_config != null) { useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); - if(useMeshiesPhysicsMesh) + if (useMeshiesPhysicsMesh) { doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); + fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); + doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); } else + { doMeshFileCache = false; + doCacheExpire = false; + } } + + CacheExpire = TimeSpan.FromHours(fcache); + } /// @@ -1273,6 +1287,7 @@ namespace OpenSim.Region.Physics.Meshing BinaryFormatter bformatter = new BinaryFormatter(); mesh = Mesh.FromStream(stream, key); + } catch (Exception e) { @@ -1281,11 +1296,14 @@ namespace OpenSim.Region.Physics.Meshing "[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); + else + File.SetLastAccessTimeUtc(filename, DateTime.UtcNow); } } @@ -1326,8 +1344,72 @@ namespace OpenSim.Region.Physics.Meshing if (stream != null) stream.Close(); - if (!ok && File.Exists(filename)) - File.Delete(filename); + if (File.Exists(filename)) + { + if (ok) + File.SetLastAccessTimeUtc(filename, DateTime.UtcNow); + else + File.Delete(filename); + } + } + } + + public void ExpireFileCache() + { + if (!doCacheExpire) + return; + + string controlfile = System.IO.Path.Combine(cachePath, "cntr"); + + lock (diskLock) + { + try + { + if (File.Exists(controlfile)) + { + int ndeleted = 0; + int totalfiles = 0; + int ndirs = 0; + DateTime OlderTime = File.GetLastAccessTimeUtc(controlfile) - CacheExpire; + File.SetLastAccessTimeUtc(controlfile, DateTime.UtcNow); + + foreach (string dir in Directory.GetDirectories(cachePath)) + { + try + { + foreach (string file in Directory.GetFiles(dir)) + { + try + { + if (File.GetLastAccessTimeUtc(file) < OlderTime) + { + File.Delete(file); + ndeleted++; + } + } + catch { } + totalfiles++; + } + } + catch { } + ndirs++; + } + + if (ndeleted == 0) + m_log.InfoFormat("[MESH CACHE]: {0} Files in {1} cache folders, no expires", + totalfiles,ndirs); + else + m_log.InfoFormat("[MESH CACHE]: {0} Files in {1} cache folders, expired {2} files accessed before {3}", + totalfiles,ndirs, ndeleted, OlderTime.ToString()); + } + else + { + m_log.Info("[MESH CACHE]: Expire delayed to next startup"); + FileStream fs = File.Create(controlfile,4096,FileOptions.WriteThrough); + fs.Close(); + } + } + catch { } } } } -- cgit v1.1 From e8936366f55c588b02c7aa29e40c478f52f16494 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 16 Oct 2012 11:39:58 +0100 Subject: coment a debug warning --- OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/Physics/UbitMeshing') diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 6550b66..29fdda4 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs @@ -347,7 +347,7 @@ namespace OpenSim.Region.Physics.Meshing if (primShape.SculptData.Length <= 0) { - m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName); +// m_log.InfoFormat("[MESH]: asset data for {0} is zero length", primName); return false; } -- cgit v1.1