diff options
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 207 |
1 files changed, 141 insertions, 66 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index cf57c0a..3e3a0f0 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -31,8 +31,10 @@ using System.Collections.Generic; | |||
31 | using OpenSim.Framework; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Region.Physics.Manager; | 32 | using OpenSim.Region.Physics.Manager; |
33 | using OpenMetaverse; | 33 | using OpenMetaverse; |
34 | using OpenMetaverse.StructuredData; | ||
34 | using System.Drawing; | 35 | using System.Drawing; |
35 | using System.Drawing.Imaging; | 36 | using System.Drawing.Imaging; |
37 | using System.IO.Compression; | ||
36 | using PrimMesher; | 38 | using PrimMesher; |
37 | using log4net; | 39 | using log4net; |
38 | using Nini.Config; | 40 | using Nini.Config; |
@@ -256,102 +258,175 @@ namespace OpenSim.Region.Physics.Meshing | |||
256 | PrimMesh primMesh; | 258 | PrimMesh primMesh; |
257 | PrimMesher.SculptMesh sculptMesh; | 259 | PrimMesher.SculptMesh sculptMesh; |
258 | 260 | ||
259 | List<Coord> coords; | 261 | List<Coord> coords = new List<Coord>(); |
260 | List<Face> faces; | 262 | List<Face> faces = new List<Face>(); |
261 | 263 | ||
262 | Image idata = null; | 264 | Image idata = null; |
263 | string decodedSculptFileName = ""; | 265 | string decodedSculptFileName = ""; |
264 | 266 | ||
265 | if (primShape.SculptEntry) | 267 | if (primShape.SculptEntry) |
266 | { | 268 | { |
267 | if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) | 269 | if (((OpenMetaverse.SculptType)primShape.SculptType) == SculptType.Mesh) |
268 | { | 270 | { |
269 | decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); | 271 | // add code for mesh physics proxy generation here |
272 | m_log.Debug("[MESH]: mesh proxy generation not implemented yet "); | ||
273 | |||
274 | OSD meshOsd; | ||
275 | |||
276 | if (primShape.SculptData.Length > 0) | ||
277 | { | ||
278 | |||
279 | |||
280 | m_log.Debug("[MESH]: asset data length: " + primShape.SculptData.Length.ToString()); | ||
281 | byte[] header = Util.StringToBytes256("<? LLSD/Binary ?>"); | ||
282 | |||
283 | ////dump to debugging file | ||
284 | //string filename = System.IO.Path.Combine(decodedSculptMapPath, "mesh_" + primShape.SculptTexture.ToString()); | ||
285 | //BinaryWriter writer = new BinaryWriter(File.Open(filename, FileMode.Create)); | ||
286 | //writer.Write(primShape.SculptData); | ||
287 | //writer.Close(); | ||
288 | |||
289 | } | ||
290 | else | ||
291 | { | ||
292 | m_log.Error("[MESH]: asset data is zero length"); | ||
293 | return null; | ||
294 | } | ||
295 | |||
270 | try | 296 | try |
271 | { | 297 | { |
272 | if (File.Exists(decodedSculptFileName)) | 298 | meshOsd = OSDParser.DeserializeLLSDBinary(primShape.SculptData, true); |
273 | { | ||
274 | idata = Image.FromFile(decodedSculptFileName); | ||
275 | } | ||
276 | } | 299 | } |
277 | catch (Exception e) | 300 | catch (Exception e) |
278 | { | 301 | { |
279 | m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); | 302 | m_log.Error("[MESH]: exception decoding mesh asset: " + e.ToString()); |
303 | return null; | ||
304 | } | ||
305 | |||
306 | if (meshOsd is OSDMap) | ||
307 | { | ||
308 | OSDMap map = (OSDMap)meshOsd; | ||
309 | //foreach (string name in map.Keys) | ||
310 | // m_log.Debug("[MESH]: key:" + name + " value:" + map[name].AsString()); | ||
311 | OSDMap physicsParms = (OSDMap)map["physics_shape"]; | ||
312 | int physOffset = physicsParms["offset"].AsInteger(); | ||
313 | int physSize = physicsParms["size"].AsInteger(); | ||
314 | |||
315 | if (physOffset < 0 || physSize == 0) | ||
316 | return null; // no mesh data in asset | ||
317 | |||
318 | m_log.Debug("[MESH]: physOffset:" + physOffset.ToString() + " physSize:" + physSize.ToString()); | ||
319 | //MemoryStream ms = new MemoryStream(primShape.SculptData, physOffset, physSize); | ||
320 | //GZipStream gzStream = new GZipStream(ms, CompressionMode.Decompress); | ||
321 | |||
322 | //int maxSize = physSize * 5; // arbitrary guess | ||
323 | //byte[] readBuffer = new byte[maxSize]; | ||
324 | |||
325 | //int bytesRead = gzStream.Read(readBuffer, 0, maxSize); | ||
326 | |||
327 | //OSD physMeshOsd = OSDParser.DeserializeLLSDBinary(readBuffer); | ||
328 | |||
329 | |||
330 | |||
331 | |||
280 | 332 | ||
281 | } | 333 | } |
282 | //if (idata != null) | ||
283 | // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); | ||
284 | } | ||
285 | 334 | ||
286 | if (idata == null) | 335 | //just bail out for now until mesh code is finished |
336 | return null; | ||
337 | |||
338 | } | ||
339 | else | ||
287 | { | 340 | { |
288 | if (primShape.SculptData == null || primShape.SculptData.Length == 0) | 341 | if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) |
289 | return null; | 342 | { |
343 | decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); | ||
344 | try | ||
345 | { | ||
346 | if (File.Exists(decodedSculptFileName)) | ||
347 | { | ||
348 | idata = Image.FromFile(decodedSculptFileName); | ||
349 | } | ||
350 | } | ||
351 | catch (Exception e) | ||
352 | { | ||
353 | m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message); | ||
290 | 354 | ||
291 | try | 355 | } |
356 | //if (idata != null) | ||
357 | // m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString()); | ||
358 | } | ||
359 | |||
360 | if (idata == null) | ||
292 | { | 361 | { |
293 | OpenMetaverse.Imaging.ManagedImage unusedData; | 362 | if (primShape.SculptData == null || primShape.SculptData.Length == 0) |
294 | OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); | 363 | return null; |
295 | unusedData = null; | ||
296 | 364 | ||
297 | //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); | 365 | try |
366 | { | ||
367 | OpenMetaverse.Imaging.ManagedImage unusedData; | ||
368 | OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata); | ||
369 | unusedData = null; | ||
370 | |||
371 | //idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData); | ||
298 | 372 | ||
299 | if (cacheSculptMaps && idata != null) | 373 | if (cacheSculptMaps && idata != null) |
374 | { | ||
375 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } | ||
376 | catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } | ||
377 | } | ||
378 | } | ||
379 | catch (DllNotFoundException) | ||
300 | { | 380 | { |
301 | try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); } | 381 | m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); |
302 | catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); } | 382 | return null; |
383 | } | ||
384 | catch (IndexOutOfRangeException) | ||
385 | { | ||
386 | m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); | ||
387 | return null; | ||
388 | } | ||
389 | catch (Exception ex) | ||
390 | { | ||
391 | m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); | ||
392 | return null; | ||
303 | } | 393 | } |
304 | } | 394 | } |
305 | catch (DllNotFoundException) | 395 | |
306 | { | 396 | PrimMesher.SculptMesh.SculptType sculptType; |
307 | m_log.Error("[PHYSICS]: OpenJpeg is not installed correctly on this system. Physics Proxy generation failed. Often times this is because of an old version of GLIBC. You must have version 2.4 or above!"); | 397 | switch ((OpenMetaverse.SculptType)primShape.SculptType) |
308 | return null; | ||
309 | } | ||
310 | catch (IndexOutOfRangeException) | ||
311 | { | ||
312 | m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed"); | ||
313 | return null; | ||
314 | } | ||
315 | catch (Exception ex) | ||
316 | { | 398 | { |
317 | m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message); | 399 | case OpenMetaverse.SculptType.Cylinder: |
318 | return null; | 400 | sculptType = PrimMesher.SculptMesh.SculptType.cylinder; |
401 | break; | ||
402 | case OpenMetaverse.SculptType.Plane: | ||
403 | sculptType = PrimMesher.SculptMesh.SculptType.plane; | ||
404 | break; | ||
405 | case OpenMetaverse.SculptType.Torus: | ||
406 | sculptType = PrimMesher.SculptMesh.SculptType.torus; | ||
407 | break; | ||
408 | case OpenMetaverse.SculptType.Sphere: | ||
409 | sculptType = PrimMesher.SculptMesh.SculptType.sphere; | ||
410 | break; | ||
411 | default: | ||
412 | sculptType = PrimMesher.SculptMesh.SculptType.plane; | ||
413 | break; | ||
319 | } | 414 | } |
320 | } | ||
321 | 415 | ||
322 | PrimMesher.SculptMesh.SculptType sculptType; | 416 | bool mirror = ((primShape.SculptType & 128) != 0); |
323 | switch ((OpenMetaverse.SculptType)primShape.SculptType) | 417 | bool invert = ((primShape.SculptType & 64) != 0); |
324 | { | ||
325 | case OpenMetaverse.SculptType.Cylinder: | ||
326 | sculptType = PrimMesher.SculptMesh.SculptType.cylinder; | ||
327 | break; | ||
328 | case OpenMetaverse.SculptType.Plane: | ||
329 | sculptType = PrimMesher.SculptMesh.SculptType.plane; | ||
330 | break; | ||
331 | case OpenMetaverse.SculptType.Torus: | ||
332 | sculptType = PrimMesher.SculptMesh.SculptType.torus; | ||
333 | break; | ||
334 | case OpenMetaverse.SculptType.Sphere: | ||
335 | sculptType = PrimMesher.SculptMesh.SculptType.sphere; | ||
336 | break; | ||
337 | default: | ||
338 | sculptType = PrimMesher.SculptMesh.SculptType.plane; | ||
339 | break; | ||
340 | } | ||
341 | |||
342 | bool mirror = ((primShape.SculptType & 128) != 0); | ||
343 | bool invert = ((primShape.SculptType & 64) != 0); | ||
344 | 418 | ||
345 | sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); | 419 | sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); |
346 | 420 | ||
347 | idata.Dispose(); | 421 | idata.Dispose(); |
348 | 422 | ||
349 | sculptMesh.DumpRaw(baseDir, primName, "primMesh"); | 423 | sculptMesh.DumpRaw(baseDir, primName, "primMesh"); |
350 | 424 | ||
351 | sculptMesh.Scale(size.X, size.Y, size.Z); | 425 | sculptMesh.Scale(size.X, size.Y, size.Z); |
352 | 426 | ||
353 | coords = sculptMesh.coords; | 427 | coords = sculptMesh.coords; |
354 | faces = sculptMesh.faces; | 428 | faces = sculptMesh.faces; |
429 | } | ||
355 | } | 430 | } |
356 | else | 431 | else |
357 | { | 432 | { |