aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs')
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs61
1 files changed, 43 insertions, 18 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index d3ba273..b1833c5 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
@@ -36,7 +36,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
36{ 36{
37public class BSShapeCollection : IDisposable 37public class BSShapeCollection : IDisposable
38{ 38{
39 // private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]"; 39 private static string LogHeader = "[BULLETSIM SHAPE COLLECTION]";
40 40
41 protected BSScene PhysicsScene { get; set; } 41 protected BSScene PhysicsScene { get; set; }
42 42
@@ -89,7 +89,7 @@ public class BSShapeCollection : IDisposable
89 // higher level dependencies on the shape or body. Mostly used for LinkSets to 89 // higher level dependencies on the shape or body. Mostly used for LinkSets to
90 // remove the physical constraints before the body is destroyed. 90 // remove the physical constraints before the body is destroyed.
91 // Called at taint-time!! 91 // Called at taint-time!!
92 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, 92 public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim,
93 ShapeData shapeData, PrimitiveBaseShape pbs, 93 ShapeData shapeData, PrimitiveBaseShape pbs,
94 ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) 94 ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback)
95 { 95 {
@@ -105,7 +105,7 @@ public class BSShapeCollection : IDisposable
105 // If we had to select a new shape geometry for the object, 105 // If we had to select a new shape geometry for the object,
106 // rebuild the body around it. 106 // rebuild the body around it.
107 // Updates prim.BSBody with information/pointers to requested body 107 // Updates prim.BSBody with information/pointers to requested body
108 bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, 108 bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World,
109 prim.BSShape, shapeData, bodyCallback); 109 prim.BSShape, shapeData, bodyCallback);
110 ret = newGeom || newBody; 110 ret = newGeom || newBody;
111 } 111 }
@@ -325,7 +325,7 @@ public class BSShapeCollection : IDisposable
325 // Info in prim.BSShape is updated to the new shape. 325 // Info in prim.BSShape is updated to the new shape.
326 // Returns 'true' if the geometry was rebuilt. 326 // Returns 'true' if the geometry was rebuilt.
327 // Called at taint-time! 327 // Called at taint-time!
328 private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData, 328 private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData,
329 PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback) 329 PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback)
330 { 330 {
331 bool ret = false; 331 bool ret = false;
@@ -335,7 +335,7 @@ public class BSShapeCollection : IDisposable
335 if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR) 335 if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
336 { 336 {
337 // an avatar capsule is close to a native shape (it is not shared) 337 // an avatar capsule is close to a native shape (it is not shared)
338 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR, 338 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR,
339 ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); 339 ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback);
340 DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.BSShape); 340 DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.BSShape);
341 haveShape = true; 341 haveShape = true;
@@ -362,7 +362,7 @@ public class BSShapeCollection : IDisposable
362 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE 362 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
363 ) 363 )
364 { 364 {
365 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, 365 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
366 ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); 366 ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
367 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", 367 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
368 prim.LocalID, forceRebuild, prim.BSShape); 368 prim.LocalID, forceRebuild, prim.BSShape);
@@ -376,7 +376,7 @@ public class BSShapeCollection : IDisposable
376 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX 376 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
377 ) 377 )
378 { 378 {
379 ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, 379 ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
380 ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); 380 ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
381 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", 381 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
382 prim.LocalID, forceRebuild, prim.BSShape); 382 prim.LocalID, forceRebuild, prim.BSShape);
@@ -423,27 +423,37 @@ public class BSShapeCollection : IDisposable
423 BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey); 423 BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey);
424 424
425 // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. 425 // Don't need to do a 'ReferenceShape()' here because native shapes are not shared.
426 DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", 426 DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}",
427 shapeData.ID, newShape, shapeData.Scale); 427 shapeData.ID, newShape, shapeData.Scale);
428 428
429 prim.BSShape = newShape; 429 prim.BSShape = newShape;
430 return true; 430 return true;
431 } 431 }
432 432
433 private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType, 433 private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType,
434 ShapeData shapeData, ShapeData.FixedShapeKey shapeKey) 434 ShapeData shapeData, ShapeData.FixedShapeKey shapeKey)
435 { 435 {
436 BulletShape newShape; 436 BulletShape newShape;
437 // Need to make sure the passed shape information is for the native type.
438 ShapeData nativeShapeData = shapeData;
439 nativeShapeData.Type = shapeType;
440 nativeShapeData.MeshKey = (ulong)shapeKey;
441 nativeShapeData.HullKey = (ulong)shapeKey;
437 442
438 if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) 443 if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR)
439 { 444 {
440 newShape = new BulletShape( 445 newShape = new BulletShape(
441 BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1.0f, 1.0f, shapeData.Scale), 446 BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1.0f, 1.0f, nativeShapeData.Scale), shapeType);
442 shapeType); 447 DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale);
443 } 448 }
444 else 449 else
445 { 450 {
446 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); 451 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
452 }
453 if (newShape.ptr == IntPtr.Zero)
454 {
455 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
456 LogHeader, nativeShapeData.ID, nativeShapeData.Type);
447 } 457 }
448 newShape.shapeKey = (System.UInt64)shapeKey; 458 newShape.shapeKey = (System.UInt64)shapeKey;
449 newShape.isNativeShape = true; 459 newShape.isNativeShape = true;
@@ -698,19 +708,26 @@ public class BSShapeCollection : IDisposable
698 return ComputeShapeKey(shapeData, pbs, out lod); 708 return ComputeShapeKey(shapeData, pbs, out lod);
699 } 709 }
700 710
711 // The creation of a mesh or hull can fail if an underlying asset is not available.
712 // There are two cases: 1) the asset is not in the cache and it needs to be fetched;
713 // and 2) the asset cannot be converted (like decompressing JPEG2000s).
714 // The first case causes the asset to be fetched. The second case just requires
715 // us to not loop forever.
716 // Called after creating a physical mesh or hull. If the physical shape was created,
717 // just return.
701 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs) 718 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs)
702 { 719 {
703 // If the shape was successfully created, nothing more to do 720 // If the shape was successfully created, nothing more to do
704 if (newShape.ptr != IntPtr.Zero) 721 if (newShape.ptr != IntPtr.Zero)
705 return newShape; 722 return newShape;
706 723
707 // The most common reason for failure is that an underlying asset is not available
708
709 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset 724 // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset
710 if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero) 725 if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero)
711 { 726 {
712 prim.LastAssetBuildFailed = true; 727 prim.LastAssetBuildFailed = true;
713 BSPhysObject xprim = prim; 728 BSPhysObject xprim = prim;
729 DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
730 LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed);
714 Util.FireAndForget(delegate 731 Util.FireAndForget(delegate
715 { 732 {
716 RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; 733 RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
@@ -724,20 +741,28 @@ public class BSShapeCollection : IDisposable
724 if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) 741 if (yprim.BaseShape.SculptTexture.ToString() != asset.ID)
725 return; 742 return;
726 743
727 yprim.BaseShape.SculptData = new byte[asset.Data.Length]; 744 yprim.BaseShape.SculptData = asset.Data;
728 asset.Data.CopyTo(yprim.BaseShape.SculptData, 0);
729 // This will cause the prim to see that the filler shape is not the right 745 // This will cause the prim to see that the filler shape is not the right
730 // one and try again to build the object. 746 // one and try again to build the object.
747 // No race condition with the native sphere setting since the rebuild is at taint time.
731 yprim.ForceBodyShapeRebuild(false); 748 yprim.ForceBodyShapeRebuild(false);
732 749
733 }); 750 });
734 } 751 }
735 }); 752 });
736 } 753 }
754 else
755 {
756 if (prim.LastAssetBuildFailed)
757 {
758 PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
759 LogHeader, shapeData.ID, pbs.SculptTexture);
760 }
761 }
737 762
738 // While we figure out the real problem, stick a simple native shape on the object. 763 // While we figure out the real problem, stick a simple native shape on the object.
739 BulletShape fillinShape = 764 BulletShape fillinShape =
740 BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_SPHERE, shapeData, ShapeData.FixedShapeKey.KEY_SPHERE); 765 BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX);
741 766
742 return fillinShape; 767 return fillinShape;
743 } 768 }
@@ -746,7 +771,7 @@ public class BSShapeCollection : IDisposable
746 // Updates prim.BSBody with the information about the new body if one is created. 771 // Updates prim.BSBody with the information about the new body if one is created.
747 // Returns 'true' if an object was actually created. 772 // Returns 'true' if an object was actually created.
748 // Called at taint-time. 773 // Called at taint-time.
749 private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, 774 private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape,
750 ShapeData shapeData, BodyDestructionCallback bodyCallback) 775 ShapeData shapeData, BodyDestructionCallback bodyCallback)
751 { 776 {
752 bool ret = false; 777 bool ret = false;