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.cs135
1 files changed, 114 insertions, 21 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 8145d61..79edc12 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Meshing
79 79
80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh 80 private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
81 81
82 private List<List<Vector3>> mConvexHulls = null;
83
82 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); 84 private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
83 85
84 public Meshmerizer(IConfigSource config) 86 public Meshmerizer(IConfigSource config)
@@ -358,6 +360,61 @@ namespace OpenSim.Region.Physics.Meshing
358 physicsParms = (OSDMap)map["physics_shape"]; // old asset format 360 physicsParms = (OSDMap)map["physics_shape"]; // old asset format
359 else if (map.ContainsKey("physics_mesh")) 361 else if (map.ContainsKey("physics_mesh"))
360 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format 362 physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
363 else if (map.ContainsKey("medium_lod"))
364 physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
365 else if (map.ContainsKey("high_lod"))
366 physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
367
368 if (map.ContainsKey("physics_convex"))
369 { // pull this out also in case physics engine can use it
370 try
371 {
372 OSDMap convexBlock = (OSDMap)map["physics_convex"];
373 if (convexBlock.ContainsKey("HullList"))
374 {
375 byte[] hullList = convexBlock["HullList"].AsBinary();
376 Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
377 if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
378 Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
379 if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
380
381 // decompress and decode hull points
382 byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
383
384 List<List<Vector3>> hulls = new List<List<Vector3>>();
385 int posNdx = 0;
386
387 foreach (byte cnt in hullList)
388 {
389 int count = cnt == 0 ? 256 : cnt;
390 List<Vector3> hull = new List<Vector3>();
391
392 for (int i = 0; i < count; i++)
393 {
394 ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
395 ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
396 ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
397
398 Vector3 pos = new Vector3(
399 Utils.UInt16ToFloat(uX, min.X, max.X),
400 Utils.UInt16ToFloat(uY, min.Y, max.Y),
401 Utils.UInt16ToFloat(uZ, min.Z, max.Z)
402 );
403
404 hull.Add(pos);
405 }
406
407 hulls.Add(hull);
408 }
409
410 mConvexHulls = hulls;
411 }
412 }
413 catch (Exception e)
414 {
415 m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message);
416 }
417 }
361 418
362 if (physicsParms == null) 419 if (physicsParms == null)
363 { 420 {
@@ -377,27 +434,7 @@ namespace OpenSim.Region.Physics.Meshing
377// byte[] decompressed = new byte[physSize * 5]; 434// byte[] decompressed = new byte[physSize * 5];
378 try 435 try
379 { 436 {
380 using (MemoryStream inMs = new MemoryStream(meshBytes)) 437 decodedMeshOsd = DecompressOsd(meshBytes);
381 {
382 using (MemoryStream outMs = new MemoryStream())
383 {
384 using (ZOutputStream zOut = new ZOutputStream(outMs))
385 {
386 byte[] readBuffer = new byte[2048];
387 int readLen = 0;
388 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
389 {
390 zOut.Write(readBuffer, 0, readLen);
391 }
392 zOut.Flush();
393 outMs.Seek(0, SeekOrigin.Begin);
394
395 byte[] decompressedBuf = outMs.GetBuffer();
396
397 decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
398 }
399 }
400 }
401 } 438 }
402 catch (Exception e) 439 catch (Exception e)
403 { 440 {
@@ -424,6 +461,41 @@ namespace OpenSim.Region.Physics.Meshing
424 return true; 461 return true;
425 } 462 }
426 463
464
465 /// <summary>
466 /// decompresses a gzipped OSD object
467 /// </summary>
468 /// <param name="decodedOsd"></param> the OSD object
469 /// <param name="meshBytes"></param>
470 /// <returns></returns>
471 private static OSD DecompressOsd(byte[] meshBytes)
472 {
473 OSD decodedOsd = null;
474
475 using (MemoryStream inMs = new MemoryStream(meshBytes))
476 {
477 using (MemoryStream outMs = new MemoryStream())
478 {
479 using (ZOutputStream zOut = new ZOutputStream(outMs))
480 {
481 byte[] readBuffer = new byte[2048];
482 int readLen = 0;
483 while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
484 {
485 zOut.Write(readBuffer, 0, readLen);
486 }
487 zOut.Flush();
488 outMs.Seek(0, SeekOrigin.Begin);
489
490 byte[] decompressedBuf = outMs.GetBuffer();
491
492 decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
493 }
494 }
495 }
496 return decodedOsd;
497 }
498
427 /// <summary> 499 /// <summary>
428 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. 500 /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
429 /// </summary> 501 /// </summary>
@@ -700,6 +772,27 @@ namespace OpenSim.Region.Physics.Meshing
700 return true; 772 return true;
701 } 773 }
702 774
775 /// <summary>
776 /// temporary prototype code - please do not use until the interface has been finalized!
777 /// </summary>
778 /// <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>
780 public List<List<Vector3>> GetConvexHulls(Vector3 size)
781 {
782 if (mConvexHulls == null)
783 return null;
784
785 List<List<Vector3>> hulls = new List<List<Vector3>>();
786 foreach (var hull in mConvexHulls)
787 {
788 List<Vector3> verts = new List<Vector3>();
789 foreach (var vert in hull)
790 verts.Add(vert * size);
791 }
792
793 return hulls;
794 }
795
703 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) 796 public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
704 { 797 {
705 return CreateMesh(primName, primShape, size, lod, false, true); 798 return CreateMesh(primName, primShape, size, lod, false, true);