aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/Meshing/Meshmerizer.cs')
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs152
1 files changed, 129 insertions, 23 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 79edc12..fc679e7 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing
64 public class Meshmerizer : IMesher 64 public class Meshmerizer : IMesher
65 { 65 {
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 private static string LogHeader = "[MESH]";
67 68
68 // Setting baseDir to a path will enable the dumping of raw files 69 // Setting baseDir to a path will enable the dumping of raw files
69 // raw files can be imported by blender so a visual inspection of the results can be done 70 // raw files can be imported by blender so a visual inspection of the results can be done
@@ -72,6 +73,8 @@ namespace OpenSim.Region.Physics.Meshing
72#else 73#else
73 private const string baseDir = null; //"rawFiles"; 74 private const string baseDir = null; //"rawFiles";
74#endif 75#endif
76 // If 'true', lots of DEBUG logging of asset parsing details
77 private bool debugDetail = false;
75 78
76 private bool cacheSculptMaps = true; 79 private bool cacheSculptMaps = true;
77 private string decodedSculptMapPath = null; 80 private string decodedSculptMapPath = null;
@@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
80 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
81 84
82 private List<List<Vector3>> mConvexHulls = null; 85 private List<List<Vector3>> mConvexHulls = null;
86 private List<Vector3> mBoundingHull = null;
83 87
84 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 88 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
85 89
@@ -90,8 +94,11 @@ namespace OpenSim.Region.Physics.Meshing
90 94
91 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); 95 decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
92 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps); 96 cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
93 if(mesh_config != null) 97 if (mesh_config != null)
98 {
94 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh); 99 useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
100 debugDetail = mesh_config.GetBoolean("LogMeshDetails", debugDetail);
101 }
95 102
96 try 103 try
97 { 104 {
@@ -321,6 +328,9 @@ namespace OpenSim.Region.Physics.Meshing
321 faces = new List<Face>(); 328 faces = new List<Face>();
322 OSD meshOsd = null; 329 OSD meshOsd = null;
323 330
331 mConvexHulls = null;
332 mBoundingHull = null;
333
324 if (primShape.SculptData.Length <= 0) 334 if (primShape.SculptData.Length <= 0)
325 { 335 {
326 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this 336 // XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
@@ -357,43 +367,79 @@ namespace OpenSim.Region.Physics.Meshing
357 OSDMap physicsParms = null; 367 OSDMap physicsParms = null;
358 OSDMap map = (OSDMap)meshOsd; 368 OSDMap map = (OSDMap)meshOsd;
359 if (map.ContainsKey("physics_shape")) 369 if (map.ContainsKey("physics_shape"))
370 {
360 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 371 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
372 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
373 }
361 else if (map.ContainsKey("physics_mesh")) 374 else if (map.ContainsKey("physics_mesh"))
375 {
362 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 376 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
377 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
378 }
363 else if (map.ContainsKey("medium_lod")) 379 else if (map.ContainsKey("medium_lod"))
380 {
364 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh 381 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
382 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
383 }
365 else if (map.ContainsKey("high_lod")) 384 else if (map.ContainsKey("high_lod"))
385 {
366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) 386 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
387 if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
388 }
367 389
368 if (map.ContainsKey("physics_convex")) 390 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it 391 { // pull this out also in case physics engine can use it
392 OSD convexBlockOsd = null;
370 try 393 try
371 { 394 {
372 OSDMap convexBlock = (OSDMap)map["physics_convex"]; 395 OSDMap convexBlock = (OSDMap)map["physics_convex"];
373 if (convexBlock.ContainsKey("HullList"))
374 { 396 {
375 byte[] hullList = convexBlock["HullList"].AsBinary(); 397 int convexOffset = convexBlock["offset"].AsInteger() + (int)start;
398 int convexSize = convexBlock["size"].AsInteger();
399
400 byte[] convexBytes = new byte[convexSize];
401
402 System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize);
403
404 try
405 {
406 convexBlockOsd = DecompressOsd(convexBytes);
407 }
408 catch (Exception e)
409 {
410 m_log.ErrorFormat("{0} prim='{1}': exception decoding convex block: {2}", LogHeader, primName, e);
411 //return false;
412 }
413 }
414
415 if (convexBlockOsd != null && convexBlockOsd is OSDMap)
416 {
417 convexBlock = convexBlockOsd as OSDMap;
418
419 if (debugDetail)
420 {
421 string keys = LogHeader + " keys found in convexBlock: ";
422 foreach (KeyValuePair<string, OSD> kvp in convexBlock)
423 keys += "'" + kvp.Key + "' ";
424 m_log.Debug(keys);
425 }
426
376 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); 427 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
377 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); 428 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
378 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); 429 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
379 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); 430 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
380 431
381 // decompress and decode hull points 432 List<Vector3> boundingHull = null;
382 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
383
384 List<List<Vector3>> hulls = new List<List<Vector3>>();
385 int posNdx = 0;
386 433
387 foreach (byte cnt in hullList) 434 if (convexBlock.ContainsKey("BoundingVerts"))
388 { 435 {
389 int count = cnt == 0 ? 256 : cnt; 436 byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary();
390 List<Vector3> hull = new List<Vector3>(); 437 boundingHull = new List<Vector3>();
391 438 for (int i = 0; i < boundingVertsBytes.Length; )
392 for (int i = 0; i < count; i++)
393 { 439 {
394 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 440 ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
395 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 441 ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
396 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; 442 ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
397 443
398 Vector3 pos = new Vector3( 444 Vector3 pos = new Vector3(
399 Utils.UInt16ToFloat(uX, min.X, max.X), 445 Utils.UInt16ToFloat(uX, min.X, max.X),
@@ -401,18 +447,57 @@ namespace OpenSim.Region.Physics.Meshing
401 Utils.UInt16ToFloat(uZ, min.Z, max.Z) 447 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
402 ); 448 );
403 449
404 hull.Add(pos); 450 boundingHull.Add(pos);
405 } 451 }
406 452
407 hulls.Add(hull); 453 mBoundingHull = boundingHull;
454 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nVerts={2}", LogHeader, primName, mBoundingHull.Count);
408 } 455 }
409 456
410 mConvexHulls = hulls; 457 if (convexBlock.ContainsKey("HullList"))
458 {
459 byte[] hullList = convexBlock["HullList"].AsBinary();
460
461 byte[] posBytes = convexBlock["Positions"].AsBinary();
462
463 List<List<Vector3>> hulls = new List<List<Vector3>>();
464 int posNdx = 0;
465
466 foreach (byte cnt in hullList)
467 {
468 int count = cnt == 0 ? 256 : cnt;
469 List<Vector3> hull = new List<Vector3>();
470
471 for (int i = 0; i < count; i++)
472 {
473 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
474 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
475 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
476
477 Vector3 pos = new Vector3(
478 Utils.UInt16ToFloat(uX, min.X, max.X),
479 Utils.UInt16ToFloat(uY, min.Y, max.Y),
480 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
481 );
482
483 hull.Add(pos);
484 }
485
486 hulls.Add(hull);
487 }
488
489 mConvexHulls = hulls;
490 if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
491 }
492 else
493 {
494 if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
495 }
411 } 496 }
412 } 497 }
413 catch (Exception e) 498 catch (Exception e)
414 { 499 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); 500 m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
416 } 501 }
417 } 502 }
418 503
@@ -431,14 +516,14 @@ namespace OpenSim.Region.Physics.Meshing
431 OSD decodedMeshOsd = new OSD(); 516 OSD decodedMeshOsd = new OSD();
432 byte[] meshBytes = new byte[physSize]; 517 byte[] meshBytes = new byte[physSize];
433 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); 518 System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize);
434// byte[] decompressed = new byte[physSize * 5]; 519 // byte[] decompressed = new byte[physSize * 5];
435 try 520 try
436 { 521 {
437 decodedMeshOsd = DecompressOsd(meshBytes); 522 decodedMeshOsd = DecompressOsd(meshBytes);
438 } 523 }
439 catch (Exception e) 524 catch (Exception e)
440 { 525 {
441 m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString()); 526 m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
442 return false; 527 return false;
443 } 528 }
444 529
@@ -447,7 +532,7 @@ namespace OpenSim.Region.Physics.Meshing
447 // physics_shape is an array of OSDMaps, one for each submesh 532 // physics_shape is an array of OSDMaps, one for each submesh
448 if (decodedMeshOsd is OSDArray) 533 if (decodedMeshOsd is OSDArray)
449 { 534 {
450// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); 535 // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
451 536
452 decodedMeshOsdArray = (OSDArray)decodedMeshOsd; 537 decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
453 foreach (OSD subMeshOsd in decodedMeshOsdArray) 538 foreach (OSD subMeshOsd in decodedMeshOsdArray)
@@ -455,6 +540,9 @@ namespace OpenSim.Region.Physics.Meshing
455 if (subMeshOsd is OSDMap) 540 if (subMeshOsd is OSDMap)
456 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces); 541 AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
457 } 542 }
543 if (debugDetail)
544 m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
545 LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
458 } 546 }
459 } 547 }
460 548
@@ -776,6 +864,23 @@ namespace OpenSim.Region.Physics.Meshing
776 /// temporary prototype code - please do not use until the interface has been finalized! 864 /// temporary prototype code - please do not use until the interface has been finalized!
777 /// </summary> 865 /// </summary>
778 /// <param name="size">value to scale the hull points by</param> 866 /// <param name="size">value to scale the hull points by</param>
867 /// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns>
868 public List<Vector3> GetBoundingHull(Vector3 size)
869 {
870 if (mBoundingHull == null)
871 return null;
872
873 List<Vector3> verts = new List<Vector3>();
874 foreach (var vert in mBoundingHull)
875 verts.Add(vert * size);
876
877 return verts;
878 }
879
880 /// <summary>
881 /// temporary prototype code - please do not use until the interface has been finalized!
882 /// </summary>
883 /// <param name="size">value to scale the hull points by</param>
779 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> 884 /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns>
780 public List<List<Vector3>> GetConvexHulls(Vector3 size) 885 public List<List<Vector3>> GetConvexHulls(Vector3 size)
781 { 886 {
@@ -788,6 +893,7 @@ namespace OpenSim.Region.Physics.Meshing
788 List<Vector3> verts = new List<Vector3>(); 893 List<Vector3> verts = new List<Vector3>();
789 foreach (var vert in hull) 894 foreach (var vert in hull)
790 verts.Add(vert * size); 895 verts.Add(vert * size);
896 hulls.Add(verts);
791 } 897 }
792 898
793 return hulls; 899 return hulls;