From e4d0ae4f6e89afaf5ce3f9b7783eb20a50dc758c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Mon, 30 Nov 2015 20:51:12 -0800 Subject: [PATCH] BulletSim: fix collision sound calculation. Modify some routines to make collider and collidee clearer. Also fix (when did it break?) avatars not moving if standing on a moving object. Now friction will move avatars if standing on a disc or the top of a train. --- .../PhysicsModules/BulletS/BSLinkset.cs | 2 +- .../PhysicsModules/BulletS/BSPhysObject.cs | 36 +++++++++++-------- .../PhysicsModules/BulletS/BSPrimLinkable.cs | 7 ++-- .../Region/PhysicsModules/BulletS/BSScene.cs | 2 +- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs index 83122398e2..e73f0e8738 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSLinkset.cs @@ -257,7 +257,7 @@ public abstract class BSLinkset // Return 'true' if linkset processed the collision. 'false' says the linkset didn't have // anything to add for the collision and it should be passed through normal processing. // Default processing for a linkset. - public virtual bool HandleCollide(uint collidingWith, BSPhysObject collidee, + public virtual bool HandleCollide(BSPhysObject collider, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs index 6adf219e32..0ad95c4a0d 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPhysObject.cs @@ -452,18 +452,20 @@ public abstract class BSPhysObject : PhysicsActor private long CollisionsLastTickStep = -1; // The simulation step is telling this object about a collision. + // I'm the 'collider', the thing I'm colliding with is the 'collidee'. // Return 'true' if a collision was processed and should be sent up. // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision. // Called at taint time from within the Step() function - public delegate bool CollideCall(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth); - public virtual bool Collide(uint collidingWith, BSPhysObject collidee, - OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + public virtual bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; + // if 'collidee' is null, that means it is terrain + uint collideeLocalID = (collidee == null) ? PhysScene.TerrainManager.HighestTerrainID : collidee.LocalID; + // The following lines make IsColliding(), CollidingGround() and CollidingObj work CollidingStep = PhysScene.SimulationStep; - if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID) + if (collideeLocalID <= PhysScene.TerrainManager.HighestTerrainID) { CollidingGroundStep = PhysScene.SimulationStep; } @@ -474,10 +476,13 @@ public abstract class BSPhysObject : PhysicsActor CollisionAccumulation++; - // For movement tests, remember if we are colliding with an object that is moving. - ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false; + // For movement tests, if the collider is me, remember if we are colliding with an object that is moving. + // Here the 'collider'/'collidee' thing gets messed up. In the larger context, when something is checking + // if the thing it is colliding with is moving, for instance, it asks if the its collider is moving. + ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero || collidee.RotationalVelocity != OMV.Vector3.Zero) : false; ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false; + // Make a collection of the collisions that happened the last simulation tick. // This is different than the collection created for sending up to the simulator as it is cleared every tick. if (CollisionsLastTickStep != PhysScene.SimulationStep) @@ -485,23 +490,26 @@ public abstract class BSPhysObject : PhysicsActor CollisionsLastTick = new CollisionEventUpdate(); CollisionsLastTickStep = PhysScene.SimulationStep; } - - CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); + CollisionsLastTick.AddCollider(collideeLocalID, new ContactPoint(contactPoint, contactNormal, pentrationDepth)); // If someone has subscribed for collision events log the collision so it will be reported up if (SubscribedEvents()) { ContactPoint newContact = new ContactPoint(contactPoint, contactNormal, pentrationDepth); - // make collision sound work just setting a speed - // see ubOde - newContact.RelativeSpeed = 2.0f; - + // Collision sound requires a velocity to know it should happen. This is a lot of computation for a little used feature. + OMV.Vector3 relvel = OMV.Vector3.Zero; + if (IsPhysical) + relvel = Velocity; + if (collidee != null && collidee.IsPhysical) + relvel -= collidee.Velocity; + newContact.RelativeSpeed = OMV.Vector3.Dot(relvel, contactNormal); + lock (PhysScene.CollisionLock) { - CollisionCollection.AddCollider(collidingWith, newContact); + CollisionCollection.AddCollider(collideeLocalID, newContact); } DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}", - LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); + LocalID, TypeName, collideeLocalID, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving); ret = true; } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs index 55b5da09c9..563dcfaa22 100755 --- a/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSPrimLinkable.cs @@ -203,15 +203,14 @@ public class BSPrimLinkable : BSPrimDisplaced // Called after a simulation step to post a collision with this object. // This returns 'true' if the collision has been queued and the SendCollisions call must // be made at the end of the simulation step. - public override bool Collide(uint collidingWith, BSPhysObject collidee, - OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) + public override bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth) { bool ret = false; // Ask the linkset if it wants to handle the collision - if (!Linkset.HandleCollide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth)) + if (!Linkset.HandleCollide(this, collidee, contactPoint, contactNormal, pentrationDepth)) { // The linkset didn't handle it so pass the collision through normal processing - ret = base.Collide(collidingWith, collidee, contactPoint, contactNormal, pentrationDepth); + ret = base.Collide(collidee, contactPoint, contactNormal, pentrationDepth); } return ret; } diff --git a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs index b2d5e474f8..f02104c5fb 100644 --- a/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs +++ b/OpenSim/Region/PhysicsModules/BulletS/BSScene.cs @@ -880,7 +880,7 @@ namespace OpenSim.Region.PhysicsModule.BulletS if (collider.IsInitialized) { - if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration)) + if (collider.Collide(collidee, collidePoint, collideNormal, penetration)) { // If a collision was 'good', remember to send it to the simulator lock (CollisionLock)