From 3052a5388954592861e0a55681844115485b6ae7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 29 Sep 2014 20:17:05 +0100 Subject: change avatar physics and motion control. Still not that good :( --- .../Scenes/Animation/ScenePresenceAnimator.cs | 147 ++++++++++++++------- 1 file changed, 99 insertions(+), 48 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes/Animation') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index db3b834..6003e92 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -56,11 +56,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// The current movement animation /// public string CurrentMovementAnimation { get; private set; } - + private int m_animTickFall; - public int m_animTickJump; // ScenePresence has to see this to control +Z force + private int m_animTickLand; + private int m_animTickJump; + public bool m_jumping = false; - public float m_jumpVelocity = 0f; + // private int m_landing = 0; /// @@ -68,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public bool Falling { get; private set; } - private float m_fallHeight; + private float m_lastFallVelocity; /// /// The scene presence that this animator applies to @@ -205,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation if (aoSitGndAnim != UUID.Zero) { - avnChangeAnim(aoSitGndAnim, false, false); + avnChangeAnim(aoSitGndAnim, false, true); aoSitGndAnim = UUID.Zero; } @@ -258,20 +260,38 @@ namespace OpenSim.Region.Framework.Scenes.Animation return ret; } + public enum motionControlStates : byte + { + sitted = 0, + flying, + falling, + jumping, + landing, + onsurface + } + + public motionControlStates currentControlState = motionControlStates.onsurface; + /// /// This method determines the proper movement related animation /// private string DetermineMovementAnimation() { - const float FALL_DELAY = 800f; - const float PREJUMP_DELAY = 200f; - const float JUMP_PERIOD = 800f; + const int FALL_DELAY = 800; + const int PREJUMP_DELAY = 200; + const int JUMP_PERIOD = 800; #region Inputs if (m_scenePresence.SitGround) + { + currentControlState = motionControlStates.sitted; return "SITGROUND"; + } if (m_scenePresence.ParentID != 0 || m_scenePresence.ParentUUID != UUID.Zero) + { + currentControlState = motionControlStates.sitted; return "SIT"; + } AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; @@ -311,17 +331,31 @@ namespace OpenSim.Region.Framework.Scenes.Animation // bool moving = (move != Vector3.Zero); #endregion Inputs + // no physics actor case + if (actor == null) + { + // well what to do? + + currentControlState = motionControlStates.onsurface; + if (move.X != 0f || move.Y != 0f) + return "WALK"; + + return "STAND"; + } + + #region Flying - if (actor != null && actor.Flying) + bool isColliding = actor.IsColliding; + + if (actor.Flying) { m_animTickFall = 0; m_animTickJump = 0; m_jumping = false; Falling = false; - m_jumpVelocity = 0f; - actor.Selected = false; - m_fallHeight = actor.Position.Z; // save latest flying height + + currentControlState = motionControlStates.flying; if (move.X != 0f || move.Y != 0f) { @@ -333,8 +367,13 @@ namespace OpenSim.Region.Framework.Scenes.Animation } else if (move.Z < 0f) { - if (actor != null && actor.IsColliding) + if (isColliding) + { + actor.Flying = false; + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; return "LAND"; + } else return "HOVER_DOWN"; } @@ -343,29 +382,41 @@ namespace OpenSim.Region.Framework.Scenes.Animation return "HOVER"; } } + else + { + if (isColliding && currentControlState == motionControlStates.flying) + { + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; + return "LAND"; + } + } #endregion Flying #region Falling/Floating/Landing - if ((actor == null || !actor.IsColliding) && !m_jumping) + if (!isColliding && currentControlState != motionControlStates.jumping) { - float fallElapsed = (float)(Environment.TickCount - m_animTickFall); - float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; + float fallVelocity = actor.Velocity.Z; - if (!m_jumping && (fallVelocity < -3.0f)) + if (fallVelocity < -2.5f) Falling = true; - if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) + if (m_animTickFall == 0 || (fallVelocity >= -0.5f)) { - // not falling yet, or going up - // reset start of fall time m_animTickFall = Environment.TickCount; } - else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.WasFlying)) + else { - // Falling long enough to trigger the animation - return "FALLDOWN"; + int fallElapsed = (Environment.TickCount - m_animTickFall); + if ((fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f)) + { + currentControlState = motionControlStates.falling; + m_lastFallVelocity = fallVelocity; + // Falling long enough to trigger the animation + return "FALLDOWN"; + } } // Check if the user has stopped walking just now @@ -375,49 +426,44 @@ namespace OpenSim.Region.Framework.Scenes.Animation return CurrentMovementAnimation; } - #endregion Falling/Floating/Landing + m_animTickFall = 0; + #endregion Falling/Floating/Landing #region Jumping // section added for jumping... - int jumptime; - jumptime = Environment.TickCount - m_animTickJump; - - if ((move.Z > 0f) && (!m_jumping)) + if (isColliding && move.Z > 0f && currentControlState != motionControlStates.jumping) { // Start jumping, prejump - m_animTickFall = 0; + currentControlState = motionControlStates.jumping; m_jumping = true; Falling = false; - actor.Selected = true; // borrowed for jumping flag m_animTickJump = Environment.TickCount; - m_jumpVelocity = 0.35f; return "PREJUMP"; } - if (m_jumping) + if (currentControlState == motionControlStates.jumping) { + int jumptime = Environment.TickCount - m_animTickJump; if ((jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) { // end jumping m_jumping = false; Falling = false; actor.Selected = false; // borrowed for jumping flag - m_jumpVelocity = 0f; - m_animTickFall = Environment.TickCount; + m_animTickLand = Environment.TickCount; + currentControlState = motionControlStates.landing; return "LAND"; } else if (jumptime > JUMP_PERIOD) { // jump down - m_jumpVelocity = 0f; return "JUMP"; } else if (jumptime > PREJUMP_DELAY) { // jump up m_jumping = true; - m_jumpVelocity = 10f; return "JUMP"; } } @@ -426,42 +472,48 @@ namespace OpenSim.Region.Framework.Scenes.Animation #region Ground Movement - if (CurrentMovementAnimation == "FALLDOWN") + if (currentControlState == motionControlStates.falling) { Falling = false; - m_animTickFall = Environment.TickCount; + currentControlState = motionControlStates.landing; + m_animTickLand = Environment.TickCount; // TODO: SOFT_LAND support - float fallHeight = m_fallHeight - actor.Position.Z; - if (fallHeight > 15.0f) + float fallVsq =m_lastFallVelocity*m_lastFallVelocity; + if (fallVsq > 300f) // aprox 20*h return "STANDUP"; - else if (fallHeight > 8.0f) + else if (fallVsq > 160f) return "SOFT_LAND"; else return "LAND"; } - else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP")) + + + if (currentControlState == motionControlStates.landing) { - int landElapsed = Environment.TickCount - m_animTickFall; + Falling = false; + int landElapsed = Environment.TickCount - m_animTickLand; int limit = 1000; if (CurrentMovementAnimation == "LAND") limit = 350; // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client - if ((m_animTickFall != 0) && (landElapsed <= limit)) + if ((m_animTickLand != 0) && (landElapsed <= limit)) { return CurrentMovementAnimation; } else { - m_fallHeight = actor.Position.Z; // save latest flying height + currentControlState = motionControlStates.onsurface; + m_animTickLand = 0; return "STAND"; } } + // next section moved outside paren. and realigned for jumping if (move.X != 0f || move.Y != 0f) { - m_fallHeight = actor.Position.Z; // save latest flying height + currentControlState = motionControlStates.onsurface; Falling = false; // Walking / crouchwalking / running if (move.Z < 0f) @@ -480,6 +532,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation } else if (!m_jumping) { + currentControlState = motionControlStates.onsurface; Falling = false; // Not walking if (move.Z < 0) @@ -493,8 +546,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation } #endregion Ground Movement - Falling = false; - return CurrentMovementAnimation; } -- cgit v1.1