diff options
author | dahlia | 2013-05-24 01:53:37 -0700 |
---|---|---|
committer | dahlia | 2013-05-24 01:53:37 -0700 |
commit | 0cdea5c2f302ece2d37357b7e7b8c1d3f6ed8f94 (patch) | |
tree | 991105a8ca49ad1b85866a02872b1ed1628e288a | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC-0cdea5c2f302ece2d37357b7e7b8c1d3f6ed8f94.zip opensim-SC-0cdea5c2f302ece2d37357b7e7b8c1d3f6ed8f94.tar.gz opensim-SC-0cdea5c2f302ece2d37357b7e7b8c1d3f6ed8f94.tar.bz2 opensim-SC-0cdea5c2f302ece2d37357b7e7b8c1d3f6ed8f94.tar.xz |
correct some errors in decoding of mesh asset convex decomposition data
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 136 |
1 files changed, 83 insertions, 53 deletions
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index fd45efe..3e2b663 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -386,61 +386,57 @@ namespace OpenSim.Region.Physics.Meshing | |||
386 | 386 | ||
387 | if (map.ContainsKey("physics_convex")) | 387 | if (map.ContainsKey("physics_convex")) |
388 | { // pull this out also in case physics engine can use it | 388 | { // pull this out also in case physics engine can use it |
389 | OSD convexBlockOsd = null; | ||
389 | try | 390 | try |
390 | { | 391 | { |
391 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; | 392 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; |
392 | |||
393 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
394 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); | ||
395 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); | ||
396 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); | ||
397 | |||
398 | List<Vector3> boundingHull = null; | ||
399 | |||
400 | if (convexBlock.ContainsKey("BoundingVerts")) | ||
401 | { | 393 | { |
402 | // decompress and decode bounding hull points | 394 | int convexOffset = convexBlock["offset"].AsInteger() + (int)start; |
403 | byte[] boundingVertsBytes = DecompressOsd(convexBlock["BoundingVerts"].AsBinary()).AsBinary(); | 395 | int convexSize = convexBlock["size"].AsInteger(); |
404 | boundingHull = new List<Vector3>(); | ||
405 | for (int i = 0; i < boundingVertsBytes.Length;) | ||
406 | { | ||
407 | ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; | ||
408 | ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; | ||
409 | ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; | ||
410 | |||
411 | Vector3 pos = new Vector3( | ||
412 | Utils.UInt16ToFloat(uX, min.X, max.X), | ||
413 | Utils.UInt16ToFloat(uY, min.Y, max.Y), | ||
414 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | ||
415 | ); | ||
416 | 396 | ||
417 | boundingHull.Add(pos); | 397 | byte[] convexBytes = new byte[convexSize]; |
398 | |||
399 | System.Buffer.BlockCopy(primShape.SculptData, convexOffset, convexBytes, 0, convexSize); | ||
400 | |||
401 | try | ||
402 | { | ||
403 | convexBlockOsd = DecompressOsd(convexBytes); | ||
404 | } | ||
405 | catch (Exception e) | ||
406 | { | ||
407 | m_log.ErrorFormat("{0} prim='{1}': exception decoding convex block: {2}", LogHeader, primName, e); | ||
408 | //return false; | ||
418 | } | 409 | } |
419 | |||
420 | mBoundingHull = boundingHull; | ||
421 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nHulls={2}", LogHeader, primName, mBoundingHull.Count); | ||
422 | } | 410 | } |
423 | 411 | ||
424 | if (convexBlock.ContainsKey("HullList")) | 412 | if (convexBlockOsd != null && convexBlockOsd is OSDMap) |
425 | { | 413 | { |
426 | byte[] hullList = convexBlock["HullList"].AsBinary(); | 414 | convexBlock = convexBlockOsd as OSDMap; |
427 | 415 | ||
428 | // decompress and decode hull points | 416 | if (debugDetail) |
429 | byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary(); | 417 | { |
430 | 418 | string keys = "[MESH]: keys found in convexBlock: "; | |
431 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | 419 | foreach (KeyValuePair<string, OSD> kvp in convexBlock) |
432 | int posNdx = 0; | 420 | keys += "'" + kvp.Key + "' "; |
421 | m_log.Info(keys); | ||
422 | } | ||
423 | |||
424 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
425 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); | ||
426 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); | ||
427 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); | ||
428 | |||
429 | List<Vector3> boundingHull = null; | ||
433 | 430 | ||
434 | foreach (byte cnt in hullList) | 431 | if (convexBlock.ContainsKey("BoundingVerts")) |
435 | { | 432 | { |
436 | int count = cnt == 0 ? 256 : cnt; | 433 | byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary(); |
437 | List<Vector3> hull = new List<Vector3>(); | 434 | boundingHull = new List<Vector3>(); |
438 | 435 | for (int i = 0; i < boundingVertsBytes.Length; ) | |
439 | for (int i = 0; i < count; i++) | ||
440 | { | 436 | { |
441 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 437 | ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
442 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 438 | ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
443 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | 439 | ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; |
444 | 440 | ||
445 | Vector3 pos = new Vector3( | 441 | Vector3 pos = new Vector3( |
446 | Utils.UInt16ToFloat(uX, min.X, max.X), | 442 | Utils.UInt16ToFloat(uX, min.X, max.X), |
@@ -448,18 +444,52 @@ namespace OpenSim.Region.Physics.Meshing | |||
448 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | 444 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) |
449 | ); | 445 | ); |
450 | 446 | ||
451 | hull.Add(pos); | 447 | boundingHull.Add(pos); |
452 | } | 448 | } |
453 | 449 | ||
454 | hulls.Add(hull); | 450 | mBoundingHull = boundingHull; |
451 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nVerts={2}", LogHeader, primName, mBoundingHull.Count); | ||
455 | } | 452 | } |
456 | 453 | ||
457 | mConvexHulls = hulls; | 454 | if (convexBlock.ContainsKey("HullList")) |
458 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count); | 455 | { |
459 | } | 456 | byte[] hullList = convexBlock["HullList"].AsBinary(); |
460 | else | 457 | |
461 | { | 458 | byte[] posBytes = convexBlock["Positions"].AsBinary(); |
462 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName); | 459 | |
460 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
461 | int posNdx = 0; | ||
462 | |||
463 | foreach (byte cnt in hullList) | ||
464 | { | ||
465 | int count = cnt == 0 ? 256 : cnt; | ||
466 | List<Vector3> hull = new List<Vector3>(); | ||
467 | |||
468 | for (int i = 0; i < count; i++) | ||
469 | { | ||
470 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
471 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
472 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
473 | |||
474 | Vector3 pos = new Vector3( | ||
475 | Utils.UInt16ToFloat(uX, min.X, max.X), | ||
476 | Utils.UInt16ToFloat(uY, min.Y, max.Y), | ||
477 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | ||
478 | ); | ||
479 | |||
480 | hull.Add(pos); | ||
481 | } | ||
482 | |||
483 | hulls.Add(hull); | ||
484 | } | ||
485 | |||
486 | mConvexHulls = hulls; | ||
487 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count); | ||
488 | } | ||
489 | else | ||
490 | { | ||
491 | if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName); | ||
492 | } | ||
463 | } | 493 | } |
464 | } | 494 | } |
465 | catch (Exception e) | 495 | catch (Exception e) |
@@ -483,7 +513,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
483 | OSD decodedMeshOsd = new OSD(); | 513 | OSD decodedMeshOsd = new OSD(); |
484 | byte[] meshBytes = new byte[physSize]; | 514 | byte[] meshBytes = new byte[physSize]; |
485 | System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); | 515 | System.Buffer.BlockCopy(primShape.SculptData, physOffset, meshBytes, 0, physSize); |
486 | // byte[] decompressed = new byte[physSize * 5]; | 516 | // byte[] decompressed = new byte[physSize * 5]; |
487 | try | 517 | try |
488 | { | 518 | { |
489 | decodedMeshOsd = DecompressOsd(meshBytes); | 519 | decodedMeshOsd = DecompressOsd(meshBytes); |
@@ -499,7 +529,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
499 | // physics_shape is an array of OSDMaps, one for each submesh | 529 | // physics_shape is an array of OSDMaps, one for each submesh |
500 | if (decodedMeshOsd is OSDArray) | 530 | if (decodedMeshOsd is OSDArray) |
501 | { | 531 | { |
502 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); | 532 | // Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd)); |
503 | 533 | ||
504 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; | 534 | decodedMeshOsdArray = (OSDArray)decodedMeshOsd; |
505 | foreach (OSD subMeshOsd in decodedMeshOsdArray) | 535 | foreach (OSD subMeshOsd in decodedMeshOsdArray) |