diff options
Diffstat (limited to '')
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; | |||
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenMetaverse.StructuredData; | 37 | using OpenMetaverse.StructuredData; |
38 | using System.Drawing; | 38 | using System.Drawing; |
39 | using System.Drawing.Imaging; | 39 | using System.Threading; |
40 | using System.IO.Compression; | 40 | using System.IO.Compression; |
41 | using PrimMesher; | 41 | using PrimMesher; |
42 | using log4net; | 42 | using log4net; |
43 | using Nini.Config; | 43 | using Nini.Config; |
44 | using System.Reflection; | 44 | using System.Reflection; |
45 | using System.IO; | 45 | using System.IO; |
46 | using System.Runtime.Serialization; | ||
47 | using System.Runtime.Serialization.Formatters.Binary; | ||
48 | 46 | ||
49 | using Mono.Addins; | 47 | using 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 | } |