diff options
author | UbitUmarov | 2012-08-06 09:06:46 +0100 |
---|---|---|
committer | UbitUmarov | 2012-08-06 09:06:46 +0100 |
commit | 36a1248b317cd80717fef6bc7c8fab318172a075 (patch) | |
tree | c81fc363cfc52d9b3faec5ccb0693f2173650bc0 /OpenSim/Region/Physics/UbitMeshing | |
parent | bug fix: keep sculpt bitmaps border pixels during resolution scaling. (diff) | |
download | opensim-SC-36a1248b317cd80717fef6bc7c8fab318172a075.zip opensim-SC-36a1248b317cd80717fef6bc7c8fab318172a075.tar.gz opensim-SC-36a1248b317cd80717fef6bc7c8fab318172a075.tar.bz2 opensim-SC-36a1248b317cd80717fef6bc7c8fab318172a075.tar.xz |
** DANGER someone should stress test more ** release unused physics meshs, including unmanaged memory allocations (allocated by managed code)
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Mesh.cs | 55 | ||||
-rw-r--r-- | OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | 117 |
2 files changed, 142 insertions, 30 deletions
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs index c715642..0727802 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs | |||
@@ -46,8 +46,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
46 | IntPtr m_indicesPtr = IntPtr.Zero; | 46 | IntPtr m_indicesPtr = IntPtr.Zero; |
47 | int m_indexCount = 0; | 47 | int m_indexCount = 0; |
48 | public float[] m_normals; | 48 | public float[] m_normals; |
49 | Vector3 _centroid; | 49 | Vector3 m_centroid; |
50 | int _centroidDiv; | 50 | int m_centroidDiv; |
51 | 51 | ||
52 | private class vertexcomp : IEqualityComparer<Vertex> | 52 | private class vertexcomp : IEqualityComparer<Vertex> |
53 | { | 53 | { |
@@ -65,7 +65,6 @@ namespace OpenSim.Region.Physics.Meshing | |||
65 | int c = v.Z.GetHashCode(); | 65 | int c = v.Z.GetHashCode(); |
66 | return (a << 16) ^ (b << 8) ^ c; | 66 | return (a << 16) ^ (b << 8) ^ c; |
67 | } | 67 | } |
68 | |||
69 | } | 68 | } |
70 | 69 | ||
71 | public Mesh() | 70 | public Mesh() |
@@ -74,8 +73,18 @@ namespace OpenSim.Region.Physics.Meshing | |||
74 | 73 | ||
75 | m_vertices = new Dictionary<Vertex, int>(vcomp); | 74 | m_vertices = new Dictionary<Vertex, int>(vcomp); |
76 | m_triangles = new List<Triangle>(); | 75 | m_triangles = new List<Triangle>(); |
77 | _centroid = Vector3.Zero; | 76 | m_centroid = Vector3.Zero; |
78 | _centroidDiv = 0; | 77 | m_centroidDiv = 0; |
78 | } | ||
79 | |||
80 | public int RefCount { get; set; } | ||
81 | |||
82 | public ulong Key { get; set; } | ||
83 | |||
84 | public void Scale(Vector3 scale) | ||
85 | { | ||
86 | |||
87 | |||
79 | } | 88 | } |
80 | 89 | ||
81 | public Mesh Clone() | 90 | public Mesh Clone() |
@@ -86,8 +95,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
86 | { | 95 | { |
87 | result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); | 96 | result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); |
88 | } | 97 | } |
89 | result._centroid = _centroid; | 98 | result.m_centroid = m_centroid; |
90 | result._centroidDiv = _centroidDiv; | 99 | result.m_centroidDiv = m_centroidDiv; |
91 | return result; | 100 | return result; |
92 | } | 101 | } |
93 | 102 | ||
@@ -109,41 +118,41 @@ namespace OpenSim.Region.Physics.Meshing | |||
109 | 118 | ||
110 | if (m_vertices.Count == 0) | 119 | if (m_vertices.Count == 0) |
111 | { | 120 | { |
112 | _centroidDiv = 0; | 121 | m_centroidDiv = 0; |
113 | _centroid = Vector3.Zero; | 122 | m_centroid = Vector3.Zero; |
114 | } | 123 | } |
115 | 124 | ||
116 | if (!m_vertices.ContainsKey(triangle.v1)) | 125 | if (!m_vertices.ContainsKey(triangle.v1)) |
117 | { | 126 | { |
118 | m_vertices[triangle.v1] = m_vertices.Count; | 127 | m_vertices[triangle.v1] = m_vertices.Count; |
119 | _centroid.X += triangle.v1.X; | 128 | m_centroid.X += triangle.v1.X; |
120 | _centroid.Y += triangle.v1.Y; | 129 | m_centroid.Y += triangle.v1.Y; |
121 | _centroid.Z += triangle.v1.Z; | 130 | m_centroid.Z += triangle.v1.Z; |
122 | _centroidDiv++; | 131 | m_centroidDiv++; |
123 | } | 132 | } |
124 | if (!m_vertices.ContainsKey(triangle.v2)) | 133 | if (!m_vertices.ContainsKey(triangle.v2)) |
125 | { | 134 | { |
126 | m_vertices[triangle.v2] = m_vertices.Count; | 135 | m_vertices[triangle.v2] = m_vertices.Count; |
127 | _centroid.X += triangle.v2.X; | 136 | m_centroid.X += triangle.v2.X; |
128 | _centroid.Y += triangle.v2.Y; | 137 | m_centroid.Y += triangle.v2.Y; |
129 | _centroid.Z += triangle.v2.Z; | 138 | m_centroid.Z += triangle.v2.Z; |
130 | _centroidDiv++; | 139 | m_centroidDiv++; |
131 | } | 140 | } |
132 | if (!m_vertices.ContainsKey(triangle.v3)) | 141 | if (!m_vertices.ContainsKey(triangle.v3)) |
133 | { | 142 | { |
134 | m_vertices[triangle.v3] = m_vertices.Count; | 143 | m_vertices[triangle.v3] = m_vertices.Count; |
135 | _centroid.X += triangle.v3.X; | 144 | m_centroid.X += triangle.v3.X; |
136 | _centroid.Y += triangle.v3.Y; | 145 | m_centroid.Y += triangle.v3.Y; |
137 | _centroid.Z += triangle.v3.Z; | 146 | m_centroid.Z += triangle.v3.Z; |
138 | _centroidDiv++; | 147 | m_centroidDiv++; |
139 | } | 148 | } |
140 | m_triangles.Add(triangle); | 149 | m_triangles.Add(triangle); |
141 | } | 150 | } |
142 | 151 | ||
143 | public Vector3 GetCentroid() | 152 | public Vector3 GetCentroid() |
144 | { | 153 | { |
145 | if (_centroidDiv > 0) | 154 | if (m_centroidDiv > 0) |
146 | return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv); | 155 | return new Vector3(m_centroid.X / m_centroidDiv, m_centroid.Y / m_centroidDiv, m_centroid.Z / m_centroidDiv); |
147 | else | 156 | else |
148 | return Vector3.Zero; | 157 | return Vector3.Zero; |
149 | } | 158 | } |
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs index 3b1bdfb..a894e5f 100644 --- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs | |||
@@ -83,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
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 | 87 | ||
87 | public Meshmerizer(IConfigSource config) | 88 | public Meshmerizer(IConfigSource config) |
88 | { | 89 | { |
@@ -986,6 +987,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
986 | return CreateMesh(primName, primShape, size, lod, false,false); | 987 | return CreateMesh(primName, primShape, size, lod, false,false); |
987 | } | 988 | } |
988 | 989 | ||
990 | private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); | ||
991 | |||
989 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) | 992 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) |
990 | { | 993 | { |
991 | #if SPAM | 994 | #if SPAM |
@@ -995,17 +998,60 @@ namespace OpenSim.Region.Physics.Meshing | |||
995 | Mesh mesh = null; | 998 | Mesh mesh = null; |
996 | ulong key = 0; | 999 | ulong key = 0; |
997 | 1000 | ||
998 | // If this mesh has been created already, return it instead of creating another copy | ||
999 | // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory | ||
1000 | key = primShape.GetMeshKey(size, lod, convex); | ||
1001 | if (m_uniqueMeshes.TryGetValue(key, out mesh)) | ||
1002 | return mesh; | ||
1003 | |||
1004 | if (size.X < 0.01f) size.X = 0.01f; | 1001 | if (size.X < 0.01f) size.X = 0.01f; |
1005 | if (size.Y < 0.01f) size.Y = 0.01f; | 1002 | if (size.Y < 0.01f) size.Y = 0.01f; |
1006 | if (size.Z < 0.01f) size.Z = 0.01f; | 1003 | if (size.Z < 0.01f) size.Z = 0.01f; |
1007 | 1004 | ||
1005 | // try to find a identical mesh on meshs in use | ||
1006 | key = primShape.GetMeshKey(size, lod, convex); | ||
1007 | |||
1008 | lock (m_uniqueMeshes) | ||
1009 | { | ||
1010 | m_uniqueMeshes.TryGetValue(key, out mesh); | ||
1011 | |||
1012 | if (mesh != null) | ||
1013 | { | ||
1014 | mesh.RefCount++; | ||
1015 | return mesh; | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | // try to find a identical mesh on meshs recently released | ||
1020 | lock (m_uniqueReleasedMeshes) | ||
1021 | { | ||
1022 | m_uniqueReleasedMeshes.TryGetValue(key, out mesh); | ||
1023 | if (mesh != null) | ||
1024 | { | ||
1025 | m_uniqueReleasedMeshes.Remove(key); | ||
1026 | lock (m_uniqueMeshes) | ||
1027 | m_uniqueMeshes.Add(key, mesh); | ||
1028 | mesh.RefCount = 1; | ||
1029 | return mesh; | ||
1030 | } | ||
1031 | } | ||
1032 | /* | ||
1033 | Mesh UnitSizeMesh = null; | ||
1034 | ulong unitsizekey = 0; | ||
1035 | |||
1036 | unitsizekey = primShape.GetMeshKey(m_MeshUnitSize, lod, convex); | ||
1037 | |||
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 | */ | ||
1008 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); | 1053 | mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); |
1054 | // mesh.Key = unitsizekey; | ||
1009 | 1055 | ||
1010 | if (mesh != null) | 1056 | if (mesh != null) |
1011 | { | 1057 | { |
@@ -1021,11 +1067,68 @@ namespace OpenSim.Region.Physics.Meshing | |||
1021 | 1067 | ||
1022 | // trim the vertex and triangle lists to free up memory | 1068 | // trim the vertex and triangle lists to free up memory |
1023 | mesh.TrimExcess(); | 1069 | mesh.TrimExcess(); |
1070 | mesh.Key = key; | ||
1071 | mesh.RefCount++; | ||
1024 | 1072 | ||
1025 | m_uniqueMeshes.Add(key, mesh); | 1073 | lock(m_uniqueMeshes) |
1074 | m_uniqueMeshes.Add(key, mesh); | ||
1026 | } | 1075 | } |
1027 | 1076 | ||
1028 | return mesh; | 1077 | return mesh; |
1029 | } | 1078 | } |
1079 | |||
1080 | public void ReleaseMesh(IMesh imesh) | ||
1081 | { | ||
1082 | if (imesh == null) | ||
1083 | return; | ||
1084 | |||
1085 | Mesh mesh = (Mesh)imesh; | ||
1086 | |||
1087 | int curRefCount = mesh.RefCount; | ||
1088 | curRefCount--; | ||
1089 | |||
1090 | if (curRefCount > 0) | ||
1091 | { | ||
1092 | mesh.RefCount = curRefCount; | ||
1093 | return; | ||
1094 | } | ||
1095 | |||
1096 | lock (m_uniqueMeshes) | ||
1097 | { | ||
1098 | mesh.RefCount = 0; | ||
1099 | m_uniqueMeshes.Remove(mesh.Key); | ||
1100 | lock (m_uniqueReleasedMeshes) | ||
1101 | m_uniqueReleasedMeshes.Add(mesh.Key, mesh); | ||
1102 | } | ||
1103 | } | ||
1104 | |||
1105 | public void ExpireReleaseMeshs() | ||
1106 | { | ||
1107 | if (m_uniqueMeshes.Count == 0) | ||
1108 | return; | ||
1109 | |||
1110 | List<Mesh> meshstodelete = new List<Mesh>(); | ||
1111 | int refcntr; | ||
1112 | |||
1113 | lock (m_uniqueReleasedMeshes) | ||
1114 | { | ||
1115 | foreach (Mesh m in m_uniqueReleasedMeshes.Values) | ||
1116 | { | ||
1117 | refcntr = m.RefCount; | ||
1118 | refcntr--; | ||
1119 | if (refcntr > -6) | ||
1120 | m.RefCount = refcntr; | ||
1121 | else | ||
1122 | meshstodelete.Add(m); | ||
1123 | } | ||
1124 | |||
1125 | foreach (Mesh m in meshstodelete) | ||
1126 | { | ||
1127 | m_uniqueReleasedMeshes.Remove(m.Key); | ||
1128 | m.releaseSourceMeshData(); | ||
1129 | m.releasePinned(); | ||
1130 | } | ||
1131 | } | ||
1132 | } | ||
1030 | } | 1133 | } |
1031 | } | 1134 | } |