aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Physics
diff options
context:
space:
mode:
authorRobert Adams2015-08-09 15:36:50 -0700
committerRobert Adams2015-08-09 15:36:50 -0700
commitfe37cb999055c0df27a3fc1e038013575a63e2ea (patch)
tree341307fa0ad9aee33a319cbb6c4d82a0f7cebe16 /OpenSim/Region/Physics
parentBulletSim: update the motion actors so they completely clean themselves (diff)
downloadopensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.zip
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.gz
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.bz2
opensim-SC-fe37cb999055c0df27a3fc1e038013575a63e2ea.tar.xz
BulletSim: rearrange code and add different locking to eliminate chances
of race conditions and, especially, race conditions when an object is removed and quickly re-added to a scene. This hopefully reduces the occurance of problems when avatars TP within a region -- the main problem being the loss of collisions.
Diffstat (limited to 'OpenSim/Region/Physics')
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs4
-rwxr-xr-xOpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs28
-rw-r--r--OpenSim/Region/Physics/BulletSPlugin/BSScene.cs51
3 files changed, 40 insertions, 43 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index d0cc1eb..9c3f160 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -459,7 +459,7 @@ public sealed class BSCharacter : BSPhysObject
459 RawVelocity = value; 459 RawVelocity = value;
460 OMV.Vector3 vel = RawVelocity; 460 OMV.Vector3 vel = RawVelocity;
461 461
462 DetailLog("{0}: set Velocity = {1}", LogHeader, value); 462 DetailLog("{0}: set Velocity = {1}", LocalID, value);
463 463
464 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate() 464 PhysScene.TaintedObject(LocalID, "BSCharacter.setVelocity", delegate()
465 { 465 {
@@ -477,7 +477,7 @@ public sealed class BSCharacter : BSPhysObject
477 set { 477 set {
478 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity"); 478 PhysScene.AssertInTaintTime("BSCharacter.ForceVelocity");
479// Util.PrintCallStack(); 479// Util.PrintCallStack();
480 DetailLog("{0}: set ForceVelocity = {1}", LogHeader, value); 480 DetailLog("{0}: set ForceVelocity = {1}", LocalID, value);
481 481
482 RawVelocity = value; 482 RawVelocity = value;
483 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity); 483 PhysScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
index b758408..90da7a6 100755
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs
@@ -80,12 +80,13 @@ public abstract class BSPhysObject : PhysicsActor
80 Name = name; // PhysicsActor also has the name of the object. Someday consolidate. 80 Name = name; // PhysicsActor also has the name of the object. Someday consolidate.
81 TypeName = typeName; 81 TypeName = typeName;
82 82
83 // The collection of things that push me around 83 // Oddity if object is destroyed and recreated very quickly it could still have the old body.
84 PhysicalActors = new BSActorCollection(PhysScene); 84 if (!PhysBody.HasPhysicalBody)
85 PhysBody = new BulletBody(localID);
85 86
86 // We don't have any physical representation yet. 87 // Clean out anything that might be in the physical actor list.
87 PhysBody = new BulletBody(localID); 88 // Again, a workaround for destroying and recreating an object very quickly.
88 PhysShape = new BSShapeNull(); 89 PhysicalActors.Dispose();
89 90
90 UserSetCenterOfMassDisplacement = null; 91 UserSetCenterOfMassDisplacement = null;
91 92
@@ -100,9 +101,6 @@ public abstract class BSPhysObject : PhysicsActor
100 // Default material type. Also sets Friction, Restitution and Density. 101 // Default material type. Also sets Friction, Restitution and Density.
101 SetMaterial((int)MaterialAttributes.Material.Wood); 102 SetMaterial((int)MaterialAttributes.Material.Wood);
102 103
103 CollisionCollection = new CollisionEventUpdate();
104 CollisionsLastReported = CollisionCollection;
105 CollisionsLastTick = new CollisionEventUpdate();
106 CollisionsLastTickStep = -1; 104 CollisionsLastTickStep = -1;
107 105
108 SubscribedEventsMs = 0; 106 SubscribedEventsMs = 0;
@@ -158,9 +156,9 @@ public abstract class BSPhysObject : PhysicsActor
158 public OMV.Vector3 Inertia { get; set; } 156 public OMV.Vector3 Inertia { get; set; }
159 157
160 // Reference to the physical body (btCollisionObject) of this object 158 // Reference to the physical body (btCollisionObject) of this object
161 public BulletBody PhysBody; 159 public BulletBody PhysBody = new BulletBody(0);
162 // Reference to the physical shape (btCollisionShape) of this object 160 // Reference to the physical shape (btCollisionShape) of this object
163 public BSShape PhysShape; 161 public BSShape PhysShape = new BSShapeNull();
164 162
165 // The physical representation of the prim might require an asset fetch. 163 // The physical representation of the prim might require an asset fetch.
166 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'. 164 // The asset state is first 'Unknown' then 'Waiting' then either 'Failed' or 'Fetched'.
@@ -445,12 +443,12 @@ public abstract class BSPhysObject : PhysicsActor
445 } 443 }
446 444
447 // The collisions that have been collected for the next collision reporting (throttled by subscription) 445 // The collisions that have been collected for the next collision reporting (throttled by subscription)
448 protected CollisionEventUpdate CollisionCollection; 446 protected CollisionEventUpdate CollisionCollection = new CollisionEventUpdate();
449 // This is the collision collection last reported to the Simulator. 447 // This is the collision collection last reported to the Simulator.
450 public CollisionEventUpdate CollisionsLastReported; 448 public CollisionEventUpdate CollisionsLastReported = new CollisionEventUpdate();
451 // Remember the collisions recorded in the last tick for fancy collision checking 449 // Remember the collisions recorded in the last tick for fancy collision checking
452 // (like a BSCharacter walking up stairs). 450 // (like a BSCharacter walking up stairs).
453 public CollisionEventUpdate CollisionsLastTick; 451 public CollisionEventUpdate CollisionsLastTick = new CollisionEventUpdate();
454 private long CollisionsLastTickStep = -1; 452 private long CollisionsLastTickStep = -1;
455 453
456 // The simulation step is telling this object about a collision. 454 // The simulation step is telling this object about a collision.
@@ -495,7 +493,7 @@ public abstract class BSPhysObject : PhysicsActor
495 { 493 {
496 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); 494 CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
497 } 495 }
498 DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", 496 DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
499 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); 497 LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);
500 498
501 ret = true; 499 ret = true;
@@ -596,7 +594,7 @@ public abstract class BSPhysObject : PhysicsActor
596 594
597 #region Per Simulation Step actions 595 #region Per Simulation Step actions
598 596
599 public BSActorCollection PhysicalActors; 597 public BSActorCollection PhysicalActors = new BSActorCollection();
600 598
601 // When an update to the physical properties happens, this event is fired to let 599 // When an update to the physical properties happens, this event is fired to let
602 // different actors to modify the update before it is passed around 600 // different actors to modify the update before it is passed around
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index f8e8f57..1a95f91 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -76,7 +76,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
76 76
77 // Keep track of all the avatars so we can send them a collision event 77 // Keep track of all the avatars so we can send them a collision event
78 // every tick so OpenSim will update its animation. 78 // every tick so OpenSim will update its animation.
79 private HashSet<BSPhysObject> m_avatars = new HashSet<BSPhysObject>(); 79 private HashSet<BSPhysObject> AvatarsInScene = new HashSet<BSPhysObject>();
80 private Object AvatarsInSceneLock = new Object();
80 81
81 // let my minuions use my logger 82 // let my minuions use my logger
82 public ILog Logger { get { return m_log; } } 83 public ILog Logger { get { return m_log; } }
@@ -425,11 +426,14 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
425 // make sure no stepping happens while we're deleting stuff 426 // make sure no stepping happens while we're deleting stuff
426 m_initialized = false; 427 m_initialized = false;
427 428
428 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects) 429 lock (PhysObjects)
429 { 430 {
430 kvp.Value.Destroy(); 431 foreach (KeyValuePair<uint, BSPhysObject> kvp in PhysObjects)
432 {
433 kvp.Value.Destroy();
434 }
435 PhysObjects.Clear();
431 } 436 }
432 PhysObjects.Clear();
433 437
434 // Now that the prims are all cleaned up, there should be no constraints left 438 // Now that the prims are all cleaned up, there should be no constraints left
435 if (Constraints != null) 439 if (Constraints != null)
@@ -480,15 +484,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
480 // TODO: Remove kludge someday. 484 // TODO: Remove kludge someday.
481 // We must generate a collision for avatars whether they collide or not. 485 // We must generate a collision for avatars whether they collide or not.
482 // This is required by OpenSim to update avatar animations, etc. 486 // This is required by OpenSim to update avatar animations, etc.
483 lock (m_avatars) 487 lock (AvatarsInSceneLock)
484 { 488 AvatarsInScene.Add(actor);
485 // The funky copy is because this list has few and infrequent changes but is
486 // read zillions of times. This allows the reader/iterator to use the
487 // list and this creates a new list with any updates.
488 HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars);
489 avatarTemp.Add(actor);
490 m_avatars = avatarTemp;
491 }
492 489
493 return actor; 490 return actor;
494 } 491 }
@@ -507,12 +504,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
507 lock (PhysObjects) 504 lock (PhysObjects)
508 PhysObjects.Remove(bsactor.LocalID); 505 PhysObjects.Remove(bsactor.LocalID);
509 // Remove kludge someday 506 // Remove kludge someday
510 lock (m_avatars) 507 lock (AvatarsInSceneLock)
511 { 508 AvatarsInScene.Remove(bsactor);
512 HashSet<BSPhysObject> avatarTemp = new HashSet<BSPhysObject>(m_avatars);
513 avatarTemp.Remove(bsactor);
514 m_avatars = avatarTemp;
515 }
516 } 509 }
517 catch (Exception e) 510 catch (Exception e)
518 { 511 {
@@ -757,13 +750,18 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
757 // The simulator expects collisions for avatars even if there are have been no collisions. 750 // The simulator expects collisions for avatars even if there are have been no collisions.
758 // The event updates avatar animations and stuff. 751 // The event updates avatar animations and stuff.
759 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen. 752 // If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
760 // Note that we copy the root of the list to search. Any updates will create a new list 753 // Note that we get a copy of the list to search because SendCollision() can take a while.
761 // thus freeing this code from having to do an extra lock for every collision. 754 HashSet<BSPhysObject> tempAvatarsInScene;
762 HashSet<BSPhysObject> avatarTemp = m_avatars; 755 lock (AvatarsInSceneLock)
763 foreach (BSPhysObject bsp in avatarTemp) 756 {
764 if (!ObjectsWithCollisions.Contains(bsp)) // don't call avatars twice 757 tempAvatarsInScene = new HashSet<BSPhysObject>(AvatarsInScene);
765 bsp.SendCollisions(); 758 }
766 avatarTemp = null; 759 foreach (BSPhysObject actor in tempAvatarsInScene)
760 {
761 if (!ObjectsWithCollisions.Contains(actor)) // don't call avatars twice
762 actor.SendCollisions();
763 }
764 tempAvatarsInScene = null;
767 765
768 // Objects that are done colliding are removed from the ObjectsWithCollisions list. 766 // Objects that are done colliding are removed from the ObjectsWithCollisions list.
769 // Not done above because it is inside an iteration of ObjectWithCollisions. 767 // Not done above because it is inside an iteration of ObjectWithCollisions.
@@ -813,6 +811,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
813 } 811 }
814 812
815 BSPhysObject collider; 813 BSPhysObject collider;
814 // NOTE that PhysObjects was locked before the call to SendCollision().
816 if (!PhysObjects.TryGetValue(localID, out collider)) 815 if (!PhysObjects.TryGetValue(localID, out collider))
817 { 816 {
818 // If the object that is colliding cannot be found, just ignore the collision. 817 // If the object that is colliding cannot be found, just ignore the collision.