aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs4
-rw-r--r--OpenSim/Region/Physics/Manager/IMesher.cs14
-rw-r--r--OpenSim/Region/Physics/Manager/ZeroMesher.cs2
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Mesh.cs57
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs183
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/SculptMap.cs95
-rw-r--r--OpenSim/Region/Physics/UbitMeshing/SculptMesh.cs440
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs53
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs19
10 files changed, 345 insertions, 524 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index d039111..ae4d52a 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -596,9 +596,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
596 } 596 }
597 break; 597 break;
598 case "R": 598 case "R":
599 Font newFont = new Font(myFont, FontStyle.Regular); 599 Font anewFont = new Font(myFont, FontStyle.Regular);
600 myFont.Dispose(); 600 myFont.Dispose();
601 myFont = newFont; 601 myFont = anewFont;
602 break; 602 break;
603 } 603 }
604 } 604 }
diff --git a/OpenSim/Region/Physics/Manager/IMesher.cs b/OpenSim/Region/Physics/Manager/IMesher.cs
index c32cf38..a8c99f7 100644
--- a/OpenSim/Region/Physics/Manager/IMesher.cs
+++ b/OpenSim/Region/Physics/Manager/IMesher.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Runtime.InteropServices;
30using OpenSim.Framework; 31using OpenSim.Framework;
31using OpenMetaverse; 32using OpenMetaverse;
32 33
@@ -37,6 +38,8 @@ namespace OpenSim.Region.Physics.Manager
37 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); 38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod);
38 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); 39 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
39 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex); 40 IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex);
41 void ReleaseMesh(IMesh mesh);
42 void ExpireReleaseMeshs();
40 } 43 }
41 44
42 // Values for level of detail to be passed to the mesher. 45 // Values for level of detail to be passed to the mesher.
@@ -54,6 +57,17 @@ namespace OpenSim.Region.Physics.Manager
54 { 57 {
55 } 58 }
56 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
57 public interface IMesh 71 public interface IMesh
58 { 72 {
59 List<Vector3> getVertexList(); 73 List<Vector3> getVertexList();
diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
index 8a3b50b..f555cb9 100644
--- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs
+++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
@@ -79,5 +79,7 @@ namespace OpenSim.Region.Physics.Manager
79 79
80 return null; 80 return null;
81 } 81 }
82 public void ReleaseMesh(IMesh mesh) { }
83 public void ExpireReleaseMeshs() { }
82 } 84 }
83} 85}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 825b858..3c4f737 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -763,5 +763,7 @@ namespace OpenSim.Region.Physics.Meshing
763 763
764 return mesh; 764 return mesh;
765 } 765 }
766 public void ReleaseMesh(IMesh imesh) { }
767 public void ExpireReleaseMeshs() { }
766 } 768 }
767} 769}
diff --git a/OpenSim/Region/Physics/UbitMeshing/Mesh.cs b/OpenSim/Region/Physics/UbitMeshing/Mesh.cs
index c715642..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;
@@ -46,8 +47,9 @@ namespace OpenSim.Region.Physics.Meshing
46 IntPtr m_indicesPtr = IntPtr.Zero; 47 IntPtr m_indicesPtr = IntPtr.Zero;
47 int m_indexCount = 0; 48 int m_indexCount = 0;
48 public float[] m_normals; 49 public float[] m_normals;
49 Vector3 _centroid; 50 Vector3 m_centroid;
50 int _centroidDiv; 51 int m_centroidDiv;
52
51 53
52 private class vertexcomp : IEqualityComparer<Vertex> 54 private class vertexcomp : IEqualityComparer<Vertex>
53 { 55 {
@@ -65,7 +67,6 @@ namespace OpenSim.Region.Physics.Meshing
65 int c = v.Z.GetHashCode(); 67 int c = v.Z.GetHashCode();
66 return (a << 16) ^ (b << 8) ^ c; 68 return (a << 16) ^ (b << 8) ^ c;
67 } 69 }
68
69 } 70 }
70 71
71 public Mesh() 72 public Mesh()
@@ -74,8 +75,18 @@ namespace OpenSim.Region.Physics.Meshing
74 75
75 m_vertices = new Dictionary<Vertex, int>(vcomp); 76 m_vertices = new Dictionary<Vertex, int>(vcomp);
76 m_triangles = new List<Triangle>(); 77 m_triangles = new List<Triangle>();
77 _centroid = Vector3.Zero; 78 m_centroid = Vector3.Zero;
78 _centroidDiv = 0; 79 m_centroidDiv = 0;
80 }
81
82 public int RefCount { get; set; }
83
84 public AMeshKey Key { get; set; }
85
86 public void Scale(Vector3 scale)
87 {
88
89
79 } 90 }
80 91
81 public Mesh Clone() 92 public Mesh Clone()
@@ -86,8 +97,8 @@ namespace OpenSim.Region.Physics.Meshing
86 { 97 {
87 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); 98 result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
88 } 99 }
89 result._centroid = _centroid; 100 result.m_centroid = m_centroid;
90 result._centroidDiv = _centroidDiv; 101 result.m_centroidDiv = m_centroidDiv;
91 return result; 102 return result;
92 } 103 }
93 104
@@ -109,41 +120,41 @@ namespace OpenSim.Region.Physics.Meshing
109 120
110 if (m_vertices.Count == 0) 121 if (m_vertices.Count == 0)
111 { 122 {
112 _centroidDiv = 0; 123 m_centroidDiv = 0;
113 _centroid = Vector3.Zero; 124 m_centroid = Vector3.Zero;
114 } 125 }
115 126
116 if (!m_vertices.ContainsKey(triangle.v1)) 127 if (!m_vertices.ContainsKey(triangle.v1))
117 { 128 {
118 m_vertices[triangle.v1] = m_vertices.Count; 129 m_vertices[triangle.v1] = m_vertices.Count;
119 _centroid.X += triangle.v1.X; 130 m_centroid.X += triangle.v1.X;
120 _centroid.Y += triangle.v1.Y; 131 m_centroid.Y += triangle.v1.Y;
121 _centroid.Z += triangle.v1.Z; 132 m_centroid.Z += triangle.v1.Z;
122 _centroidDiv++; 133 m_centroidDiv++;
123 } 134 }
124 if (!m_vertices.ContainsKey(triangle.v2)) 135 if (!m_vertices.ContainsKey(triangle.v2))
125 { 136 {
126 m_vertices[triangle.v2] = m_vertices.Count; 137 m_vertices[triangle.v2] = m_vertices.Count;
127 _centroid.X += triangle.v2.X; 138 m_centroid.X += triangle.v2.X;
128 _centroid.Y += triangle.v2.Y; 139 m_centroid.Y += triangle.v2.Y;
129 _centroid.Z += triangle.v2.Z; 140 m_centroid.Z += triangle.v2.Z;
130 _centroidDiv++; 141 m_centroidDiv++;
131 } 142 }
132 if (!m_vertices.ContainsKey(triangle.v3)) 143 if (!m_vertices.ContainsKey(triangle.v3))
133 { 144 {
134 m_vertices[triangle.v3] = m_vertices.Count; 145 m_vertices[triangle.v3] = m_vertices.Count;
135 _centroid.X += triangle.v3.X; 146 m_centroid.X += triangle.v3.X;
136 _centroid.Y += triangle.v3.Y; 147 m_centroid.Y += triangle.v3.Y;
137 _centroid.Z += triangle.v3.Z; 148 m_centroid.Z += triangle.v3.Z;
138 _centroidDiv++; 149 m_centroidDiv++;
139 } 150 }
140 m_triangles.Add(triangle); 151 m_triangles.Add(triangle);
141 } 152 }
142 153
143 public Vector3 GetCentroid() 154 public Vector3 GetCentroid()
144 { 155 {
145 if (_centroidDiv > 0) 156 if (m_centroidDiv > 0)
146 return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv); 157 return new Vector3(m_centroid.X / m_centroidDiv, m_centroid.Y / m_centroidDiv, m_centroid.Z / m_centroidDiv);
147 else 158 else
148 return Vector3.Zero; 159 return Vector3.Zero;
149 } 160 }
diff --git a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
index f002bba..4c40175 100644
--- a/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/Meshmerizer.cs
@@ -82,7 +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>();
87 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
88 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
86 89
87 public Meshmerizer(IConfigSource config) 90 public Meshmerizer(IConfigSource config)
88 { 91 {
@@ -314,6 +317,9 @@ namespace OpenSim.Region.Physics.Meshing
314 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z)); 317 coords[f.v3].X, coords[f.v3].Y, coords[f.v3].Z));
315 } 318 }
316 319
320 coords.Clear();
321 faces.Clear();
322
317 return mesh; 323 return mesh;
318 } 324 }
319 325
@@ -780,7 +786,9 @@ namespace OpenSim.Region.Physics.Meshing
780 } 786 }
781 787
782 PrimMesher.SculptMesh.SculptType sculptType; 788 PrimMesher.SculptMesh.SculptType sculptType;
783 switch ((OpenMetaverse.SculptType)primShape.SculptType) 789 // remove mirror and invert bits
790 OpenMetaverse.SculptType pbsSculptType = ((OpenMetaverse.SculptType)(primShape.SculptType & 0x3f));
791 switch (pbsSculptType)
784 { 792 {
785 case OpenMetaverse.SculptType.Cylinder: 793 case OpenMetaverse.SculptType.Cylinder:
786 sculptType = PrimMesher.SculptMesh.SculptType.cylinder; 794 sculptType = PrimMesher.SculptMesh.SculptType.cylinder;
@@ -802,7 +810,7 @@ namespace OpenSim.Region.Physics.Meshing
802 bool mirror = ((primShape.SculptType & 128) != 0); 810 bool mirror = ((primShape.SculptType & 128) != 0);
803 bool invert = ((primShape.SculptType & 64) != 0); 811 bool invert = ((primShape.SculptType & 64) != 0);
804 812
805 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); 813 sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, mirror, invert);
806 814
807 idata.Dispose(); 815 idata.Dispose();
808 816
@@ -971,6 +979,76 @@ namespace OpenSim.Region.Physics.Meshing
971 return true; 979 return true;
972 } 980 }
973 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
974 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 1052 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
975 { 1053 {
976 return CreateMesh(primName, primShape, size, lod, false,false); 1054 return CreateMesh(primName, primShape, size, lod, false,false);
@@ -981,6 +1059,8 @@ namespace OpenSim.Region.Physics.Meshing
981 return CreateMesh(primName, primShape, size, lod, false,false); 1059 return CreateMesh(primName, primShape, size, lod, false,false);
982 } 1060 }
983 1061
1062 private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
1063
984 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) 1064 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
985 { 1065 {
986#if SPAM 1066#if SPAM
@@ -988,18 +1068,42 @@ namespace OpenSim.Region.Physics.Meshing
988#endif 1068#endif
989 1069
990 Mesh mesh = null; 1070 Mesh mesh = null;
991 ulong key = 0; 1071// ulong key = 0;
992 1072
993 // If this mesh has been created already, return it instead of creating another copy
994 // For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
995 key = primShape.GetMeshKey(size, lod, convex);
996 if (m_uniqueMeshes.TryGetValue(key, out mesh))
997 return mesh;
998 1073
999 if (size.X < 0.01f) size.X = 0.01f; 1074 if (size.X < 0.01f) size.X = 0.01f;
1000 if (size.Y < 0.01f) size.Y = 0.01f; 1075 if (size.Y < 0.01f) size.Y = 0.01f;
1001 if (size.Z < 0.01f) size.Z = 0.01f; 1076 if (size.Z < 0.01f) size.Z = 0.01f;
1002 1077
1078 // try to find a identical mesh on meshs in use
1079// key = primShape.GetMeshKey(size, lod, convex);
1080 AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
1081
1082 lock (m_uniqueMeshes)
1083 {
1084 m_uniqueMeshes.TryGetValue(key, out mesh);
1085
1086 if (mesh != null)
1087 {
1088 mesh.RefCount++;
1089 return mesh;
1090 }
1091 }
1092
1093 // try to find a identical mesh on meshs recently released
1094 lock (m_uniqueReleasedMeshes)
1095 {
1096 m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
1097 if (mesh != null)
1098 {
1099 m_uniqueReleasedMeshes.Remove(key);
1100 lock (m_uniqueMeshes)
1101 m_uniqueMeshes.Add(key, mesh);
1102 mesh.RefCount = 1;
1103 return mesh;
1104 }
1105 }
1106
1003 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); 1107 mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
1004 1108
1005 if (mesh != null) 1109 if (mesh != null)
@@ -1016,11 +1120,68 @@ namespace OpenSim.Region.Physics.Meshing
1016 1120
1017 // trim the vertex and triangle lists to free up memory 1121 // trim the vertex and triangle lists to free up memory
1018 mesh.TrimExcess(); 1122 mesh.TrimExcess();
1123 mesh.Key = key;
1124 mesh.RefCount = 1;
1019 1125
1020 m_uniqueMeshes.Add(key, mesh); 1126 lock(m_uniqueMeshes)
1127 m_uniqueMeshes.Add(key, mesh);
1021 } 1128 }
1022 1129
1023 return mesh; 1130 return mesh;
1024 } 1131 }
1132
1133 public void ReleaseMesh(IMesh imesh)
1134 {
1135 if (imesh == null)
1136 return;
1137
1138 Mesh mesh = (Mesh)imesh;
1139
1140 int curRefCount = mesh.RefCount;
1141 curRefCount--;
1142
1143 if (curRefCount > 0)
1144 {
1145 mesh.RefCount = curRefCount;
1146 return;
1147 }
1148
1149 lock (m_uniqueMeshes)
1150 {
1151 mesh.RefCount = 0;
1152 m_uniqueMeshes.Remove(mesh.Key);
1153 lock (m_uniqueReleasedMeshes)
1154 m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
1155 }
1156 }
1157
1158 public void ExpireReleaseMeshs()
1159 {
1160 if (m_uniqueReleasedMeshes.Count == 0)
1161 return;
1162
1163 List<Mesh> meshstodelete = new List<Mesh>();
1164 int refcntr;
1165
1166 lock (m_uniqueReleasedMeshes)
1167 {
1168 foreach (Mesh m in m_uniqueReleasedMeshes.Values)
1169 {
1170 refcntr = m.RefCount;
1171 refcntr--;
1172 if (refcntr > -6)
1173 m.RefCount = refcntr;
1174 else
1175 meshstodelete.Add(m);
1176 }
1177
1178 foreach (Mesh m in meshstodelete)
1179 {
1180 m_uniqueReleasedMeshes.Remove(m.Key);
1181 m.releaseSourceMeshData();
1182 m.releasePinned();
1183 }
1184 }
1185 }
1025 } 1186 }
1026} 1187}
diff --git a/OpenSim/Region/Physics/UbitMeshing/SculptMap.cs b/OpenSim/Region/Physics/UbitMeshing/SculptMap.cs
index b3d9cb6..1c75db6 100644
--- a/OpenSim/Region/Physics/UbitMeshing/SculptMap.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/SculptMap.cs
@@ -25,14 +25,10 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28// to build without references to System.Drawing, comment this out
29#define SYSTEM_DRAWING
30
31using System; 28using System;
32using System.Collections.Generic; 29using System.Collections.Generic;
33using System.Text; 30using System.Text;
34 31
35#if SYSTEM_DRAWING
36using System.Drawing; 32using System.Drawing;
37using System.Drawing.Imaging; 33using System.Drawing.Imaging;
38 34
@@ -60,11 +56,12 @@ namespace PrimMesher
60 56
61 int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image 57 int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
62 58
63 bool smallMap = bmW * bmH <= numLodPixels;
64 bool needsScaling = false; 59 bool needsScaling = false;
60 bool smallMap = false;
65 61
66 width = bmW; 62 width = bmW;
67 height = bmH; 63 height = bmH;
64
68 while (width * height > numLodPixels * 4) 65 while (width * height > numLodPixels * 4)
69 { 66 {
70 width >>= 1; 67 width >>= 1;
@@ -85,9 +82,12 @@ namespace PrimMesher
85 82
86 if (width * height > numLodPixels) 83 if (width * height > numLodPixels)
87 { 84 {
85 smallMap = false;
88 width >>= 1; 86 width >>= 1;
89 height >>= 1; 87 height >>= 1;
90 } 88 }
89 else
90 smallMap = true;
91 91
92 int numBytes = (width + 1) * (height + 1); 92 int numBytes = (width + 1) * (height + 1);
93 redBytes = new byte[numBytes]; 93 redBytes = new byte[numBytes];
@@ -95,21 +95,18 @@ namespace PrimMesher
95 blueBytes = new byte[numBytes]; 95 blueBytes = new byte[numBytes];
96 96
97 int byteNdx = 0; 97 int byteNdx = 0;
98 Color c;
98 99
99 try 100 try
100 { 101 {
101 for (int y = 0; y <= height; y++) 102 for (int y = 0; y <= height; y++)
102 { 103 {
103 for (int x = 0; x <= width; x++) 104 for (int x = 0; x < width; x++)
104 { 105 {
105 Color c;
106
107 if (smallMap) 106 if (smallMap)
108 c = bm.GetPixel(x < width ? x : x - 1, 107 c = bm.GetPixel(x, y < height ? y : y - 1);
109 y < height ? y : y - 1);
110 else 108 else
111 c = bm.GetPixel(x < width ? x * 2 : x * 2 - 1, 109 c = bm.GetPixel(x * 2, y < height ? y * 2 : y * 2 - 1);
112 y < height ? y * 2 : y * 2 - 1);
113 110
114 redBytes[byteNdx] = c.R; 111 redBytes[byteNdx] = c.R;
115 greenBytes[byteNdx] = c.G; 112 greenBytes[byteNdx] = c.G;
@@ -117,6 +114,17 @@ namespace PrimMesher
117 114
118 ++byteNdx; 115 ++byteNdx;
119 } 116 }
117
118 if (smallMap)
119 c = bm.GetPixel(width - 1, y < height ? y : y - 1);
120 else
121 c = bm.GetPixel(width * 2 - 1, y < height ? y * 2 : y * 2 - 1);
122
123 redBytes[byteNdx] = c.R;
124 greenBytes[byteNdx] = c.G;
125 blueBytes[byteNdx] = c.B;
126
127 ++byteNdx;
120 } 128 }
121 } 129 }
122 catch (Exception e) 130 catch (Exception e)
@@ -140,7 +148,6 @@ namespace PrimMesher
140 int rowNdx, colNdx; 148 int rowNdx, colNdx;
141 int smNdx = 0; 149 int smNdx = 0;
142 150
143
144 for (rowNdx = 0; rowNdx < numRows; rowNdx++) 151 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
145 { 152 {
146 List<Coord> row = new List<Coord>(numCols); 153 List<Coord> row = new List<Coord>(numCols);
@@ -163,16 +170,27 @@ namespace PrimMesher
163 { 170 {
164 171
165 Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb); 172 Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
166 173
167 Color c; 174 Color c;
168 float xscale = srcImage.Width / destWidth;
169 float yscale = srcImage.Height / destHeight;
170 175
176
177 // will let last step to be eventually diferent, as seems to be in sl
178
179 float xscale = (float)srcImage.Width / (float)destWidth;
180 float yscale = (float)srcImage.Height / (float)destHeight;
181
182 int lastsx = srcImage.Width - 1;
183 int lastsy = srcImage.Height - 1;
184 int lastdx = destWidth - 1;
185 int lastdy = destHeight - 1;
186
171 float sy = 0.5f; 187 float sy = 0.5f;
172 for (int y = 0; y < destHeight; y++) 188 float sx;
189
190 for (int y = 0; y < lastdy; y++)
173 { 191 {
174 float sx = 0.5f; 192 sx = 0.5f;
175 for (int x = 0; x < destWidth; x++) 193 for (int x = 0; x < lastdx; x++)
176 { 194 {
177 try 195 try
178 { 196 {
@@ -182,16 +200,45 @@ namespace PrimMesher
182 catch (IndexOutOfRangeException) 200 catch (IndexOutOfRangeException)
183 { 201 {
184 } 202 }
185
186 sx += xscale; 203 sx += xscale;
187 } 204 }
205 try
206 {
207 c = srcImage.GetPixel(lastsx, (int)(sy));
208 scaledImage.SetPixel(lastdx, y, Color.FromArgb(c.R, c.G, c.B));
209 }
210 catch (IndexOutOfRangeException)
211 {
212 }
213
188 sy += yscale; 214 sy += yscale;
189 } 215 }
216
217 sx = 0.5f;
218 for (int x = 0; x < lastdx; x++)
219 {
220 try
221 {
222 c = srcImage.GetPixel((int)(sx), lastsy);
223 scaledImage.SetPixel(x, lastdy, Color.FromArgb(c.R, c.G, c.B));
224 }
225 catch (IndexOutOfRangeException)
226 {
227 }
228
229 sx += xscale;
230 }
231 try
232 {
233 c = srcImage.GetPixel(lastsx, lastsy);
234 scaledImage.SetPixel(lastdx, lastdy, Color.FromArgb(c.R, c.G, c.B));
235 }
236 catch (IndexOutOfRangeException)
237 {
238 }
239
190 srcImage.Dispose(); 240 srcImage.Dispose();
191 return scaledImage; 241 return scaledImage;
192 } 242 }
193
194 }
195
196 } 243 }
197#endif 244} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitMeshing/SculptMesh.cs b/OpenSim/Region/Physics/UbitMeshing/SculptMesh.cs
index 4a7f3ad..bc1375b 100644
--- a/OpenSim/Region/Physics/UbitMeshing/SculptMesh.cs
+++ b/OpenSim/Region/Physics/UbitMeshing/SculptMesh.cs
@@ -25,18 +25,13 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28// to build without references to System.Drawing, comment this out
29#define SYSTEM_DRAWING
30
31using System; 28using System;
32using System.Collections.Generic; 29using System.Collections.Generic;
33using System.Text; 30using System.Text;
34using System.IO; 31using System.IO;
35 32
36#if SYSTEM_DRAWING
37using System.Drawing; 33using System.Drawing;
38using System.Drawing.Imaging; 34using System.Drawing.Imaging;
39#endif
40 35
41namespace PrimMesher 36namespace PrimMesher
42{ 37{
@@ -46,274 +41,28 @@ namespace PrimMesher
46 public List<Coord> coords; 41 public List<Coord> coords;
47 public List<Face> faces; 42 public List<Face> faces;
48 43
49 public List<ViewerFace> viewerFaces;
50 public List<Coord> normals;
51 public List<UVCoord> uvs;
52
53 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 }; 44 public enum SculptType { sphere = 1, torus = 2, plane = 3, cylinder = 4 };
54 45
55#if SYSTEM_DRAWING
56
57 public SculptMesh SculptMeshFromFile(string fileName, SculptType sculptType, int lod, bool viewerMode)
58 {
59 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
60 SculptMesh sculptMesh = new SculptMesh(bitmap, sculptType, lod, viewerMode);
61 bitmap.Dispose();
62 return sculptMesh;
63 }
64
65
66 public SculptMesh(string fileName, int sculptType, int lod, int viewerMode, int mirror, int invert)
67 {
68 Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
69 _SculptMesh(bitmap, (SculptType)sculptType, lod, viewerMode != 0, mirror != 0, invert != 0);
70 bitmap.Dispose();
71 }
72#endif
73
74 /// <summary>
75 /// ** Experimental ** May disappear from future versions ** not recommeneded for use in applications
76 /// Construct a sculpt mesh from a 2D array of floats
77 /// </summary>
78 /// <param name="zMap"></param>
79 /// <param name="xBegin"></param>
80 /// <param name="xEnd"></param>
81 /// <param name="yBegin"></param>
82 /// <param name="yEnd"></param>
83 /// <param name="viewerMode"></param>
84 public SculptMesh(float[,] zMap, float xBegin, float xEnd, float yBegin, float yEnd, bool viewerMode)
85 {
86 float xStep, yStep;
87 float uStep, vStep;
88
89 int numYElements = zMap.GetLength(0);
90 int numXElements = zMap.GetLength(1);
91
92 try
93 {
94 xStep = (xEnd - xBegin) / (float)(numXElements - 1);
95 yStep = (yEnd - yBegin) / (float)(numYElements - 1);
96
97 uStep = 1.0f / (numXElements - 1);
98 vStep = 1.0f / (numYElements - 1);
99 }
100 catch (DivideByZeroException)
101 {
102 return;
103 }
104
105 coords = new List<Coord>();
106 faces = new List<Face>();
107 normals = new List<Coord>();
108 uvs = new List<UVCoord>();
109
110 viewerFaces = new List<ViewerFace>();
111
112 int p1, p2, p3, p4;
113
114 int x, y;
115 int xStart = 0, yStart = 0;
116
117 for (y = yStart; y < numYElements; y++)
118 {
119 int rowOffset = y * numXElements;
120
121 for (x = xStart; x < numXElements; x++)
122 {
123 /*
124 * p1-----p2
125 * | \ f2 |
126 * | \ |
127 * | f1 \|
128 * p3-----p4
129 */
130
131 p4 = rowOffset + x;
132 p3 = p4 - 1;
133
134 p2 = p4 - numXElements;
135 p1 = p3 - numXElements;
136
137 Coord c = new Coord(xBegin + x * xStep, yBegin + y * yStep, zMap[y, x]);
138 this.coords.Add(c);
139 if (viewerMode)
140 {
141 this.normals.Add(new Coord());
142 this.uvs.Add(new UVCoord(uStep * x, 1.0f - vStep * y));
143 }
144
145 if (y > 0 && x > 0)
146 {
147 Face f1, f2;
148
149 if (viewerMode)
150 {
151 f1 = new Face(p1, p4, p3, p1, p4, p3);
152 f1.uv1 = p1;
153 f1.uv2 = p4;
154 f1.uv3 = p3;
155
156 f2 = new Face(p1, p2, p4, p1, p2, p4);
157 f2.uv1 = p1;
158 f2.uv2 = p2;
159 f2.uv3 = p4;
160 }
161 else
162 {
163 f1 = new Face(p1, p4, p3);
164 f2 = new Face(p1, p2, p4);
165 }
166
167 this.faces.Add(f1);
168 this.faces.Add(f2);
169 }
170 }
171 }
172
173 if (viewerMode)
174 calcVertexNormals(SculptType.plane, numXElements, numYElements);
175 }
176
177#if SYSTEM_DRAWING
178 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode)
179 {
180 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, false, false);
181 }
182 46
183 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) 47 public SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool mirror, bool invert)
184 { 48 {
185 _SculptMesh(sculptBitmap, sculptType, lod, viewerMode, mirror, invert); 49 if (mirror)
186 } 50 invert = !invert;
187#endif
188
189 public SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert)
190 {
191 _SculptMesh(rows, sculptType, viewerMode, mirror, invert);
192 }
193
194#if SYSTEM_DRAWING
195 /// <summary>
196 /// converts a bitmap to a list of lists of coords, while scaling the image.
197 /// the scaling is done in floating point so as to allow for reduced vertex position
198 /// quantization as the position will be averaged between pixel values. this routine will
199 /// likely fail if the bitmap width and height are not powers of 2.
200 /// </summary>
201 /// <param name="bitmap"></param>
202 /// <param name="scale"></param>
203 /// <param name="mirror"></param>
204 /// <returns></returns>
205 private List<List<Coord>> bitmap2Coords(Bitmap bitmap, int scale, bool mirror)
206 {
207 int numRows = bitmap.Height / scale;
208 int numCols = bitmap.Width / scale;
209 List<List<Coord>> rows = new List<List<Coord>>(numRows);
210
211 float pixScale = 1.0f / (scale * scale);
212 pixScale /= 255;
213
214 int imageX, imageY = 0;
215
216 int rowNdx, colNdx;
217
218 for (rowNdx = 0; rowNdx < numRows; rowNdx++)
219 {
220 List<Coord> row = new List<Coord>(numCols);
221 for (colNdx = 0; colNdx < numCols; colNdx++)
222 {
223 imageX = colNdx * scale;
224 int imageYStart = rowNdx * scale;
225 int imageYEnd = imageYStart + scale;
226 int imageXEnd = imageX + scale;
227 float rSum = 0.0f;
228 float gSum = 0.0f;
229 float bSum = 0.0f;
230 for (; imageX < imageXEnd; imageX++)
231 {
232 for (imageY = imageYStart; imageY < imageYEnd; imageY++)
233 {
234 Color c = bitmap.GetPixel(imageX, imageY);
235 if (c.A != 255)
236 {
237 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
238 c = bitmap.GetPixel(imageX, imageY);
239 }
240 rSum += c.R;
241 gSum += c.G;
242 bSum += c.B;
243 }
244 }
245 if (mirror)
246 row.Add(new Coord(-(rSum * pixScale - 0.5f), gSum * pixScale - 0.5f, bSum * pixScale - 0.5f));
247 else
248 row.Add(new Coord(rSum * pixScale - 0.5f, gSum * pixScale - 0.5f, bSum * pixScale - 0.5f));
249
250 }
251 rows.Add(row);
252 }
253 return rows;
254 }
255
256 private List<List<Coord>> bitmap2CoordsSampled(Bitmap bitmap, int scale, bool mirror)
257 {
258 int numRows = bitmap.Height / scale;
259 int numCols = bitmap.Width / scale;
260 List<List<Coord>> rows = new List<List<Coord>>(numRows);
261
262 float pixScale = 1.0f / 256.0f;
263
264 int imageX, imageY = 0;
265
266 int rowNdx, colNdx;
267
268 for (rowNdx = 0; rowNdx <= numRows; rowNdx++)
269 {
270 List<Coord> row = new List<Coord>(numCols);
271 imageY = rowNdx * scale;
272 if (rowNdx == numRows) imageY--;
273 for (colNdx = 0; colNdx <= numCols; colNdx++)
274 {
275 imageX = colNdx * scale;
276 if (colNdx == numCols) imageX--;
277
278 Color c = bitmap.GetPixel(imageX, imageY);
279 if (c.A != 255)
280 {
281 bitmap.SetPixel(imageX, imageY, Color.FromArgb(255, c.R, c.G, c.B));
282 c = bitmap.GetPixel(imageX, imageY);
283 }
284
285 if (mirror)
286 row.Add(new Coord(-(c.R * pixScale - 0.5f), c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
287 else
288 row.Add(new Coord(c.R * pixScale - 0.5f, c.G * pixScale - 0.5f, c.B * pixScale - 0.5f));
289 51
290 } 52 SculptMap smap = new SculptMap(sculptBitmap, lod);
291 rows.Add(row);
292 }
293 return rows;
294 }
295 53
54 List<List<Coord>> rows = smap.ToRows(mirror);
296 55
297 void _SculptMesh(Bitmap sculptBitmap, SculptType sculptType, int lod, bool viewerMode, bool mirror, bool invert) 56 _SculptMesh(rows, sculptType, invert);
298 {
299 _SculptMesh(new SculptMap(sculptBitmap, lod).ToRows(mirror), sculptType, viewerMode, mirror, invert);
300 } 57 }
301#endif
302 58
303 void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool viewerMode, bool mirror, bool invert) 59 private void _SculptMesh(List<List<Coord>> rows, SculptType sculptType, bool invert)
304 { 60 {
305 coords = new List<Coord>(); 61 coords = new List<Coord>();
306 faces = new List<Face>(); 62 faces = new List<Face>();
307 normals = new List<Coord>();
308 uvs = new List<UVCoord>();
309 63
310 sculptType = (SculptType)(((int)sculptType) & 0x07); 64 sculptType = (SculptType)(((int)sculptType) & 0x07);
311 65
312 if (mirror)
313 invert = !invert;
314
315 viewerFaces = new List<ViewerFace>();
316
317 int width = rows[0].Count; 66 int width = rows[0].Count;
318 67
319 int p1, p2, p3, p4; 68 int p1, p2, p3, p4;
@@ -375,7 +124,6 @@ namespace PrimMesher
375 124
376 int coordsDown = rows.Count; 125 int coordsDown = rows.Count;
377 int coordsAcross = rows[0].Count; 126 int coordsAcross = rows[0].Count;
378// int lastColumn = coordsAcross - 1;
379 127
380 float widthUnit = 1.0f / (coordsAcross - 1); 128 float widthUnit = 1.0f / (coordsAcross - 1);
381 float heightUnit = 1.0f / (coordsDown - 1); 129 float heightUnit = 1.0f / (coordsDown - 1);
@@ -401,45 +149,11 @@ namespace PrimMesher
401 p1 = p3 - coordsAcross; 149 p1 = p3 - coordsAcross;
402 150
403 this.coords.Add(rows[imageY][imageX]); 151 this.coords.Add(rows[imageY][imageX]);
404 if (viewerMode)
405 {
406 this.normals.Add(new Coord());
407 this.uvs.Add(new UVCoord(widthUnit * imageX, heightUnit * imageY));
408 }
409 152
410 if (imageY > 0 && imageX > 0) 153 if (imageY > 0 && imageX > 0)
411 { 154 {
412 Face f1, f2; 155 Face f1, f2;
413 156
414 if (viewerMode)
415 {
416 if (invert)
417 {
418 f1 = new Face(p1, p4, p3, p1, p4, p3);
419 f1.uv1 = p1;
420 f1.uv2 = p4;
421 f1.uv3 = p3;
422
423 f2 = new Face(p1, p2, p4, p1, p2, p4);
424 f2.uv1 = p1;
425 f2.uv2 = p2;
426 f2.uv3 = p4;
427 }
428 else
429 {
430 f1 = new Face(p1, p3, p4, p1, p3, p4);
431 f1.uv1 = p1;
432 f1.uv2 = p3;
433 f1.uv3 = p4;
434
435 f2 = new Face(p1, p4, p2, p1, p4, p2);
436 f2.uv1 = p1;
437 f2.uv2 = p4;
438 f2.uv3 = p2;
439 }
440 }
441 else
442 {
443 if (invert) 157 if (invert)
444 { 158 {
445 f1 = new Face(p1, p4, p3); 159 f1 = new Face(p1, p4, p3);
@@ -450,16 +164,12 @@ namespace PrimMesher
450 f1 = new Face(p1, p3, p4); 164 f1 = new Face(p1, p3, p4);
451 f2 = new Face(p1, p4, p2); 165 f2 = new Face(p1, p4, p2);
452 } 166 }
453 }
454 167
455 this.faces.Add(f1); 168 this.faces.Add(f1);
456 this.faces.Add(f2); 169 this.faces.Add(f2);
457 } 170 }
458 } 171 }
459 } 172 }
460
461 if (viewerMode)
462 calcVertexNormals(sculptType, coordsAcross, coordsDown);
463 } 173 }
464 174
465 /// <summary> 175 /// <summary>
@@ -475,129 +185,6 @@ namespace PrimMesher
475 { 185 {
476 coords = new List<Coord>(sm.coords); 186 coords = new List<Coord>(sm.coords);
477 faces = new List<Face>(sm.faces); 187 faces = new List<Face>(sm.faces);
478 viewerFaces = new List<ViewerFace>(sm.viewerFaces);
479 normals = new List<Coord>(sm.normals);
480 uvs = new List<UVCoord>(sm.uvs);
481 }
482
483 private void calcVertexNormals(SculptType sculptType, int xSize, int ySize)
484 { // compute vertex normals by summing all the surface normals of all the triangles sharing
485 // each vertex and then normalizing
486 int numFaces = this.faces.Count;
487 for (int i = 0; i < numFaces; i++)
488 {
489 Face face = this.faces[i];
490 Coord surfaceNormal = face.SurfaceNormal(this.coords);
491 this.normals[face.n1] += surfaceNormal;
492 this.normals[face.n2] += surfaceNormal;
493 this.normals[face.n3] += surfaceNormal;
494 }
495
496 int numNormals = this.normals.Count;
497 for (int i = 0; i < numNormals; i++)
498 this.normals[i] = this.normals[i].Normalize();
499
500 if (sculptType != SculptType.plane)
501 { // blend the vertex normals at the cylinder seam
502 for (int y = 0; y < ySize; y++)
503 {
504 int rowOffset = y * xSize;
505
506 this.normals[rowOffset] = this.normals[rowOffset + xSize - 1] = (this.normals[rowOffset] + this.normals[rowOffset + xSize - 1]).Normalize();
507 }
508 }
509
510 foreach (Face face in this.faces)
511 {
512 ViewerFace vf = new ViewerFace(0);
513 vf.v1 = this.coords[face.v1];
514 vf.v2 = this.coords[face.v2];
515 vf.v3 = this.coords[face.v3];
516
517 vf.coordIndex1 = face.v1;
518 vf.coordIndex2 = face.v2;
519 vf.coordIndex3 = face.v3;
520
521 vf.n1 = this.normals[face.n1];
522 vf.n2 = this.normals[face.n2];
523 vf.n3 = this.normals[face.n3];
524
525 vf.uv1 = this.uvs[face.uv1];
526 vf.uv2 = this.uvs[face.uv2];
527 vf.uv3 = this.uvs[face.uv3];
528
529 this.viewerFaces.Add(vf);
530 }
531 }
532
533 /// <summary>
534 /// Adds a value to each XYZ vertex coordinate in the mesh
535 /// </summary>
536 /// <param name="x"></param>
537 /// <param name="y"></param>
538 /// <param name="z"></param>
539 public void AddPos(float x, float y, float z)
540 {
541 int i;
542 int numVerts = this.coords.Count;
543 Coord vert;
544
545 for (i = 0; i < numVerts; i++)
546 {
547 vert = this.coords[i];
548 vert.X += x;
549 vert.Y += y;
550 vert.Z += z;
551 this.coords[i] = vert;
552 }
553
554 if (this.viewerFaces != null)
555 {
556 int numViewerFaces = this.viewerFaces.Count;
557
558 for (i = 0; i < numViewerFaces; i++)
559 {
560 ViewerFace v = this.viewerFaces[i];
561 v.AddPos(x, y, z);
562 this.viewerFaces[i] = v;
563 }
564 }
565 }
566
567 /// <summary>
568 /// Rotates the mesh
569 /// </summary>
570 /// <param name="q"></param>
571 public void AddRot(Quat q)
572 {
573 int i;
574 int numVerts = this.coords.Count;
575
576 for (i = 0; i < numVerts; i++)
577 this.coords[i] *= q;
578
579 int numNormals = this.normals.Count;
580 for (i = 0; i < numNormals; i++)
581 this.normals[i] *= q;
582
583 if (this.viewerFaces != null)
584 {
585 int numViewerFaces = this.viewerFaces.Count;
586
587 for (i = 0; i < numViewerFaces; i++)
588 {
589 ViewerFace v = this.viewerFaces[i];
590 v.v1 *= q;
591 v.v2 *= q;
592 v.v3 *= q;
593
594 v.n1 *= q;
595 v.n2 *= q;
596 v.n3 *= q;
597
598 this.viewerFaces[i] = v;
599 }
600 }
601 } 188 }
602 189
603 public void Scale(float x, float y, float z) 190 public void Scale(float x, float y, float z)
@@ -608,19 +195,6 @@ namespace PrimMesher
608 Coord m = new Coord(x, y, z); 195 Coord m = new Coord(x, y, z);
609 for (i = 0; i < numVerts; i++) 196 for (i = 0; i < numVerts; i++)
610 this.coords[i] *= m; 197 this.coords[i] *= m;
611
612 if (this.viewerFaces != null)
613 {
614 int numViewerFaces = this.viewerFaces.Count;
615 for (i = 0; i < numViewerFaces; i++)
616 {
617 ViewerFace v = this.viewerFaces[i];
618 v.v1 *= m;
619 v.v2 *= m;
620 v.v3 *= m;
621 this.viewerFaces[i] = v;
622 }
623 }
624 } 198 }
625 199
626 public void DumpRaw(String path, String name, String title) 200 public void DumpRaw(String path, String name, String title)
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
index 6bf5be1..fbc6134 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODEPrim.cs
@@ -57,7 +57,6 @@ using OdeAPI;
57using OpenSim.Framework; 57using OpenSim.Framework;
58using OpenSim.Region.Physics.Manager; 58using OpenSim.Region.Physics.Manager;
59 59
60
61namespace OpenSim.Region.Physics.OdePlugin 60namespace OpenSim.Region.Physics.OdePlugin
62{ 61{
63 public class OdePrim : PhysicsActor 62 public class OdePrim : PhysicsActor
@@ -538,24 +537,6 @@ namespace OpenSim.Region.Physics.OdePlugin
538 { 537 {
539 set 538 set
540 { 539 {
541/*
542 IMesh mesh = null;
543 if (_parent_scene.needsMeshing(value))
544 {
545 bool convex;
546 if (m_shapetype == 0)
547 convex = false;
548 else
549 convex = true;
550 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex);
551 }
552
553 if (mesh != null)
554 {
555 lock (m_meshlock)
556 m_mesh = mesh;
557 }
558*/
559 AddChange(changes.Shape, value); 540 AddChange(changes.Shape, value);
560 } 541 }
561 } 542 }
@@ -1092,18 +1073,21 @@ namespace OpenSim.Region.Physics.OdePlugin
1092 CalcPrimBodyData(); 1073 CalcPrimBodyData();
1093 1074
1094 m_mesh = null; 1075 m_mesh = null;
1095 if (_parent_scene.needsMeshing(pbs)) 1076 if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0))
1096 { 1077 {
1097 bool convex; 1078 bool convex;
1079 int clod = (int)LevelOfDetail.High;
1098 if (m_shapetype == 0) 1080 if (m_shapetype == 0)
1099 convex = false; 1081 convex = false;
1100 else 1082 else
1083 {
1101 convex = true; 1084 convex = true;
1102 1085 if (_pbs.SculptType != (byte)SculptType.Mesh)
1103 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex); 1086 clod = (int)LevelOfDetail.Low;
1087 }
1088 m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1104 } 1089 }
1105 1090
1106
1107 m_building = true; // control must set this to false when done 1091 m_building = true; // control must set this to false when done
1108 1092
1109 AddChange(changes.Add, null); 1093 AddChange(changes.Add, null);
@@ -1354,18 +1338,23 @@ namespace OpenSim.Region.Physics.OdePlugin
1354 1338
1355 IMesh mesh = null; 1339 IMesh mesh = null;
1356 1340
1357
1358 lock (m_meshlock) 1341 lock (m_meshlock)
1359 { 1342 {
1360 if (m_mesh == null) 1343 if (m_mesh == null)
1361 { 1344 {
1362 bool convex; 1345 bool convex;
1346 int clod = (int)LevelOfDetail.High;
1347
1363 if (m_shapetype == 0) 1348 if (m_shapetype == 0)
1364 convex = false; 1349 convex = false;
1365 else 1350 else
1351 {
1366 convex = true; 1352 convex = true;
1353 if (_pbs.SculptType != (byte)SculptType.Mesh)
1354 clod = (int)LevelOfDetail.Low;
1355 }
1367 1356
1368 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex); 1357 mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
1369 } 1358 }
1370 else 1359 else
1371 { 1360 {
@@ -1373,7 +1362,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1373 } 1362 }
1374 1363
1375 if (mesh == null) 1364 if (mesh == null)
1376 { 1365 {
1377 m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z); 1366 m_log.WarnFormat("[PHYSICS]: CreateMesh Failed on prim {0} at <{1},{2},{3}>.", Name, _position.X, _position.Y, _position.Z);
1378 return false; 1367 return false;
1379 } 1368 }
@@ -1394,7 +1383,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1394 hasOOBoffsetFromMesh = true; 1383 hasOOBoffsetFromMesh = true;
1395 1384
1396 mesh.releaseSourceMeshData(); 1385 mesh.releaseSourceMeshData();
1397 m_mesh = null; 1386 m_mesh = mesh;
1398 } 1387 }
1399 1388
1400 IntPtr geo = IntPtr.Zero; 1389 IntPtr geo = IntPtr.Zero;
@@ -1536,7 +1525,10 @@ namespace OpenSim.Region.Physics.OdePlugin
1536 d.GeomTriMeshDataDestroy(_triMeshData); 1525 d.GeomTriMeshDataDestroy(_triMeshData);
1537 _triMeshData = IntPtr.Zero; 1526 _triMeshData = IntPtr.Zero;
1538 } 1527 }
1528
1539 } 1529 }
1530
1531
1540 // catch (System.AccessViolationException) 1532 // catch (System.AccessViolationException)
1541 catch (Exception e) 1533 catch (Exception e)
1542 { 1534 {
@@ -1550,6 +1542,13 @@ namespace OpenSim.Region.Physics.OdePlugin
1550 { 1542 {
1551 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); 1543 m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
1552 } 1544 }
1545
1546 if (m_mesh != null)
1547 {
1548 _parent_scene.mesher.ReleaseMesh(m_mesh);
1549 m_mesh = null;
1550 }
1551
1553 Body = IntPtr.Zero; 1552 Body = IntPtr.Zero;
1554 hasOOBoffsetFromMesh = false; 1553 hasOOBoffsetFromMesh = false;
1555 } 1554 }
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index f3ac3ca..3ee5198 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -194,7 +194,8 @@ namespace OpenSim.Region.Physics.OdePlugin
194 private float metersInSpace = 25.6f; 194 private float metersInSpace = 25.6f;
195 private float m_timeDilation = 1.0f; 195 private float m_timeDilation = 1.0f;
196 196
197 DateTime m_lastframe; 197 private DateTime m_lastframe;
198 private DateTime m_lastMeshExpire;
198 199
199 public float gravityx = 0f; 200 public float gravityx = 0f;
200 public float gravityy = 0f; 201 public float gravityy = 0f;
@@ -203,6 +204,8 @@ namespace OpenSim.Region.Physics.OdePlugin
203 private float waterlevel = 0f; 204 private float waterlevel = 0f;
204 private int framecount = 0; 205 private int framecount = 0;
205 206
207 private int m_meshExpireCntr;
208
206// private IntPtr WaterGeom = IntPtr.Zero; 209// private IntPtr WaterGeom = IntPtr.Zero;
207// private IntPtr WaterHeightmapData = IntPtr.Zero; 210// private IntPtr WaterHeightmapData = IntPtr.Zero;
208// private GCHandle WaterMapHandler = new GCHandle(); 211// private GCHandle WaterMapHandler = new GCHandle();
@@ -263,7 +266,6 @@ namespace OpenSim.Region.Physics.OdePlugin
263 const int maxContactsbeforedeath = 4000; 266 const int maxContactsbeforedeath = 4000;
264 private volatile int m_global_contactcount = 0; 267 private volatile int m_global_contactcount = 0;
265 268
266
267 private IntPtr contactgroup; 269 private IntPtr contactgroup;
268 270
269 public ContactData[] m_materialContactsData = new ContactData[8]; 271 public ContactData[] m_materialContactsData = new ContactData[8];
@@ -594,6 +596,7 @@ namespace OpenSim.Region.Physics.OdePlugin
594 } 596 }
595 597
596 m_lastframe = DateTime.UtcNow; 598 m_lastframe = DateTime.UtcNow;
599 m_lastMeshExpire = m_lastframe;
597 } 600 }
598 601
599 internal void waitForSpaceUnlock(IntPtr space) 602 internal void waitForSpaceUnlock(IntPtr space)
@@ -1768,9 +1771,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1768 { 1771 {
1769 1772
1770 DateTime now = DateTime.UtcNow; 1773 DateTime now = DateTime.UtcNow;
1771 TimeSpan SinceLastFrame = now - m_lastframe; 1774 TimeSpan timedif = now - m_lastframe;
1772 m_lastframe = now; 1775 m_lastframe = now;
1773 timeStep = (float)SinceLastFrame.TotalSeconds; 1776 timeStep = (float)timedif.TotalSeconds;
1774 1777
1775 // acumulate time so we can reduce error 1778 // acumulate time so we can reduce error
1776 step_time += timeStep; 1779 step_time += timeStep;
@@ -1972,6 +1975,14 @@ namespace OpenSim.Region.Physics.OdePlugin
1972 _badCharacter.Clear(); 1975 _badCharacter.Clear();
1973 } 1976 }
1974 } 1977 }
1978
1979 timedif = now - m_lastMeshExpire;
1980
1981 if (timedif.Seconds > 10)
1982 {
1983 mesher.ExpireReleaseMeshs();
1984 m_lastMeshExpire = now;
1985 }
1975/* 1986/*
1976 int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); 1987 int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
1977 int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); 1988 int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);