WhiteCore.Region.Animation.Animator.GetMovementAnimation C# (CSharp) Method

GetMovementAnimation() public method

This method determines the proper movement related animation
public GetMovementAnimation ( ) : string
return string
        public string GetMovementAnimation ()
        {
            const float STANDUP_TIME = 2f;
            const float BRUSH_TIME = 3.5f;
            const float FALL_AFTER_MOVE_TIME = 0.75f;
            const float SOFTLAND_FORCE = 80;

            #region Inputs

            if (m_scenePresence.SitGround) {
                return "SIT_GROUND_CONSTRAINED";
            }
            var controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            // Create forward and left vectors from the current avatar rotation
            Vector3 fwd = Vector3.UnitX * m_scenePresence.Rotation;
            Vector3 left = Vector3.UnitY * m_scenePresence.Rotation;

            // Check control flags
            bool heldForward =
                (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) ==
                  AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) ||
                 ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) ==
                  AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS));
            bool yawPos = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS;
            bool yawNeg = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG;
            bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
            bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
            bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) ==
                             AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
            bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) ==
                                AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
            bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) ==
                                 AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
            bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) ==
                          AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
            bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) ==
                            AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
            //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;

            // Direction in which the avatar is trying to move
            Vector3 move = Vector3.Zero;
            if (heldForward) {
                move.X += fwd.X;
                move.Y += fwd.Y;
            }
            if (heldBack) {
                move.X -= fwd.X;
                move.Y -= fwd.Y;
            }
            if (heldLeft) {
                move.X += left.X;
                move.Y += left.Y;
            }
            if (heldRight) {
                move.X -= left.X;
                move.Y -= left.Y;
            }
            if (heldUp) {
                move.Z += 1;
            }
            if (heldDown) {
                move.Z -= 1;
            }

            float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

            if (heldTurnLeft && yawPos && !heldForward &&
                !heldBack && actor != null && !actor.IsJumping &&
                !actor.Flying && Util.ApproxZero(move.Z) &&
                Util.ApproxZero (fallVelocity) && !heldUp &&
                !heldDown && move.CompareTo (Vector3.Zero) == 0) {
                return "TURNLEFT";
            }
            if (heldTurnRight && yawNeg && !heldForward &&
                !heldBack && actor != null && !actor.IsJumping &&
                !actor.Flying && Util.ApproxZero (move.Z) &&
                Util.ApproxZero (fallVelocity) && !heldUp &&
                !heldDown && move.CompareTo (Vector3.Zero) == 0) {
                return "TURNRIGHT";
            }

            // Is the avatar trying to move?
            //            bool moving = (move != Vector3.Zero);

            #endregion Inputs

            #region Standup

            float standupElapsed = (Util.EnvironmentTickCount () - m_animTickStandup) / 1000f;
            if (m_scenePresence.PhysicsActor != null && standupElapsed < STANDUP_TIME &&
                m_useSplatAnimation) {
                // Falling long enough to trigger the animation
                m_scenePresence.FallenStandUp = true;
                m_scenePresence.PhysicsActor.Velocity = Vector3.Zero;
                return "STANDUP";
            }

            // need the brush off?
            if (standupElapsed < BRUSH_TIME && m_useSplatAnimation) {
                m_scenePresence.FallenStandUp = true;
                return "BRUSH";
            }

            if (Util.NotZero(m_animTickStandup) || m_scenePresence.FallenStandUp) {
                m_scenePresence.FallenStandUp = false;
                m_animTickStandup = 0;
            }

            #endregion Standup

            #region Flying

            if (actor != null &&
                (m_scenePresence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) ==
                (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY || m_scenePresence.ForceFly) {
                m_animTickWalk = 0;
                m_animTickFall = 0;
                if (Util.NotZero(move.X) || Util.NotZero(move.Y)) {
                    // level?
                    if (Util.NotZero(move.Z)) {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight) {
                            return "SWIM_FORWARD";
                        }

                        // must be flying then
                        if (m_timesBeforeSlowFlyIsOff < SLOWFLY_DELAY) {
                            m_timesBeforeSlowFlyIsOff++;
                            return "FLYSLOW";
                        }

                        return "FLY";

                    }

                    // going up then...
                    if (move.Z > 0) {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                            return "SWIM_UP";

                        // easy does it
                        return "FLYSLOW";
                    }
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        return "SWIM_DOWN";

                    // in the wild blue yonder
                    return "FLY";
                }

                // moving left/right but going up as well?
                if (move.Z > 0f) {
                    //This is for the slow fly timer
                    m_timesBeforeSlowFlyIsOff = 0;
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        return "SWIM_UP";

                    // going up...
                    return "HOVER_UP";
                }

                // mabye moving down then?
                if (move.Z < 0f) {
                    wasLastFlying = true;
                    //This is for the slow fly timer
                    m_timesBeforeSlowFlyIsOff = 0;
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        return "SWIM_DOWN";
                    
                    ITerrainChannel channel = m_scenePresence.Scene.RequestModuleInterface<ITerrainChannel> ();
                    if (channel != null) {
                        float groundHeight =
                            channel.GetNormalizedGroundHeight ((int)m_scenePresence.AbsolutePosition.X,
                                                              (int)m_scenePresence.AbsolutePosition.Y);
                        if (actor != null && (m_scenePresence.AbsolutePosition.Z - groundHeight) < 2)
                            return "LAND";

                            return "HOVER_DOWN";
                        }

                    // no ground here...
                    return "HOVER_DOWN";
                }


                //This is for the slow fly timer
                m_timesBeforeSlowFlyIsOff = 0;
                if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                    actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    return "SWIM_HOVER";

                return "HOVER";
            }

            m_timesBeforeSlowFlyIsOff = 0;

            #endregion Flying

            #region Jumping

            if (actor != null && actor.IsJumping) {
                return "JUMP";
            }

            if (actor != null && actor.IsPreJumping) {
                return "PREJUMP";
            }

            #endregion

            #region Falling/Floating/Landing

            float walkElapsed = (Util.EnvironmentTickCount () - m_animTickWalk) / 1000f;
            if (actor != null && actor.IsPhysical && !actor.IsJumping && (!actor.IsColliding) && !actor.Flying && actor.TargetVelocity != Vector3.Zero/* && actor.Velocity.Z < -2*/ &&
                (walkElapsed > FALL_AFTER_MOVE_TIME || Util.ApproxZero(m_animTickWalk)))//For if they user is walking off something, or they are falling
            {
                //Always return falldown immediately as there shouldn't be a waiting period
                if (Util.ApproxZero(m_animTickFall))
                    m_animTickFall = Util.EnvironmentTickCount ();
                return "FALLDOWN";
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

            if (m_movementAnimation == "FALLDOWN") {
                float fallElapsed = (Util.EnvironmentTickCount () - m_animTickFall) / 1000f;
                // soft landing?
                if (fallElapsed < 0.75) {
                    m_animTickFall = Util.EnvironmentTickCount ();

                    return "SOFT_LAND";
                }

                // a bit harder then?
                if (actor != null &&
                    (fallElapsed < 1.1 ||
                     (Math.Abs (actor.Velocity.X) > 1 &&
                      Math.Abs (actor.Velocity.Y) > 1 &&
                      actor.Velocity.Z < 3)
                    )
                   ) {
                    m_animTickFall = Util.EnvironmentTickCount ();

                    return "LAND";
                }

                // maybe a hard one...
                if (m_useSplatAnimation) {
                    m_animTickStandup = Util.EnvironmentTickCount ();
                    return "STANDUP";
                }

                // just a simple landing
                return "LAND";
            }

            // landing then
            if (m_movementAnimation == "LAND") {
                if (actor != null && actor.Velocity.Z < 0) {
                    if (actor.Velocity.Z < SOFTLAND_FORCE)
                        return "LAND";
                    return "SOFT_LAND";
                }
                //return "LAND";
            }

            m_animTickFall = 0;

            if (move.Z <= 0f) {
                if (actor != null && 
                    (Util.NotZero(move.X) || Util.NotZero(move.Y) || 
                     (Util.NotZero(actor.Velocity.X) && Util.NotZero(actor.Velocity.Y))
                    )
                   ) {
                    wasLastFlying = false;
                    if (actor.IsColliding)
                        m_animTickWalk = Util.EnvironmentTickCount ();

                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                        return "CROUCHWALK";

                    // always run?
                    if (m_scenePresence.SetAlwaysRun)
                        return "RUN";

                    // must be walking then
                    return "WALK";
                }

                // Not walking
                if (move.Z < 0f && !wasLastFlying)
                    return "CROUCH";

                return "STAND";
            }

            #endregion Ground Movement

            // none of the above so just continue the last animation
            return m_movementAnimation;
        }