aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs24
-rw-r--r--OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs39
-rw-r--r--OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs8
-rw-r--r--OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs392
5 files changed, 249 insertions, 216 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
index 42fc11b..f72ad28 100755
--- a/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
+++ b/OpenSim/Region/PhysicsModules/BulletS/BSTerrainHeightmap.cs
@@ -141,14 +141,30 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
141 } 141 }
142 142
143 // The passed position is relative to the base of the region. 143 // The passed position is relative to the base of the region.
144 // There are many assumptions herein that the heightmap increment is 1.
144 public override float GetTerrainHeightAtXYZ(Vector3 pos) 145 public override float GetTerrainHeightAtXYZ(Vector3 pos)
145 { 146 {
146 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET; 147 float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
147 148
148 int mapIndex = (int)pos.Y * (int)m_mapInfo.sizeY + (int)pos.X; 149 try {
149 try 150 int baseX = (int)pos.X;
150 { 151 int baseY = (int)pos.Y;
151 ret = m_mapInfo.heightMap[mapIndex]; 152 int maxX = (int)m_mapInfo.sizeX;
153 int maxY = (int)m_mapInfo.sizeY;
154 float diffX = pos.X - (float)baseX;
155 float diffY = pos.Y - (float)baseY;
156
157 float mapHeight1 = m_mapInfo.heightMap[baseY * maxY + baseX];
158 float mapHeight2 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + baseX];
159 float mapHeight3 = m_mapInfo.heightMap[baseY * maxY + Math.Min(baseX + 1, maxX - 1)];
160 float mapHeight4 = m_mapInfo.heightMap[Math.Min(baseY + 1, maxY - 1) * maxY + Math.Min(baseX + 1, maxX - 1)];
161
162 float Xrise = (mapHeight4 - mapHeight3) * diffX;
163 float Yrise = (mapHeight2 - mapHeight1) * diffY;
164
165 ret = mapHeight1 + ((Xrise + Yrise) / 2f);
166 // m_physicsScene.DetailLog("{0},BSTerrainHeightMap,GetTerrainHeightAtXYZ,pos={1},{2}/{3}/{4}/{5},ret={6}",
167 // BSScene.DetailLogZero, pos, mapHeight1, mapHeight2, mapHeight3, mapHeight4, ret);
152 } 168 }
153 catch 169 catch
154 { 170 {
diff --git a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
index 4f95554..0d4b6b9 100644
--- a/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/Meshing/Meshmerizer/Meshmerizer.cs
@@ -66,7 +66,7 @@ namespace OpenSim.Region.PhysicsModule.Meshing
66 66
67 private bool cacheSculptMaps = true; 67 private bool cacheSculptMaps = true;
68 private string decodedSculptMapPath = null; 68 private string decodedSculptMapPath = null;
69 private bool useMeshiesPhysicsMesh = false; 69 private bool useMeshiesPhysicsMesh = true;
70 70
71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 71 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
72 72
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
index dc87a78..5465035 100644
--- a/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEMeshWorker.cs
@@ -62,6 +62,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
62 public byte shapetype; 62 public byte shapetype;
63 public bool hasOBB; 63 public bool hasOBB;
64 public bool hasMeshVolume; 64 public bool hasMeshVolume;
65 public bool isTooSmall;
65 public MeshState meshState; 66 public MeshState meshState;
66 public UUID? assetID; 67 public UUID? assetID;
67 public meshWorkerCmnds comand; 68 public meshWorkerCmnds comand;
@@ -69,16 +70,14 @@ namespace OpenSim.Region.PhysicsModule.ubOde
69 70
70 public class ODEMeshWorker 71 public class ODEMeshWorker
71 { 72 {
72
73 private ILog m_log; 73 private ILog m_log;
74 private ODEScene m_scene; 74 private ODEScene m_scene;
75 private IMesher m_mesher; 75 private IMesher m_mesher;
76 76
77 public bool meshSculptedPrim = true; 77 public bool meshSculptedPrim = true;
78 public bool forceSimplePrimMeshing = false;
79 public float meshSculptLOD = 32; 78 public float meshSculptLOD = 32;
80 public float MeshSculptphysicalLOD = 32; 79 public float MeshSculptphysicalLOD = 32;
81 80 public float MinSizeToMeshmerize = 0.1f;
82 81
83 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>(); 82 private OpenSim.Framework.BlockingQueue<ODEPhysRepData> workQueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
84 private bool m_running; 83 private bool m_running;
@@ -93,9 +92,9 @@ namespace OpenSim.Region.PhysicsModule.ubOde
93 92
94 if (pConfig != null) 93 if (pConfig != null)
95 { 94 {
96 forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
97 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim); 95 meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
98 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD); 96 meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
97 MinSizeToMeshmerize = pConfig.GetFloat("mesh_min_size", MinSizeToMeshmerize);
99 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD); 98 MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
100 } 99 }
101 m_running = true; 100 m_running = true;
@@ -288,6 +287,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
288 { 287 {
289 PrimitiveBaseShape pbs = repData.pbs; 288 PrimitiveBaseShape pbs = repData.pbs;
290 // check sculpts or meshs 289 // check sculpts or meshs
290
291 Vector3 scale = pbs.Scale;
292 if(scale.X <= MinSizeToMeshmerize &&
293 scale.Y <= MinSizeToMeshmerize &&
294 scale.Z <= MinSizeToMeshmerize)
295 {
296 repData.isTooSmall = true;
297 return false;
298 }
299
291 if (pbs.SculptEntry) 300 if (pbs.SculptEntry)
292 { 301 {
293 if (meshSculptedPrim) 302 if (meshSculptedPrim)
@@ -299,9 +308,6 @@ namespace OpenSim.Region.PhysicsModule.ubOde
299 return false; 308 return false;
300 } 309 }
301 310
302 if (forceSimplePrimMeshing)
303 return true;
304
305 // convex shapes have no holes 311 // convex shapes have no holes
306 ushort profilehollow = pbs.ProfileHollow; 312 ushort profilehollow = pbs.ProfileHollow;
307 if(repData.shapetype == 2) 313 if(repData.shapetype == 2)
@@ -425,17 +431,8 @@ namespace OpenSim.Region.PhysicsModule.ubOde
425 Vector3 size = repData.size; 431 Vector3 size = repData.size;
426 432
427 int clod = (int)LevelOfDetail.High; 433 int clod = (int)LevelOfDetail.High;
428 bool convex;
429 byte shapetype = repData.shapetype; 434 byte shapetype = repData.shapetype;
430 if (shapetype == 0) 435 bool convex = shapetype == 2;
431 convex = false;
432 else
433 {
434 convex = true;
435 // sculpts pseudo convex
436 if (pbs.SculptEntry && pbs.SculptType != (byte)SculptType.Mesh)
437 clod = (int)LevelOfDetail.Low;
438 }
439 436
440 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); 437 mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
441 438
@@ -563,10 +560,16 @@ namespace OpenSim.Region.PhysicsModule.ubOde
563 560
564 private void CalculateBasicPrimVolume(ODEPhysRepData repData) 561 private void CalculateBasicPrimVolume(ODEPhysRepData repData)
565 { 562 {
566 PrimitiveBaseShape _pbs = repData.pbs;
567 Vector3 _size = repData.size; 563 Vector3 _size = repData.size;
568 564
569 float volume = _size.X * _size.Y * _size.Z; // default 565 float volume = _size.X * _size.Y * _size.Z; // default
566 if(repData.isTooSmall)
567 {
568 repData.volume = volume;
569 return;
570 }
571
572 PrimitiveBaseShape _pbs = repData.pbs;
570 float tmp; 573 float tmp;
571 574
572 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; 575 float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f;
diff --git a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
index 76ef88b..aa208e2 100644
--- a/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
+++ b/OpenSim/Region/PhysicsModules/ubOde/ODEPrim.cs
@@ -1733,7 +1733,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
1733 return true; 1733 return true;
1734 } 1734 }
1735 1735
1736 private void CreateGeom() 1736 private void CreateGeom(bool OverrideToBox)
1737 { 1737 {
1738 bool hasMesh = false; 1738 bool hasMesh = false;
1739 1739
@@ -1742,7 +1742,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
1742 if ((m_meshState & MeshState.MeshNoColide) != 0) 1742 if ((m_meshState & MeshState.MeshNoColide) != 0)
1743 m_NoColide = true; 1743 m_NoColide = true;
1744 1744
1745 else if(m_mesh != null) 1745 else if(!OverrideToBox && m_mesh != null)
1746 { 1746 {
1747 if (GetMeshGeom()) 1747 if (GetMeshGeom())
1748 hasMesh = true; 1748 hasMesh = true;
@@ -3180,7 +3180,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
3180 3180
3181 primVolume = repData.volume; 3181 primVolume = repData.volume;
3182 3182
3183 CreateGeom(); 3183 CreateGeom(repData.isTooSmall);
3184 3184
3185 if (prim_geom != IntPtr.Zero) 3185 if (prim_geom != IntPtr.Zero)
3186 { 3186 {
@@ -3256,7 +3256,7 @@ namespace OpenSim.Region.PhysicsModule.ubOde
3256 3256
3257 primVolume = repData.volume; 3257 primVolume = repData.volume;
3258 3258
3259 CreateGeom(); 3259 CreateGeom(repData.isTooSmall);
3260 3260
3261 if (prim_geom != IntPtr.Zero) 3261 if (prim_geom != IntPtr.Zero)
3262 { 3262 {
diff --git a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
index 0117800..a2a3f79 100644
--- a/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
+++ b/OpenSim/Region/PhysicsModules/ubOdeMeshing/Meshmerizer.cs
@@ -36,15 +36,13 @@ using OpenSim.Region.PhysicsModules.ConvexDecompositionDotNet;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenMetaverse.StructuredData; 37using OpenMetaverse.StructuredData;
38using System.Drawing; 38using System.Drawing;
39using System.Drawing.Imaging; 39using System.Threading;
40using System.IO.Compression; 40using System.IO.Compression;
41using PrimMesher; 41using PrimMesher;
42using log4net; 42using log4net;
43using Nini.Config; 43using Nini.Config;
44using System.Reflection; 44using System.Reflection;
45using System.IO; 45using System.IO;
46using System.Runtime.Serialization;
47using System.Runtime.Serialization.Formatters.Binary;
48 46
49using Mono.Addins; 47using Mono.Addins;
50 48
@@ -58,22 +56,22 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
58 // Setting baseDir to a path will enable the dumping of raw files 56 // Setting baseDir to a path will enable the dumping of raw files
59 // raw files can be imported by blender so a visual inspection of the results can be done 57 // raw files can be imported by blender so a visual inspection of the results can be done
60 58
59 private static string cacheControlFilename = "cntr";
61 private bool m_Enabled = false; 60 private bool m_Enabled = false;
62 61
63 public static object diskLock = new object(); 62 public static object diskLock = new object();
64 63
65 public bool doMeshFileCache = true; 64 public bool doMeshFileCache = true;
66 65 public bool doCacheExpire = true;
67 public string cachePath = "MeshCache"; 66 public string cachePath = "MeshCache";
68 public TimeSpan CacheExpire; 67 public TimeSpan CacheExpire;
69 public bool doCacheExpire = true;
70 68
71// const string baseDir = "rawFiles"; 69// const string baseDir = "rawFiles";
72 private const string baseDir = null; //"rawFiles"; 70 private const string baseDir = null; //"rawFiles";
73 71
74 private bool useMeshiesPhysicsMesh = false; 72 private bool useMeshiesPhysicsMesh = true;
75 73 private bool doConvexPrims = true;
76 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 74 private bool doConvexSculpts = true;
77 75
78 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>(); 76 private Dictionary<AMeshKey, Mesh> m_uniqueMeshes = new Dictionary<AMeshKey, Mesh>();
79 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>(); 77 private Dictionary<AMeshKey, Mesh> m_uniqueReleasedMeshes = new Dictionary<AMeshKey, Mesh>();
@@ -103,40 +101,31 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
103 if (mesh_config != null) 101 if (mesh_config != null)
104 { 102 {
105 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 103 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
106 if (useMeshiesPhysicsMesh) 104 doConvexPrims = mesh_config.GetBoolean("ConvexPrims",doConvexPrims);
107 { 105 doConvexSculpts = mesh_config.GetBoolean("ConvexSculpts",doConvexPrims);
108 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache); 106 doMeshFileCache = mesh_config.GetBoolean("MeshFileCache", doMeshFileCache);
109 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath); 107 cachePath = mesh_config.GetString("MeshFileCachePath", cachePath);
110 fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache); 108 fcache = mesh_config.GetFloat("MeshFileCacheExpireHours", fcache);
111 doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire); 109 doCacheExpire = mesh_config.GetBoolean("MeshFileCacheDoExpire", doCacheExpire);
112 }
113 else
114 {
115 doMeshFileCache = false;
116 doCacheExpire = false;
117 }
118 110
119 m_Enabled = true; 111 m_Enabled = true;
120 } 112 }
121 113
122 CacheExpire = TimeSpan.FromHours(fcache); 114 CacheExpire = TimeSpan.FromHours(fcache);
123 115
124 lock (diskLock) 116 if(String.IsNullOrEmpty(cachePath))
117 doMeshFileCache = false;
118
119 if(doMeshFileCache)
125 { 120 {
126 if(doMeshFileCache && cachePath != "") 121 if(!checkCache())
127 { 122 {
128 try 123 doMeshFileCache = false;
129 { 124 doCacheExpire = false;
130 if (!Directory.Exists(cachePath))
131 Directory.CreateDirectory(cachePath);
132 }
133 catch
134 {
135 doMeshFileCache = false;
136 doCacheExpire = false;
137 }
138 } 125 }
139 } 126 }
127 else
128 doCacheExpire = false;
140 } 129 }
141 } 130 }
142 131
@@ -168,87 +157,6 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
168 157
169 #endregion 158 #endregion
170 159
171 /// <summary>
172 /// creates a simple box mesh of the specified size. This mesh is of very low vertex count and may
173 /// be useful as a backup proxy when level of detail is not needed or when more complex meshes fail
174 /// for some reason
175 /// </summary>
176 /// <param name="minX"></param>
177 /// <param name="maxX"></param>
178 /// <param name="minY"></param>
179 /// <param name="maxY"></param>
180 /// <param name="minZ"></param>
181 /// <param name="maxZ"></param>
182 /// <returns></returns>
183 private static Mesh CreateSimpleBoxMesh(float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
184 {
185 Mesh box = new Mesh(true);
186 List<Vertex> vertices = new List<Vertex>();
187 // bottom
188
189 vertices.Add(new Vertex(minX, maxY, minZ));
190 vertices.Add(new Vertex(maxX, maxY, minZ));
191 vertices.Add(new Vertex(maxX, minY, minZ));
192 vertices.Add(new Vertex(minX, minY, minZ));
193
194 box.Add(new Triangle(vertices[0], vertices[1], vertices[2]));
195 box.Add(new Triangle(vertices[0], vertices[2], vertices[3]));
196
197 // top
198
199 vertices.Add(new Vertex(maxX, maxY, maxZ));
200 vertices.Add(new Vertex(minX, maxY, maxZ));
201 vertices.Add(new Vertex(minX, minY, maxZ));
202 vertices.Add(new Vertex(maxX, minY, maxZ));
203
204 box.Add(new Triangle(vertices[4], vertices[5], vertices[6]));
205 box.Add(new Triangle(vertices[4], vertices[6], vertices[7]));
206
207 // sides
208
209 box.Add(new Triangle(vertices[5], vertices[0], vertices[3]));
210 box.Add(new Triangle(vertices[5], vertices[3], vertices[6]));
211
212 box.Add(new Triangle(vertices[1], vertices[0], vertices[5]));
213 box.Add(new Triangle(vertices[1], vertices[5], vertices[4]));
214
215 box.Add(new Triangle(vertices[7], vertices[1], vertices[4]));
216 box.Add(new Triangle(vertices[7], vertices[2], vertices[1]));
217
218 box.Add(new Triangle(vertices[3], vertices[2], vertices[7]));
219 box.Add(new Triangle(vertices[3], vertices[7], vertices[6]));
220
221 return box;
222 }
223
224 /// <summary>
225 /// Creates a simple bounding box mesh for a complex input mesh
226 /// </summary>
227 /// <param name="meshIn"></param>
228 /// <returns></returns>
229 private static Mesh CreateBoundingBoxMesh(Mesh meshIn)
230 {
231 float minX = float.MaxValue;
232 float maxX = float.MinValue;
233 float minY = float.MaxValue;
234 float maxY = float.MinValue;
235 float minZ = float.MaxValue;
236 float maxZ = float.MinValue;
237
238 foreach (Vector3 v in meshIn.getVertexList())
239 {
240 if (v.X < minX) minX = v.X;
241 if (v.Y < minY) minY = v.Y;
242 if (v.Z < minZ) minZ = v.Z;
243
244 if (v.X > maxX) maxX = v.X;
245 if (v.Y > maxY) maxY = v.Y;
246 if (v.Z > maxZ) maxZ = v.Z;
247 }
248
249 return CreateSimpleBoxMesh(minX, maxX, minY, maxY, minZ, maxZ);
250 }
251
252 private void ReportPrimError(string message, string primName, PrimMesh primMesh) 160 private void ReportPrimError(string message, string primName, PrimMesh primMesh)
253 { 161 {
254 m_log.Error(message); 162 m_log.Error(message);
@@ -265,7 +173,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
265 /// <param name="faces"></param> 173 /// <param name="faces"></param>
266 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces) 174 private void AddSubMesh(OSDMap subMeshData, List<Coord> coords, List<Face> faces)
267 { 175 {
268 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap)); 176 // Console.WriteLine("subMeshMap for {0} - {1}", primName, Util.GetFormattedXml((OSD)subMeshMap));
269 177
270 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level 178 // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level
271 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no 179 // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no
@@ -330,6 +238,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
330 238
331 List<Coord> coords; 239 List<Coord> coords;
332 List<Face> faces; 240 List<Face> faces;
241 bool needsConvexProcessing = convex;
333 242
334 if (primShape.SculptEntry) 243 if (primShape.SculptEntry)
335 { 244 {
@@ -340,23 +249,49 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
340 249
341 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex)) 250 if (!GenerateCoordsAndFacesFromPrimMeshData(primName, primShape, out coords, out faces, convex))
342 return null; 251 return null;
252 needsConvexProcessing = false;
343 } 253 }
344 else 254 else
345 { 255 {
346 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces)) 256 if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, lod, out coords, out faces))
347 return null; 257 return null;
258 needsConvexProcessing &= doConvexSculpts;
348 } 259 }
349 } 260 }
350 else 261 else
351 { 262 {
352 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces)) 263 if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, lod, convex, out coords, out faces))
353 return null; 264 return null;
265 needsConvexProcessing &= doConvexPrims;
354 } 266 }
355 267
356
357 int numCoords = coords.Count; 268 int numCoords = coords.Count;
358 int numFaces = faces.Count; 269 int numFaces = faces.Count;
359 270
271 if(numCoords < 3 || (!needsConvexProcessing && numFaces < 1))
272 {
273 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
274 return null;
275 }
276
277 if(needsConvexProcessing)
278 {
279 List<Coord> convexcoords;
280 List<Face> convexfaces;
281 if(CreateBoundingHull(coords, out convexcoords, out convexfaces) && convexcoords != null && convexfaces != null)
282 {
283 coords.Clear();
284 coords = convexcoords;
285 numCoords = coords.Count;
286
287 faces.Clear();
288 faces = convexfaces;
289 numFaces = faces.Count;
290 }
291 else
292 m_log.ErrorFormat("[ubMESH]: failed to create convex for {0} using normal mesh", primName);
293 }
294
360 Mesh mesh = new Mesh(true); 295 Mesh mesh = new Mesh(true);
361 // Add the corresponding triangles to the mesh 296 // Add the corresponding triangles to the mesh
362 for (int i = 0; i < numFaces; i++) 297 for (int i = 0; i < numFaces; i++)
@@ -371,10 +306,10 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
371 faces.Clear(); 306 faces.Clear();
372 307
373 if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1) 308 if(mesh.numberVertices() < 3 || mesh.numberTriangles() < 1)
374 { 309 {
375 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim " + primName + " ignored"); 310 m_log.ErrorFormat("[MESH]: invalid degenerated mesh for prim {0} ignored", primName);
376 return null; 311 return null;
377 } 312 }
378 313
379 primShape.SculptData = Utils.EmptyBytes; 314 primShape.SculptData = Utils.EmptyBytes;
380 315
@@ -625,45 +560,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
625 vs.Clear(); 560 vs.Clear();
626 continue; 561 continue;
627 } 562 }
628 /*
629 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
630 {
631 vs.Clear();
632 continue;
633 }
634 563
635 nverts = hullr.Vertices.Count;
636 nindexs = hullr.Indices.Count;
637
638 if (nindexs % 3 != 0)
639 {
640 vs.Clear();
641 continue;
642 }
643
644 for (i = 0; i < nverts; i++)
645 {
646 c.X = hullr.Vertices[i].x;
647 c.Y = hullr.Vertices[i].y;
648 c.Z = hullr.Vertices[i].z;
649 coords.Add(c);
650 }
651
652 for (i = 0; i < nindexs; i += 3)
653 {
654 t1 = hullr.Indices[i];
655 if (t1 > nverts)
656 break;
657 t2 = hullr.Indices[i + 1];
658 if (t2 > nverts)
659 break;
660 t3 = hullr.Indices[i + 2];
661 if (t3 > nverts)
662 break;
663 f = new Face(vertsoffset + t1, vertsoffset + t2, vertsoffset + t3);
664 faces.Add(f);
665 }
666 */
667 List<int> indices; 564 List<int> indices;
668 if (!HullUtils.ComputeHull(vs, out indices)) 565 if (!HullUtils.ComputeHull(vs, out indices))
669 { 566 {
@@ -769,38 +666,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
769 vs.Clear(); 666 vs.Clear();
770 return true; 667 return true;
771 } 668 }
772/*
773 if (!HullUtils.ComputeHull(vs, ref hullr, 0, 0.0f))
774 return false;
775
776 nverts = hullr.Vertices.Count;
777 nindexs = hullr.Indices.Count;
778
779 if (nindexs % 3 != 0)
780 return false;
781 669
782 for (i = 0; i < nverts; i++)
783 {
784 c.X = hullr.Vertices[i].x;
785 c.Y = hullr.Vertices[i].y;
786 c.Z = hullr.Vertices[i].z;
787 coords.Add(c);
788 }
789 for (i = 0; i < nindexs; i += 3)
790 {
791 t1 = hullr.Indices[i];
792 if (t1 > nverts)
793 break;
794 t2 = hullr.Indices[i + 1];
795 if (t2 > nverts)
796 break;
797 t3 = hullr.Indices[i + 2];
798 if (t3 > nverts)
799 break;
800 f = new Face(t1, t2, t3);
801 faces.Add(f);
802 }
803*/
804 List<int> indices; 670 List<int> indices;
805 if (!HullUtils.ComputeHull(vs, out indices)) 671 if (!HullUtils.ComputeHull(vs, out indices))
806 return false; 672 return false;
@@ -1413,7 +1279,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1413 } 1279 }
1414 } 1280 }
1415 1281
1416 public void FileNames(AMeshKey key, out string dir,out string fullFileName) 1282 public void FileNames(AMeshKey key, out string dir, out string fullFileName)
1417 { 1283 {
1418 string id = key.ToString(); 1284 string id = key.ToString();
1419 string init = id.Substring(0, 1); 1285 string init = id.Substring(0, 1);
@@ -1530,7 +1396,7 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1530 if (!doCacheExpire) 1396 if (!doCacheExpire)
1531 return; 1397 return;
1532 1398
1533 string controlfile = System.IO.Path.Combine(cachePath, "cntr"); 1399 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1534 1400
1535 lock (diskLock) 1401 lock (diskLock)
1536 { 1402 {
@@ -1583,5 +1449,153 @@ namespace OpenSim.Region.PhysicsModule.ubODEMeshing
1583 catch { } 1449 catch { }
1584 } 1450 }
1585 } 1451 }
1452
1453 public bool checkCache()
1454 {
1455 string controlfile = System.IO.Path.Combine(cachePath, cacheControlFilename);
1456 lock (diskLock)
1457 {
1458 try
1459 {
1460 if (!Directory.Exists(cachePath))
1461 {
1462 Directory.CreateDirectory(cachePath);
1463 Thread.Sleep(100);
1464 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1465 fs.Close();
1466 return true;
1467 }
1468 }
1469 catch
1470 {
1471 doMeshFileCache = false;
1472 doCacheExpire = false;
1473 return false;
1474 }
1475 finally {}
1476
1477 if (File.Exists(controlfile))
1478 return true;
1479
1480 try
1481 {
1482 Directory.Delete(cachePath, true);
1483 while(Directory.Exists(cachePath))
1484 Thread.Sleep(100);
1485 }
1486 catch(Exception e)
1487 {
1488 m_log.Error("[MESH CACHE]: failed to delete old version of the cache: " + e.Message);
1489 doMeshFileCache = false;
1490 doCacheExpire = false;
1491 return false;
1492 }
1493 finally {}
1494 try
1495 {
1496 Directory.CreateDirectory(cachePath);
1497 while(!Directory.Exists(cachePath))
1498 Thread.Sleep(100);
1499 }
1500 catch(Exception e)
1501 {
1502 m_log.Error("[MESH CACHE]: failed to create new cache folder: " + e.Message);
1503 doMeshFileCache = false;
1504 doCacheExpire = false;
1505 return false;
1506 }
1507 finally {}
1508
1509 try
1510 {
1511 FileStream fs = File.Create(controlfile, 4096, FileOptions.WriteThrough);
1512 fs.Close();
1513 }
1514 catch(Exception e)
1515 {
1516 m_log.Error("[MESH CACHE]: failed to create new control file: " + e.Message);
1517 doMeshFileCache = false;
1518 doCacheExpire = false;
1519 return false;
1520 }
1521 finally {}
1522
1523 return true;
1524 }
1525 }
1526
1527 public bool CreateBoundingHull(List<Coord> inputVertices, out List<Coord> convexcoords, out List<Face> newfaces)
1528 {
1529 convexcoords = null;
1530 newfaces = null;
1531 HullDesc desc = new HullDesc();
1532 HullResult result = new HullResult();
1533
1534 int nInputVerts = inputVertices.Count;
1535 int i;
1536
1537 List<float3> vs = new List<float3>(nInputVerts);
1538 float3 f3;
1539
1540 //useless copy
1541 for(i = 0 ; i < nInputVerts; i++)
1542 {
1543 f3 = new float3(inputVertices[i].X, inputVertices[i].Y, inputVertices[i].Z);
1544 vs.Add(f3);
1545 }
1546
1547 desc.Vertices = vs;
1548 desc.Flags = HullFlag.QF_TRIANGLES;
1549 desc.MaxVertices = 256;
1550
1551 try
1552 {
1553 HullError ret = HullUtils.CreateConvexHull(desc, ref result);
1554 if (ret != HullError.QE_OK)
1555 return false;
1556 int nverts = result.OutputVertices.Count;
1557 int nindx = result.Indices.Count;
1558 if(nverts < 3 || nindx< 3)
1559 return false;
1560 if(nindx % 3 != 0)
1561 return false;
1562
1563 convexcoords = new List<Coord>(nverts);
1564 Coord c;
1565 vs = result.OutputVertices;
1566
1567 for(i = 0 ; i < nverts; i++)
1568 {
1569 c = new Coord(vs[i].x, vs[i].y, vs[i].z);
1570 convexcoords.Add(c);
1571 }
1572
1573 newfaces = new List<Face>(nindx / 3);
1574 List<int> indxs = result.Indices;
1575 int k, l, m;
1576 Face f;
1577 for(i = 0 ; i < nindx;)
1578 {
1579 k = indxs[i++];
1580 l = indxs[i++];
1581 m = indxs[i++];
1582 if(k > nInputVerts)
1583 continue;
1584 if(l > nInputVerts)
1585 continue;
1586 if(m > nInputVerts)
1587 continue;
1588 f = new Face(k,l,m);
1589 newfaces.Add(f);
1590 }
1591 return true;
1592 }
1593 catch
1594 {
1595
1596 return false;
1597 }
1598 return false;
1599 }
1586 } 1600 }
1587} 1601}