diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 3b5a5bd6f2..5beee7371d 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -403,11 +403,18 @@ namespace OpenSim.Region.Framework.Scenes.Animation
Falling = false;
// Walking / crouchwalking / running
if (move.Z < 0f)
+ {
return "CROUCHWALK";
- else if (m_scenePresence.SetAlwaysRun)
- return "RUN";
- else
- return "WALK";
+ }
+ // We need to prevent these animations if the user tries to make their avatar walk or run whilst
+ // specifying AGENT_CONTROL_STOP (pressing down space on viewers).
+ else if (!m_scenePresence.AgentControlStopActive)
+ {
+ if (m_scenePresence.SetAlwaysRun)
+ return "RUN";
+ else
+ return "WALK";
+ }
}
else if (!m_jumping)
{
@@ -435,6 +442,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation
/// 'true' if the animation was changed
public bool UpdateMovementAnimations()
{
+// m_log.DebugFormat("[SCENE PRESENCE ANIMATOR]: Updating movement animations for {0}", m_scenePresence.Name);
+
bool ret = false;
lock (m_animations)
{
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a34c44ccca..7a6a334f2d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -355,6 +355,11 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_updateflag;
+ ///
+ /// Is the agent stop control flag currently active?
+ ///
+ public bool AgentControlStopActive { get; private set; }
+
public bool Updated
{
set { m_updateflag = value; }
@@ -768,6 +773,14 @@ namespace OpenSim.Region.Framework.Scenes
set { m_speedModifier = value; }
}
+ ///
+ /// Modifier for agent movement if we get an AGENT_CONTROL_STOP whilst walking or running
+ ///
+ ///
+ /// AGENT_CONTRL_STOP comes about if user holds down space key on viewers.
+ ///
+ private float AgentControlStopSlowWhilstMoving = 0.5f;
+
private bool m_forceFly;
public bool ForceFly
@@ -1634,7 +1647,6 @@ namespace OpenSim.Region.Framework.Scenes
if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
ControllingClient.SendAgentTerseUpdate(this);
-
PhysicsActor actor = PhysicsActor;
if (actor == null)
{
@@ -1712,7 +1724,7 @@ namespace OpenSim.Region.Framework.Scenes
// Why did I get this?
}
- if ((MovementFlag & (uint)DCF) == 0)
+ if (((MovementFlag & (uint)DCF) == 0) & !AgentControlStopActive)
{
//m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
MovementFlag += (uint)DCF;
@@ -1744,6 +1756,13 @@ namespace OpenSim.Region.Framework.Scenes
i++;
}
+ // Detect AGENT_CONTROL_STOP state changes
+ if (AgentControlStopActive != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STOP) != 0))
+ {
+ AgentControlStopActive = !AgentControlStopActive;
+ update_movementflag = true;
+ }
+
if (MovingToTarget)
{
// If the user has pressed a key then we want to cancel any move to target.
@@ -1769,53 +1788,79 @@ namespace OpenSim.Region.Framework.Scenes
// Only do this if we're flying
if (Flying && !ForceFly)
{
- // Landing detection code
-
- // Are the landing controls requirements filled?
- bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
- ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
-
- //m_log.Debug("[CONTROL]: " +flags);
- // 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)
+ // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
+ if (AgentControlStopActive)
{
- ApplyFlyingRoll(
- FLY_ROLL_RADIANS_PER_UPDATE,
- (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
- (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
- }
- else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
- (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
- {
- ApplyFlyingRoll(
- -FLY_ROLL_RADIANS_PER_UPDATE,
- (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
- (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
+ agent_control_v3 = Vector3.Zero;
}
else
{
- if (m_AngularVelocity.Z != 0)
- m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
- }
+ // Landing detection code
- if (Flying && IsColliding && controlland)
- {
- // nesting this check because LengthSquared() is expensive and we don't
- // want to do it every step when flying.
- if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
- StopFlying();
+ // Are the landing controls requirements filled?
+ bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) ||
+ ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
+
+ //m_log.Debug("[CONTROL]: " +flags);
+ // 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_UPDATE,
+ (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
+ (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
+ }
+ else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) != 0 &&
+ (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
+ {
+ ApplyFlyingRoll(
+ -FLY_ROLL_RADIANS_PER_UPDATE,
+ (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0,
+ (flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0);
+ }
+ else
+ {
+ if (m_AngularVelocity.Z != 0)
+ m_AngularVelocity.Z += CalculateFlyingRollResetToZero(FLY_ROLL_RESET_RADIANS_PER_UPDATE);
+ }
+
+ if (Flying && IsColliding && controlland)
+ {
+ // nesting this check because LengthSquared() is expensive and we don't
+ // want to do it every step when flying.
+ if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
+ StopFlying();
+ }
}
}
+// m_log.DebugFormat("[SCENE PRESENCE]: MovementFlag {0} for {1}", MovementFlag, Name);
+
// If the agent update does move the avatar, then calculate the force ready for the velocity update,
// which occurs later in the main scene loop
- if (update_movementflag || (update_rotation && DCFlagKeyPressed))
+ // We also need to update if the user rotates their avatar whilst it is slow walking/running (if they
+ // held down AGENT_CONTROL_STOP whilst normal walking/running). However, we do not want to update
+ // if the user rotated whilst holding down AGENT_CONTROL_STOP when already still (which locks the
+ // avatar location in place).
+ if (update_movementflag
+ || (update_rotation && DCFlagKeyPressed && (!AgentControlStopActive || MovementFlag != 0)))
{
-// m_log.DebugFormat(
-// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
-// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
+// if (update_movementflag || !AgentControlStopActive || MovementFlag != 0)
+// {
+// m_log.DebugFormat(
+// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, mf = {4}, ur = {5}",
+// m_scene.RegionInfo.RegionName, agent_control_v3, Name,
+// update_movementflag, MovementFlag, update_rotation);
- AddNewMovement(agent_control_v3);
+ float speedModifier;
+
+ if (AgentControlStopActive)
+ speedModifier = 0.5f;
+ else
+ speedModifier = 1;
+
+ AddNewMovement(agent_control_v3, speedModifier);
+// }
}
// else
// {
@@ -1828,7 +1873,10 @@ namespace OpenSim.Region.Framework.Scenes
// }
if (update_movementflag && ParentID == 0)
+ {
+// m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name);
Animator.UpdateMovementAnimations();
+ }
SendControlsToScripts(flagsForScripts);
}
@@ -2711,10 +2759,13 @@ namespace OpenSim.Region.Framework.Scenes
/// Rotate the avatar to the given rotation and apply a movement in the given relative vector
///
/// The vector in which to move. This is relative to the rotation argument
- public void AddNewMovement(Vector3 vec)
+ ///
+ /// Optional additional speed modifier for this particular add. Default is 1
+ public void AddNewMovement(Vector3 vec, float thisAddSpeedModifier = 1)
{
// m_log.DebugFormat(
-// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1} for {2}", vec, Rotation, Name);
+// "[SCENE PRESENCE]: Adding new movement {0} with rotation {1}, thisAddSpeedModifier {2} for {3}",
+// vec, Rotation, thisAddSpeedModifier, Name);
Vector3 direc = vec * Rotation;
direc.Normalize();
@@ -2732,7 +2783,7 @@ namespace OpenSim.Region.Framework.Scenes
if ((vec.Z == 0f) && !Flying)
direc.Z = 0f; // Prevent camera WASD up.
- direc *= 0.03f * 128f * SpeedModifier;
+ direc *= 0.03f * 128f * SpeedModifier * thisAddSpeedModifier;
// m_log.DebugFormat("[SCENE PRESENCE]: Force to apply before modification was {0} for {1}", direc, Name);