From 7c4e0ff03c5ba9331feb777247594e94fc0f7ac1 Mon Sep 17 00:00:00 2001 From: teravus Date: Wed, 30 Jan 2013 06:22:05 -0500 Subject: [PATCH] * Adds a satisfying angular roll when an avatar is flying and turning. (General, not physics). Makes flying not feel as stiff. --- .../ClientStack/Linden/UDP/LLClientView.cs | 2 +- .../Region/Framework/Scenes/ScenePresence.cs | 81 +++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 0ccd69a70b..88b64f5f66 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4893,7 +4893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // may improve movement smoothness. // acceleration = new Vector3(1, 0, 0); - angularVelocity = Vector3.Zero; + angularVelocity = presence.AngularVelocity; rotation = presence.Rotation; if (sendTexture) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a90872e541..1d22560f3d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -200,6 +200,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; @@ -568,6 +573,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; } /// @@ -690,6 +703,8 @@ namespace OpenSim.Region.Framework.Scenes #endregion + + #region Constructor(s) public ScenePresence( @@ -1033,6 +1048,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(); @@ -1513,6 +1571,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