diff options
author | Robert Adams | 2015-08-09 15:36:50 -0700 |
---|---|---|
committer | Robert Adams | 2015-08-09 15:36:50 -0700 |
commit | fe37cb999055c0df27a3fc1e038013575a63e2ea (patch) | |
tree | 341307fa0ad9aee33a319cbb6c4d82a0f7cebe16 /OpenSim/Region/Physics | |
parent | BulletSim: update the motion actors so they completely clean themselves (diff) | |
download | opensim-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.cs | 4 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | 28 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 51 |
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. |