From cc1781926b4c49c72977d4ddb16cc583a9ffeb80 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 31 Jan 2013 20:37:58 +0000 Subject: [PATCH] * Adds a satisfying angular roll when an avatar is flying and turning. (General, not physics). Makes flying not feel as stiff. Conflicts: OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs --- .../ClientStack/Linden/UDP/LLClientView.cs | 5 +- .../Region/Framework/Scenes/ScenePresence.cs | 81 +++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index fd82db703b..f2b016045b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4963,8 +4963,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP // in that direction, even though we don't model this on the server. Implementing this in the future // may improve movement smoothness. // acceleration = new Vector3(1, 0, 0); - - angularVelocity = Vector3.Zero; + + angularVelocity = presence.AngularVelocity; + rotation = presence.Rotation; if (sendTexture) textureEntry = presence.Appearance.Texture.GetBytes(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a9195f72fe..3e5f947d8f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -204,6 +204,11 @@ namespace OpenSim.Region.Framework.Scenes private const int LAND_VELOCITYMAG_MAX = 12; + private const float FLY_ROLL_MAX_RADIANS = 1.1f; + + private const float FLY_ROLL_RADIANS_PER_SECOND = 0.06f; + private const float FLY_ROLL_RESET_RADIANS_PER_SECOND = 0.02f; + private float m_health = 100f; protected ulong crossingFromRegion; @@ -606,6 +611,14 @@ namespace OpenSim.Region.Framework.Scenes } } + // Used for limited viewer 'fake' user rotations. + private Vector3 m_AngularVelocity = Vector3.Zero; + + public Vector3 AngularVelocity + { + get { return m_AngularVelocity; } + } + public bool IsChildAgent { get; set; } public bool IsLoggingIn { get; set; } @@ -736,6 +749,8 @@ namespace OpenSim.Region.Framework.Scenes #endregion + + #region Constructor(s) public ScenePresence( @@ -1225,6 +1240,49 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.StopFlying(this); } + /// + /// Applies a roll accumulator to the avatar's angular velocity for the avatar fly roll effect. + /// + /// Postive or negative roll amount in radians + private void ApplyFlyingRoll(float amount) + { + float noise = ((float)(Util.RandomClass.NextDouble()*0.2f)-0.1f); + float rollAmount = Util.Clamp(m_AngularVelocity.Z + amount, -FLY_ROLL_MAX_RADIANS, FLY_ROLL_MAX_RADIANS) + noise; + m_AngularVelocity.Z = rollAmount; + } + + /// + /// incrementally sets roll amount to zero + /// + /// Positive roll amount in radians + /// + private float CalculateFlyingRollResetToZero(float amount) + { + const float rollMinRadians = 0f; + + if (m_AngularVelocity.Z > 0) + { + + float leftOverToMin = m_AngularVelocity.Z - rollMinRadians; + if (amount > leftOverToMin) + return -leftOverToMin; + else + return -amount; + + } + else + { + + float leftOverToMin = -m_AngularVelocity.Z - rollMinRadians; + if (amount > leftOverToMin) + return leftOverToMin; + else + return amount; + } + } + + + // neighbouring regions we have enabled a child agent in // holds the seed cap for the child agent in that region private Dictionary m_knownChildRegions = new Dictionary(); @@ -1741,6 +1799,29 @@ namespace OpenSim.Region.Framework.Scenes bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + + + // Applies a satisfying roll effect to the avatar when flying. + if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) != 0) && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)) + { + ApplyFlyingRoll(FLY_ROLL_RADIANS_PER_SECOND); + + } + else if (((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0) && + ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)) + { + ApplyFlyingRoll(-FLY_ROLL_RADIANS_PER_SECOND); + + } + else + { + if (m_AngularVelocity.Z != 0) + m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_SECOND); + + } + + + if (Flying && IsColliding && controlland) { // nesting this check because LengthSquared() is expensive and we don't