diff options
-rw-r--r-- | OpenSim/Region/Physics/Manager/IMesher.cs | 12 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 107 |
3 files changed, 96 insertions, 29 deletions
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs index 19aa747..a8c99f7 100644 --- a/OpenSim/Region/Physics/Manager/IMesher.cs +++ b/OpenSim/Region/Physics/Manager/IMesher.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Runtime.InteropServices; | ||
30 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
31 | using OpenMetaverse; | 32 | using OpenMetaverse; |
32 | 33 | ||
@@ -56,6 +57,17 @@ namespace OpenSim.Region.Physics.Manager | |||
56 | { | 57 | { |
57 | } | 58 | } |
58 | 59 | ||
60 | [StructLayout(LayoutKind.Explicit)] | ||
61 | public struct AMeshKey | ||
62 | { | ||
63 | [FieldOffset(0)] | ||
64 | public UUID uuid; | ||
65 | [FieldOffset(0)] | ||
66 | public ulong hashA; | ||
67 | [FieldOffset(8)] | ||
68 | public ulong hashB; | ||
69 | } | ||
70 | |||
59 | public interface IMesh | 71 | public interface IMesh |
60 | { | 72 | { |
61 | List<Vector3> getVertexList(); | 73 | List<Vector3> getVertexList(); |
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index 0727802..98c0f0b 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs | |||
@@ -37,6 +37,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
37 | { | 37 | { |
38 | public class Mesh : IMesh | 38 | public class Mesh : IMesh |
39 | { | 39 | { |
40 | |||
40 | private Dictionary<Vertex, int> m_vertices; | 41 | private Dictionary<Vertex, int> m_vertices; |
41 | private List<Triangle> m_triangles; | 42 | private List<Triangle> m_triangles; |
42 | GCHandle m_pinnedVertexes; | 43 | GCHandle m_pinnedVertexes; |
@@ -47,7 +48,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
47 | int m_indexCount = 0; | 48 | int m_indexCount = 0; |
48 | public float[] m_normals; | 49 | public float[] m_normals; |
49 | Vector3 m_centroid; | 50 | Vector3 m_centroid; |
50 | int m_centroidDiv; | 51 | int m_centroidDiv; |
52 | |||
51 | 53 | ||
52 | private class vertexcomp : IEqualityComparer<Vertex> | 54 | private class vertexcomp : IEqualityComparer<Vertex> |
53 | { | 55 | { |
@@ -79,7 +81,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
79 | 81 | ||
80 | public int RefCount { get; set; } | 82 | public int RefCount { get; set; } |
81 | 83 | ||
82 | public ulong Key { get; set; } | 84 | public AMeshKey Key { get; set; } |
83 | 85 | ||
84 | public void Scale(Vector3 scale) | 86 | public void Scale(Vector3 scale) |
85 | { | 87 | { |
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index a894e5f..4c40175 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -82,8 +82,10 @@ namespace OpenSim.Region.Physics.Meshing | |||
82 | 82 | ||
83 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh | 83 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh |
84 | 84 | ||
85 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 85 | // private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
86 | private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>(); | 86 | // private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>(); |
87 | private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>(); | ||
88 | private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>(); | ||
87 | 89 | ||
88 | public Meshmerizer(IConfigSource config) | 90 | public Meshmerizer(IConfigSource config) |
89 | { | 91 | { |
@@ -977,6 +979,76 @@ namespace OpenSim.Region.Physics.Meshing | |||
977 | return true; | 979 | return true; |
978 | } | 980 | } |
979 | 981 | ||
982 | public AMeshKey GetMeshUniqueKey(PrimitiveBaseShape primShape, Vector3 size, byte lod, bool convex) | ||
983 | { | ||
984 | AMeshKey key = new AMeshKey(); | ||
985 | Byte[] someBytes; | ||
986 | |||
987 | key.hashB = 5181; | ||
988 | ulong hash = 5381; | ||
989 | |||
990 | if (primShape.SculptEntry) | ||
991 | { | ||
992 | key.uuid = primShape.SculptTexture; | ||
993 | key.hashB = mdjb2(key.hashB, primShape.SculptType); | ||
994 | } | ||
995 | else | ||
996 | { | ||
997 | hash = mdjb2(hash, primShape.PathCurve); | ||
998 | hash = mdjb2(hash, (byte)primShape.HollowShape); | ||
999 | hash = mdjb2(hash, (byte)primShape.ProfileShape); | ||
1000 | hash = mdjb2(hash, primShape.PathBegin); | ||
1001 | hash = mdjb2(hash, primShape.PathEnd); | ||
1002 | hash = mdjb2(hash, primShape.PathScaleX); | ||
1003 | hash = mdjb2(hash, primShape.PathScaleY); | ||
1004 | hash = mdjb2(hash, primShape.PathShearX); | ||
1005 | hash = mdjb2(hash, primShape.PathShearY); | ||
1006 | hash = mdjb2(hash, (byte)primShape.PathTwist); | ||
1007 | hash = mdjb2(hash, (byte)primShape.PathTwistBegin); | ||
1008 | hash = mdjb2(hash, (byte)primShape.PathRadiusOffset); | ||
1009 | hash = mdjb2(hash, (byte)primShape.PathTaperX); | ||
1010 | hash = mdjb2(hash, (byte)primShape.PathTaperY); | ||
1011 | hash = mdjb2(hash, primShape.PathRevolutions); | ||
1012 | hash = mdjb2(hash, (byte)primShape.PathSkew); | ||
1013 | hash = mdjb2(hash, primShape.ProfileBegin); | ||
1014 | hash = mdjb2(hash, primShape.ProfileEnd); | ||
1015 | hash = mdjb2(hash, primShape.ProfileHollow); | ||
1016 | key.hashA = hash; | ||
1017 | } | ||
1018 | |||
1019 | hash = key.hashB; | ||
1020 | |||
1021 | someBytes = size.GetBytes(); | ||
1022 | for (int i = 0; i < someBytes.Length; i++) | ||
1023 | hash = mdjb2(hash, someBytes[i]); | ||
1024 | |||
1025 | hash = mdjb2(hash, lod); | ||
1026 | |||
1027 | hash &= 0x3fffffffffffffff; | ||
1028 | |||
1029 | if (convex) | ||
1030 | hash |= 0x4000000000000000; | ||
1031 | |||
1032 | if (primShape.SculptEntry) | ||
1033 | hash |= 0x8000000000000000; | ||
1034 | |||
1035 | key.hashB = hash; | ||
1036 | |||
1037 | return key; | ||
1038 | } | ||
1039 | |||
1040 | private ulong mdjb2(ulong hash, byte c) | ||
1041 | { | ||
1042 | return ((hash << 5) + hash) + (ulong)c; | ||
1043 | } | ||
1044 | |||
1045 | private ulong mdjb2(ulong hash, ushort c) | ||
1046 | { | ||
1047 | hash = ((hash << 5) + hash) + (ulong)((byte)c); | ||
1048 | return ((hash << 5) + hash) + (ulong)(c >> 8); | ||
1049 | } | ||
1050 | |||
1051 | |||
980 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 1052 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
981 | { | 1053 | { |
982 | return CreateMesh(primName, primShape, size, lod, false,false); | 1054 | return CreateMesh(primName, primShape, size, lod, false,false); |
@@ -996,14 +1068,16 @@ namespace OpenSim.Region.Physics.Meshing | |||
996 | #endif | 1068 | #endif |
997 | 1069 | ||
998 | Mesh mesh = null; | 1070 | Mesh mesh = null; |
999 | ulong key = 0; | 1071 | // ulong key = 0; |
1072 | |||
1000 | 1073 | ||
1001 | if (size.X < 0.01f) size.X = 0.01f; | 1074 | if (size.X < 0.01f) size.X = 0.01f; |
1002 | if (size.Y < 0.01f) size.Y = 0.01f; | 1075 | if (size.Y < 0.01f) size.Y = 0.01f; |
1003 | if (size.Z < 0.01f) size.Z = 0.01f; | 1076 | if (size.Z < 0.01f) size.Z = 0.01f; |
1004 | 1077 | ||
1005 | // try to find a identical mesh on meshs in use | 1078 | // try to find a identical mesh on meshs in use |
1006 | key = primShape.GetMeshKey(size, lod, convex); | 1079 | // key = primShape.GetMeshKey(size, lod, convex); |
1080 | AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex); | ||
1007 | 1081 | ||
1008 | lock (m_uniqueMeshes) | 1082 | lock (m_uniqueMeshes) |
1009 | { | 1083 | { |
@@ -1029,29 +1103,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
1029 | return mesh; | 1103 | return mesh; |
1030 | } | 1104 | } |
1031 | } | 1105 | } |
1032 | /* | ||
1033 | Mesh UnitSizeMesh = null; | ||
1034 | ulong unitsizekey = 0; | ||
1035 | |||
1036 | unitsizekey = primShape.GetMeshKey(m_MeshUnitSize, lod, convex); | ||
1037 | 1106 | ||
1038 | lock(m_uniqueMeshes) | ||
1039 | m_uniqueMeshes.TryGetValue(unitsizekey, out UnitSizeMesh); | ||
1040 | |||
1041 | if (UnitSizeMesh !=null) | ||
1042 | { | ||
1043 | UnitSizeMesh.RefCount++; | ||
1044 | mesh = UnitSizeMesh.Clone(); | ||
1045 | mesh.Key = key; | ||
1046 | mesh.Scale(size); | ||
1047 | mesh.RefCount++; | ||
1048 | lock(m_uniqueMeshes) | ||
1049 | m_uniqueMeshes.Add(key, mesh); | ||
1050 | return mesh; | ||
1051 | } | ||
1052 | */ | ||
1053 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); | 1107 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); |
1054 | // mesh.Key = unitsizekey; | ||
1055 | 1108 | ||
1056 | if (mesh != null) | 1109 | if (mesh != null) |
1057 | { | 1110 | { |
@@ -1068,7 +1121,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
1068 | // trim the vertex and triangle lists to free up memory | 1121 | // trim the vertex and triangle lists to free up memory |
1069 | mesh.TrimExcess(); | 1122 | mesh.TrimExcess(); |
1070 | mesh.Key = key; | 1123 | mesh.Key = key; |
1071 | mesh.RefCount++; | 1124 | mesh.RefCount = 1; |
1072 | 1125 | ||
1073 | lock(m_uniqueMeshes) | 1126 | lock(m_uniqueMeshes) |
1074 | m_uniqueMeshes.Add(key, mesh); | 1127 | m_uniqueMeshes.Add(key, mesh); |
@@ -1104,7 +1157,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
1104 | 1157 | ||
1105 | public void ExpireReleaseMeshs() | 1158 | public void ExpireReleaseMeshs() |
1106 | { | 1159 | { |
1107 | if (m_uniqueMeshes.Count == 0) | 1160 | if (m_uniqueReleasedMeshes.Count == 0) |
1108 | return; | 1161 | return; |
1109 | 1162 | ||
1110 | List<Mesh> meshstodelete = new List<Mesh>(); | 1163 | List<Mesh> meshstodelete = new List<Mesh>(); |