From fcc276a68da1da15fac802725a116b3e8d7f7197 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 8 Nov 2007 15:22:36 +0000 Subject: [PATCH] * Fixed occasional character drift caused by sim not sending the avatar's final resting velocity. * Added Smooth moving prim * Added event to PhysicsActor RequestPhysicsterseUpdate to allow physics plugins to be able to schedule a terse update. --- .../Environment/Scenes/SceneObjectPart.cs | 12 +++ .../Environment/Scenes/ScenePresence.cs | 2 + .../Region/Physics/Manager/PhysicsActor.cs | 20 +++- OpenSim/Region/Physics/OdePlugin/OdePlugin.cs | 93 ++++++++++++++++--- 4 files changed, 111 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 0e2b1860d7..f54b52f3db 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -782,10 +782,15 @@ namespace OpenSim.Region.Environment.Scenes if (UsePhysics) { AddFlag(LLObject.ObjectFlags.Physics); + if (PhysActor != null) + PhysActor.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; + } else { RemFlag(LLObject.ObjectFlags.Physics); + if (PhysActor != null) + PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate; } if (IsPhantom) @@ -1067,6 +1072,13 @@ namespace OpenSim.Region.Environment.Scenes public virtual void UpdateMovement() { } + #region Events + public void PhysicsRequestingTerseUpdate() + { + SendTerseUpdateToAllClients(); + } + #endregion + public virtual void OnGrab(LLVector3 offsetPos, IClientAPI remoteClient) { diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 789bd68a1c..608efc3568 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -386,6 +386,7 @@ namespace OpenSim.Region.Environment.Scenes if (PhysicsActor != null) { m_scene.PhysScene.RemoveAvatar(PhysicsActor); + m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; PhysicsActor = null; } } @@ -1092,6 +1093,7 @@ namespace OpenSim.Region.Environment.Scenes AbsolutePosition.Z); m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec); + m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; } internal void Close() diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 2d8eb9afe9..049da965a3 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -36,14 +36,19 @@ namespace OpenSim.Region.Physics.Manager public delegate void OrientationUpdate(Quaternion orientation); + + public abstract class PhysicsActor - { + { + public delegate void RequestTerseUpdate(); + #pragma warning disable 67 public event PositionUpdate OnPositionUpdate; public event VelocityUpdate OnVelocityUpdate; public event OrientationUpdate OnOrientationUpdate; + public event RequestTerseUpdate OnRequestTerseUpdate; #pragma warning restore 67 public static PhysicsActor Null @@ -57,6 +62,19 @@ namespace OpenSim.Region.Physics.Manager { set; } + public virtual void RequestPhysicsterseUpdate() + { + // Make a temporary copy of the event to avoid possibility of + // a race condition if the last subscriber unsubscribes + // immediately after the null check and before the event is raised. + RequestTerseUpdate handler = OnRequestTerseUpdate; + if (handler != null) + { + OnRequestTerseUpdate(); + } + + } + public abstract PhysicsVector Position { get; set; } diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs index 512b96e206..b6c63afe76 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs @@ -217,21 +217,18 @@ namespace OpenSim.Region.Physics.OdePlugin private void collision_optimized(float timeStep) { - foreach (OdeCharacter chr in _characters) - { - chr.IsColliding = false; - } + foreach (OdeCharacter chr in _characters) { - + chr.IsColliding = false; d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); foreach (OdeCharacter ch2 in _characters) /// should be a separate space -- lots of avatars will be N**2 slow { - + d.SpaceCollide2(chr.Shell, ch2.Shell, IntPtr.Zero, nearCallback); } @@ -614,6 +611,7 @@ namespace OpenSim.Region.Physics.OdePlugin private PhysicsVector _position; private d.Vector3 _zeroPosition; private bool _zeroFlag = false; + private bool m_lastUpdateSent = false; private PhysicsVector _velocity; private PhysicsVector _target_velocity; private PhysicsVector _acceleration; @@ -624,7 +622,10 @@ namespace OpenSim.Region.Physics.OdePlugin public static float CAPSULE_RADIUS = 0.5f; public static float CAPSULE_LENGTH = 0.79f; private bool flying = false; - private bool iscolliding = false; + private bool m_iscolliding = false; + + private bool[] m_colliderarr = new bool[10]; + private bool jumping = false; //private float gravityAccel; public IntPtr Body; @@ -640,6 +641,12 @@ namespace OpenSim.Region.Physics.OdePlugin _position = pos; _acceleration = new PhysicsVector(); _parent_scene = parent_scene; + + for (int i = 0; i < 10; i++) + { + m_colliderarr[i] = false; + } + lock (OdeScene.OdeLock) { @@ -667,11 +674,48 @@ namespace OpenSim.Region.Physics.OdePlugin } public override bool IsColliding { - get { return iscolliding; } + + get { return m_iscolliding; } set - {iscolliding = value;} + { + int i; + int truecount=0; + int falsecount=0; + + if (m_colliderarr.Length >= 6) + { + for (i = 0; i < 6; i++) + { + m_colliderarr[i] = m_colliderarr[i + 1]; + } + } + m_colliderarr[6] = value; + + for (i = 0; i < 7; i++) + { + if (m_colliderarr[i]) + { + truecount++; + } + else + { + falsecount++; + } + } + + // Equal truecounts and false counts means we're colliding with something. + + if (falsecount > truecount) + { + m_iscolliding = false; + } + else + { + m_iscolliding = true; + } + } } - public override PhysicsVector Position + public override PhysicsVector Position { get { return _position; } set @@ -737,7 +781,7 @@ namespace OpenSim.Region.Physics.OdePlugin _target_velocity.Y += force.Y; _target_velocity.Z += force.Z; - + //m_lastUpdateSent = false; } public void doForce(PhysicsVector force) { @@ -756,6 +800,8 @@ namespace OpenSim.Region.Physics.OdePlugin float servo = (2.5f - posture) * POSTURE_SERVO; d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); + //m_lastUpdateSent = false; + } } @@ -771,7 +817,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.Vector3 vel = d.BodyGetLinearVel(Body); // if velocity is zero, use position control; otherwise, velocity control - if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && iscolliding) + if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding) { // keep track of where we stopped. No more slippin' & slidin' if (!_zeroFlag) @@ -791,12 +837,12 @@ namespace OpenSim.Region.Physics.OdePlugin { _zeroFlag = false; - if (iscolliding || flying) + if (m_iscolliding || flying) { vec.X = (_target_velocity.X - vel.X) * PID_D; vec.Y = (_target_velocity.Y - vel.Y) * PID_D; } - if (iscolliding && !flying && _target_velocity.Z > 0.0f) + if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) { d.Vector3 pos = d.BodyGetPosition(Body); vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; @@ -836,9 +882,16 @@ namespace OpenSim.Region.Physics.OdePlugin _velocity.X = 0.0f; _velocity.Y = 0.0f; _velocity.Z = 0.0f; + if (!m_lastUpdateSent) + { + m_lastUpdateSent = true; + base.RequestPhysicsterseUpdate(); + + } } else { + m_lastUpdateSent = false; vec = d.BodyGetLinearVel(Body); _velocity.X = (vec.X); _velocity.Y = (vec.Y); @@ -875,7 +928,10 @@ namespace OpenSim.Region.Physics.OdePlugin public IntPtr _triMeshData; private bool iscolliding = false; private bool m_isphysical = false; + public bool _zeroFlag = false; + private bool m_lastUpdateSent = false; + public IntPtr Body = (IntPtr) 0; private String m_primName; private PhysicsVector _target_velocity; @@ -1281,6 +1337,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } + IsPhysical = false; _velocity.X = 0; _velocity.Y = 0; @@ -1288,15 +1345,20 @@ namespace OpenSim.Region.Physics.OdePlugin m_rotationalVelocity.X = 0; m_rotationalVelocity.Y = 0; m_rotationalVelocity.Z = 0; + base.RequestPhysicsterseUpdate(); _zeroFlag = true; } - if (m_lastposition == l_position) + if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) + && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) + && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02 )) { + _zeroFlag = true; } else { + System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString()); _zeroFlag = false; } m_lastposition = l_position; @@ -1337,6 +1399,7 @@ namespace OpenSim.Region.Physics.OdePlugin _orientation.x = ori.X; _orientation.y = ori.Y; _orientation.z = ori.Z; + base.RequestPhysicsterseUpdate(); } }