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.cs69
1 files changed, 47 insertions, 22 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs
index d3ba273..30fa50a 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,9 +335,10 @@ 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 ret = true;
341 haveShape = true; 342 haveShape = true;
342 } 343 }
343 // If the prim attributes are simple, this could be a simple Bullet native shape 344 // If the prim attributes are simple, this could be a simple Bullet native shape
@@ -362,7 +363,7 @@ public class BSShapeCollection : IDisposable
362 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE 363 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE
363 ) 364 )
364 { 365 {
365 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, 366 ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE,
366 ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); 367 ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback);
367 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", 368 DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}",
368 prim.LocalID, forceRebuild, prim.BSShape); 369 prim.LocalID, forceRebuild, prim.BSShape);
@@ -376,7 +377,7 @@ public class BSShapeCollection : IDisposable
376 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX 377 || prim.BSShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX
377 ) 378 )
378 { 379 {
379 ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, 380 ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX,
380 ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); 381 ShapeData.FixedShapeKey.KEY_BOX, shapeCallback);
381 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", 382 DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}",
382 prim.LocalID, forceRebuild, prim.BSShape); 383 prim.LocalID, forceRebuild, prim.BSShape);
@@ -411,39 +412,49 @@ public class BSShapeCollection : IDisposable
411 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, 412 ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey,
412 ShapeDestructionCallback shapeCallback) 413 ShapeDestructionCallback shapeCallback)
413 { 414 {
415 // release any previous shape
416 DereferenceShape(prim.BSShape, true, shapeCallback);
414 417
415 shapeData.Type = shapeType; 418 shapeData.Type = shapeType;
416 // Bullet native objects are scaled by the Bullet engine so pass the size in 419 // Bullet native objects are scaled by the Bullet engine so pass the size in
417 prim.Scale = shapeData.Size; 420 prim.Scale = shapeData.Size;
418 shapeData.Scale = shapeData.Size; 421 shapeData.Scale = shapeData.Size;
419 422
420 // release any previous shape
421 DereferenceShape(prim.BSShape, true, shapeCallback);
422
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, 1f, 1f, nativeShapeData.Scale)
442 shapeType); 447 , shapeType);
448 DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale);
443 } 449 }
444 else 450 else
445 { 451 {
446 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, shapeData), shapeType); 452 newShape = new BulletShape(BulletSimAPI.BuildNativeShape2(PhysicsScene.World.ptr, nativeShapeData), shapeType);
453 }
454 if (newShape.ptr == IntPtr.Zero)
455 {
456 PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}",
457 LogHeader, nativeShapeData.ID, nativeShapeData.Type);
447 } 458 }
448 newShape.shapeKey = (System.UInt64)shapeKey; 459 newShape.shapeKey = (System.UInt64)shapeKey;
449 newShape.isNativeShape = true; 460 newShape.isNativeShape = true;
@@ -698,19 +709,26 @@ public class BSShapeCollection : IDisposable
698 return ComputeShapeKey(shapeData, pbs, out lod); 709 return ComputeShapeKey(shapeData, pbs, out lod);
699 } 710 }
700 711
712 // The creation of a mesh or hull can fail if an underlying asset is not available.
713 // There are two cases: 1) the asset is not in the cache and it needs to be fetched;
714 // and 2) the asset cannot be converted (like decompressing JPEG2000s).
715 // The first case causes the asset to be fetched. The second case just requires
716 // us to not loop forever.
717 // Called after creating a physical mesh or hull. If the physical shape was created,
718 // just return.
701 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs) 719 private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs)
702 { 720 {
703 // If the shape was successfully created, nothing more to do 721 // If the shape was successfully created, nothing more to do
704 if (newShape.ptr != IntPtr.Zero) 722 if (newShape.ptr != IntPtr.Zero)
705 return newShape; 723 return newShape;
706 724
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 725 // 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) 726 if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero)
711 { 727 {
712 prim.LastAssetBuildFailed = true; 728 prim.LastAssetBuildFailed = true;
713 BSPhysObject xprim = prim; 729 BSPhysObject xprim = prim;
730 DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}",
731 LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed);
714 Util.FireAndForget(delegate 732 Util.FireAndForget(delegate
715 { 733 {
716 RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; 734 RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod;
@@ -724,20 +742,28 @@ public class BSShapeCollection : IDisposable
724 if (yprim.BaseShape.SculptTexture.ToString() != asset.ID) 742 if (yprim.BaseShape.SculptTexture.ToString() != asset.ID)
725 return; 743 return;
726 744
727 yprim.BaseShape.SculptData = new byte[asset.Data.Length]; 745 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 746 // This will cause the prim to see that the filler shape is not the right
730 // one and try again to build the object. 747 // one and try again to build the object.
748 // No race condition with the native sphere setting since the rebuild is at taint time.
731 yprim.ForceBodyShapeRebuild(false); 749 yprim.ForceBodyShapeRebuild(false);
732 750
733 }); 751 });
734 } 752 }
735 }); 753 });
736 } 754 }
755 else
756 {
757 if (prim.LastAssetBuildFailed)
758 {
759 PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}",
760 LogHeader, shapeData.ID, pbs.SculptTexture);
761 }
762 }
737 763
738 // While we figure out the real problem, stick a simple native shape on the object. 764 // While we figure out the real problem, stick a simple native shape on the object.
739 BulletShape fillinShape = 765 BulletShape fillinShape =
740 BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_SPHERE, shapeData, ShapeData.FixedShapeKey.KEY_SPHERE); 766 BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX);
741 767
742 return fillinShape; 768 return fillinShape;
743 } 769 }
@@ -746,7 +772,7 @@ public class BSShapeCollection : IDisposable
746 // Updates prim.BSBody with the information about the new body if one is created. 772 // Updates prim.BSBody with the information about the new body if one is created.
747 // Returns 'true' if an object was actually created. 773 // Returns 'true' if an object was actually created.
748 // Called at taint-time. 774 // Called at taint-time.
749 private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, 775 private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape,
750 ShapeData shapeData, BodyDestructionCallback bodyCallback) 776 ShapeData shapeData, BodyDestructionCallback bodyCallback)
751 { 777 {
752 bool ret = false; 778 bool ret = false;
@@ -765,7 +791,6 @@ public class BSShapeCollection : IDisposable
765 // If the collisionObject is not the correct type for solidness, rebuild what's there 791 // If the collisionObject is not the correct type for solidness, rebuild what's there
766 mustRebuild = true; 792 mustRebuild = true;
767 } 793 }
768
769 } 794 }
770 795
771 if (mustRebuild || forceRebuild) 796 if (mustRebuild || forceRebuild)