/// <summary>
            /// Builds an AgentUpdate packet entirely from parameters. This
            /// will not touch the state of Self.Movement or
            /// Self.Movement.Camera in any way
            /// </summary>
            /// <param name="controlFlags"></param>
            /// <param name="position"></param>
            /// <param name="forwardAxis"></param>
            /// <param name="leftAxis"></param>
            /// <param name="upAxis"></param>
            /// <param name="bodyRotation"></param>
            /// <param name="headRotation"></param>
            /// <param name="farClip"></param>
            /// <param name="reliable"></param>
            /// <param name="flags"></param>
            /// <param name="state"></param>
            public void SendManualUpdate(AgentManager.ControlFlags controlFlags, Vector3 position, Vector3 forwardAxis,
                                         Vector3 leftAxis, Vector3 upAxis, Quaternion bodyRotation, Quaternion headRotation, float farClip,
                                         AgentFlags flags, AgentState state, bool reliable)
            {
                // Since version 1.40.4 of the Linden simulator, sending this update
                // causes corruption of the agent position in the simulator
                if (Client.Network.CurrentSim != null && (!Client.Network.CurrentSim.HandshakeComplete))
                {
                    return;
                }

                AgentUpdatePacket update = new AgentUpdatePacket();

                update.AgentData.AgentID        = Client.Self.AgentID;
                update.AgentData.SessionID      = Client.Self.SessionID;
                update.AgentData.BodyRotation   = bodyRotation;
                update.AgentData.HeadRotation   = headRotation;
                update.AgentData.CameraCenter   = position;
                update.AgentData.CameraAtAxis   = forwardAxis;
                update.AgentData.CameraLeftAxis = leftAxis;
                update.AgentData.CameraUpAxis   = upAxis;
                update.AgentData.Far            = farClip;
                update.AgentData.ControlFlags   = (uint)controlFlags;
                update.AgentData.Flags          = (byte)flags;
                update.AgentData.State          = (byte)state;

                update.Header.Reliable = reliable;

                Client.Network.SendPacket(update);
            }
 public void OnNewMovement(ref AgentManager.ControlFlags flags)
 {
     lock (scriptedcontrols)
     {
         if (scriptedcontrols.Count > 0)
         {
             SendControlToScripts((uint)flags);
             flags = RemoveIgnoredControls(flags, IgnoredControls);
         }
     }
 }
Beispiel #3
0
        void MoveCamera()
        {
            while (running)
            {
                if (client.Network.Connected)
                {
                    // TWEAK: Randomize far distance to force an interest list recomputation
                    float far = (float)(random.NextDouble() * 252d + 4d);

                    // Random small movements
                    AgentManager.ControlFlags flags = AgentManager.ControlFlags.NONE;
                    if (far < 96f)
                    {
                        flags |= AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
                    }
                    else if (far < 196f)
                    {
                        flags |= AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
                    }
                    else if (far < 212f)
                    {
                        flags |= AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
                    }
                    else
                    {
                        flags |= AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
                    }

                    // Randomly change the camera position
                    Vector3 pos = RandomPosition();

                    client.Self.Movement.SendManualUpdate(
                        flags, pos, Vector3.UnitZ, Vector3.UnitX, Vector3.UnitY, Quaternion.Identity, Quaternion.Identity, far,
                        AgentFlags.None, AgentState.None, false);
                }

                Thread.Sleep(500);
            }
        }
            /// <summary>
            /// Builds an AgentUpdate packet entirely from parameters. This
            /// will not touch the state of Self.Movement or
            /// Self.Movement.Camera in any way
            /// </summary>
            /// <param name="controlFlags"></param>
            /// <param name="position"></param>
            /// <param name="forwardAxis"></param>
            /// <param name="leftAxis"></param>
            /// <param name="upAxis"></param>
            /// <param name="bodyRotation"></param>
            /// <param name="headRotation"></param>
            /// <param name="farClip"></param>
            /// <param name="reliable"></param>
            /// <param name="flags"></param>
            /// <param name="state"></param>
            public void SendManualUpdate(AgentManager.ControlFlags controlFlags, Vector3 position, Vector3 forwardAxis,
                                         Vector3 leftAxis, Vector3 upAxis, Quaternion bodyRotation, Quaternion headRotation, float farClip,
                                         AgentFlags flags, AgentState state, bool reliable)
            {
                AgentUpdatePacket update = new AgentUpdatePacket();

                update.AgentData.AgentID        = Client.Self.AgentID;
                update.AgentData.SessionID      = Client.Self.SessionID;
                update.AgentData.BodyRotation   = bodyRotation;
                update.AgentData.HeadRotation   = headRotation;
                update.AgentData.CameraCenter   = position;
                update.AgentData.CameraAtAxis   = forwardAxis;
                update.AgentData.CameraLeftAxis = leftAxis;
                update.AgentData.CameraUpAxis   = upAxis;
                update.AgentData.Far            = farClip;
                update.AgentData.ControlFlags   = (uint)controlFlags;
                update.AgentData.Flags          = (byte)flags;
                update.AgentData.State          = (byte)state;

                update.Header.Reliable = reliable;

                Client.Network.SendPacket(update);
            }
Beispiel #5
0
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        public string GetMovementAnimation()
        {
            const float FALL_DELAY    = 0.33f;
            const float PREJUMP_DELAY = 0.25f;

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

            // Create forward and left vectors from the current avatar rotation
            Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
            Vector3 fwd       = Vector3.Transform(Vector3.UnitX, rotMatrix);
            Vector3 left      = Vector3.Transform(Vector3.UnitY, rotMatrix);

            // 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 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;
            }

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

            #endregion Inputs

            #region Flying

            if (actor != null && actor.Flying)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;

                if (move.X != 0f || move.Y != 0f)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (move.Z > 0f)
                {
                    return("HOVER_UP");
                }
                else if (move.Z < 0f)
                {
                    if (actor != null && actor.IsColliding)
                    {
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if (actor == null || !actor.IsColliding)
            {
                float fallElapsed  = (float)(Environment.TickCount - m_animTickFall) / 1000f;
                float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

                if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
                {
                    // Just started falling
                    m_animTickFall = Environment.TickCount;
                }
                else if (!jumping && fallElapsed > FALL_DELAY)
                {
                    // Falling long enough to trigger the animation
                    return("FALLDOWN");
                }
                else if (m_animTickJump == -1)
                {
                    m_animTickJump = 0;
                    return("STAND");
                }

                return(m_movementAnimation);
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

            if (m_movementAnimation == "FALLDOWN")
            {
                m_animTickFall = Environment.TickCount;

                // TODO: SOFT_LAND support
                return("LAND");
            }
            else if (m_movementAnimation == "LAND")
            {
                float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
                if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY))
                {
                    return("LAND");
                }
            }

            m_animTickFall = 0;

            if (move.Z > 0f)
            {
                // Jumping
                if (!jumping)
                {
                    // Begin prejump
                    m_animTickJump = Environment.TickCount;
                    return("PREJUMP");
                }
                else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
                {
                    // Start actual jump
                    if (m_animTickJump == -1)
                    {
                        // Already jumping! End the current jump
                        m_animTickJump = 0;
                        return("JUMP");
                    }

                    m_animTickJump = -1;
                    return("JUMP");
                }
                else
                {
                    return("JUMP");
                }
            }
            else
            {
                // Not jumping
                m_animTickJump = 0;

                if (move.X != 0f || move.Y != 0f)
                {
                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                    {
                        return("CROUCHWALK");
                    }
                    else if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
                else
                {
                    // Not walking
                    if (move.Z < 0f)
                    {
                        return("CROUCH");
                    }
                    else
                    {
                        return("STAND");
                    }
                }
            }

            #endregion Ground Movement

            //return m_movementAnimation;
        }
            protected internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
            {
                if (ignored == ScriptControlled.CONTROL_ZERO)
                {
                    return(flags);
                }

                if ((ignored & ScriptControlled.CONTROL_BACK) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
                }
                if ((ignored & ScriptControlled.CONTROL_FWD) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS);
                }
                if ((ignored & ScriptControlled.CONTROL_DOWN) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG);
                }
                if ((ignored & ScriptControlled.CONTROL_UP) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS);
                }
                if ((ignored & ScriptControlled.CONTROL_LEFT) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
                }
                if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG);
                }
                if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG);
                }
                if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS);
                }
                if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN);
                }
                if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0)
                {
                    flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN);
                }

                //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS,
                //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG,
                //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS,
                //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG,
                //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS,
                //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG,
                //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG

                return(flags);
            }
        public void CopyFrom(AgentData cAgent)
        {
            m_originRegionID = cAgent.RegionID;

            m_callbackURI = cAgent.CallbackURI;

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            m_CameraCenter = cAgent.Center;
            //m_avHeight = cAgent.Size.Z;
            m_CameraAtAxis = cAgent.AtAxis;
            m_CameraLeftAxis = cAgent.LeftAxis;
            m_CameraUpAxis = cAgent.UpAxis;

            m_DrawDistance = cAgent.Far;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            m_bodyRot = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                m_godLevel = cAgent.GodLevel;
            m_setAlwaysRun = cAgent.AlwaysRun;

            uint i = 0;
            try
            {
                if (cAgent.Wearables == null)
                   cAgent.Wearables  = new UUID[0];
                AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
                for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
                {
                    UUID itemId = cAgent.Wearables[n];
                    UUID assetId = cAgent.Wearables[n + 1];
                    wears[i++] = new AvatarWearable(itemId, assetId);
                }
                m_appearance.Wearables = wears;
                Primitive.TextureEntry te;
                if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
                    te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);
                else
                    te = AvatarAppearance.GetDefaultTexture();
                if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
                    cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams();
                m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone());
            }
            catch (Exception e)
            {
                m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
            }

            // Attachments
            try
            {
                if (cAgent.Attachments != null)
                {
                    foreach (AttachmentData att in cAgent.Attachments)
                    {
                        m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
                    }
                }
            }
            catch { } 

            // Animations
            try
            {
                Animator.ResetAnimations();
                Animator.Animations.FromArray(cAgent.Anims);
            }
            catch {  }

            //cAgent.GroupID = ??
            //Groups???
        }
        private void CopyFrom(AgentData cAgent)
        {
            m_callbackURI = cAgent.CallbackURI;
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
//                Name, m_scene.RegionInfo.RegionName, m_callbackURI);

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            CameraPosition = cAgent.Center;
            CameraAtAxis = cAgent.AtAxis;
            CameraLeftAxis = cAgent.LeftAxis;
            CameraUpAxis = cAgent.UpAxis;
            ParentUUID = cAgent.ParentPart;
            PrevSitOffset = cAgent.SitOffset;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            DrawDistance = cAgent.Far;
            // DrawDistance = Scene.DefaultDrawDistance;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            Rotation = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                GodLevel = cAgent.GodLevel;
            SetAlwaysRun = cAgent.AlwaysRun;

            Appearance = new AvatarAppearance(cAgent.Appearance);
            if (PhysicsActor != null)
            {
                bool isFlying = Flying;
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
            
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.objectID = c.ObjectID;
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }

            // FIXME: Why is this null check necessary?  Where are the cases where we get a null Anims object?
            if (cAgent.Anims != null)
                Animator.Animations.FromArray(cAgent.Anims);
            if (cAgent.DefaultAnim != null)
                Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
            if (cAgent.AnimState != null)
                Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);

            if (Scene.AttachmentsModule != null)
                Scene.AttachmentsModule.CopyAttachments(cAgent, this);

            // This must occur after attachments are copied, as it releases the CompleteMovement() calling thread
            // originating from the client completing a teleport.  Otherwise, CompleteMovement() code to restart
            // script attachments can outrace this thread.
            lock (m_originRegionIDAccessLock)
                m_originRegionID = cAgent.RegionID;
        }
Beispiel #9
0
        private void CopyFrom(AgentData cAgent)
        {
            m_callbackURI = cAgent.CallbackURI;
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
//                Name, m_scene.RegionInfo.RegionName, m_callbackURI);

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            CameraPosition = cAgent.Center;
            CameraAtAxis = cAgent.AtAxis;
            CameraLeftAxis = cAgent.LeftAxis;
            CameraUpAxis = cAgent.UpAxis;
            ParentUUID = cAgent.ParentPart;
            PrevSitOffset = cAgent.SitOffset;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            DrawDistance = cAgent.Far;
            //DrawDistance = Scene.DefaultDrawDistance;

            if (cAgent.ChildrenCapSeeds != null && cAgent.ChildrenCapSeeds.Count > 0)
            {
                if (Scene.CapsModule != null)
                {
                    Scene.CapsModule.SetChildrenSeed(UUID, cAgent.ChildrenCapSeeds);
                }
                KnownRegions = cAgent.ChildrenCapSeeds;
            }

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            Rotation = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                GodLevel = cAgent.GodLevel;
            SetAlwaysRun = cAgent.AlwaysRun;


            Appearance = new AvatarAppearance(cAgent.Appearance);
/*
            bool isFlying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 

            if (PhysicsActor != null)
            {
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
*/            
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.objectID = c.ObjectID;
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }

            Animator.ResetAnimations();

            Overrides.CopyAOPairsFrom(cAgent.MovementAnimationOverRides);

            // FIXME: Why is this null check necessary?  Where are the cases where we get a null Anims object?
            if (cAgent.DefaultAnim != null)
                Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
            if (cAgent.AnimState != null)
                Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);
            if (cAgent.Anims != null)
                Animator.Animations.FromArray(cAgent.Anims);
            if (cAgent.MotionState != 0)
                Animator.currentControlState = (ScenePresenceAnimator.motionControlStates) cAgent.MotionState;

            if (Scene.AttachmentsModule != null)
                Scene.AttachmentsModule.CopyAttachments(cAgent, this);

            lock (m_originRegionIDAccessLock)
                m_originRegionID = cAgent.RegionID;
        }
Beispiel #10
0
        private void CopyFrom(AgentData cAgent)
        {
            m_originRegionID = cAgent.RegionID;

            m_callbackURI = cAgent.CallbackURI;
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
//                Name, m_scene.RegionInfo.RegionName, m_callbackURI);

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            CameraPosition = cAgent.Center;
            CameraAtAxis = cAgent.AtAxis;
            CameraLeftAxis = cAgent.LeftAxis;
            CameraUpAxis = cAgent.UpAxis;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // DrawDistance = cAgent.Far;
            DrawDistance = Scene.DefaultDrawDistance;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            Rotation = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                GodLevel = cAgent.GodLevel;
            SetAlwaysRun = cAgent.AlwaysRun;

            Appearance = new AvatarAppearance(cAgent.Appearance);
            if (PhysicsActor != null)
            {
                bool isFlying = Flying;
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
            
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }

            // FIXME: Why is this null check necessary?  Where are the cases where we get a null Anims object?
            if (cAgent.Anims != null)
                Animator.Animations.FromArray(cAgent.Anims);

            if (Scene.AttachmentsModule != null)
                Scene.AttachmentsModule.CopyAttachments(cAgent, this);
        }
        public virtual void CopyFrom(AgentData cAgent)
        {
            try
            {
                m_pos = cAgent.Position;
                if (PhysicsActor != null)
                {
                    AbsolutePosition = cAgent.Position;
                    PhysicsActor.ForceSetPosition(cAgent.Position);
                }
                Velocity = cAgent.Velocity;
                m_CameraCenter = cAgent.Center;
                SetHeight(cAgent.Size.Z);
                m_CameraAtAxis = cAgent.AtAxis;
                m_CameraLeftAxis = cAgent.LeftAxis;
                m_CameraUpAxis = cAgent.UpAxis;

                DrawDistance = cAgent.Far;

                if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                    ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

                m_headrotation = cAgent.HeadRotation;
                m_bodyRot = cAgent.BodyRotation;
                m_AgentControlFlags = (AgentManager.ControlFlags) cAgent.ControlFlags;
                m_savedVelocity = cAgent.Velocity;

                SpeedModifier = cAgent.Speed;
                DrawDistance = cAgent.DrawDistance;
                m_setAlwaysRun = cAgent.AlwaysRun;
                if (cAgent.IsCrossing)
                {
                    m_scene.AuthenticateHandler.GetAgentCircuitData(UUID).TeleportFlags |=
                        (uint) TeleportFlags.ViaRegionID;
                    m_scene.AuthenticateHandler.GetAgentCircuitData(UUID).IsChildAgent = false;
                        //We're going to be a root
                }
                IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule>();
                if (appearance != null)
                {
                    appearance.InitialHasWearablesBeenSent = cAgent.SentInitialWearables;
                    appearance.Appearance = new AvatarAppearance(cAgent.Appearance);
                }

                // Animations
                try
                {
                    Animator.ResetAnimations();
                    Animator.Animations.FromArray(cAgent.Anims);
                }
                catch
                {
                }
                try
                {
                    if (cAgent.SittingObjects != null && cAgent.SittingObjects.m_sittingObjectXML != "")
                    {
                        ISceneEntity sceneObject = null;
                        IRegionSerialiserModule mod = Scene.RequestModuleInterface<IRegionSerialiserModule>();
                        if (mod != null)
                            sceneObject = mod.DeserializeGroupFromXml2(cAgent.SittingObjects.m_sittingObjectXML, Scene);

                        if (sceneObject != null)
                        {
                            //We were sitting on something when we crossed
                            if (Scene.SceneGraph.RestorePrimToScene(sceneObject, false))
                            {
                                if (sceneObject.IsSelected)
                                    sceneObject.RootChild.CreateSelected = true;
                                sceneObject.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate);
                                sceneObject.CreateScriptInstances(0, false, StateSource.PrimCrossing, UUID.Zero, false);

                                sceneObject.RootChild.PhysActor.ForceSetVelocity(cAgent.Velocity);
                                sceneObject.RootChild.PhysActor.Velocity = (cAgent.Velocity);
                                sceneObject.AbsolutePosition = cAgent.Position;
                                Animator.TrySetMovementAnimation(cAgent.SittingObjects.m_animation);
                                m_nextSitAnimation = cAgent.SittingObjects.m_animation;
                                cAgent.SittingObjects.m_objectID = sceneObject.UUID;
                                m_objectToSitOn = cAgent.SittingObjects;

                                foreach (ISceneChildEntity child in sceneObject.ChildrenEntities())
                                {
                                    foreach (TaskInventoryItem taskInv in child.Inventory.GetInventoryItems())
                                    {
                                        foreach (ControllerData cd in cAgent.Controllers)
                                        {
                                            if (cd.ItemID == taskInv.ItemID || cd.ItemID == taskInv.OldItemID)
                                            {
                                                cd.ItemID = taskInv.ItemID;
                                            }
                                        }
                                    }
                                }

                                try
                                {
                                    IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule>();
                                    if (m != null)
                                        if (cAgent.Controllers != null)
                                            m.Deserialize(cAgent.Controllers);
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }
                catch
                {
                }
            }
            catch (Exception ex)
            {
                MainConsole.Instance.Warn("[ScenePresence]: Error in CopyFrom: " + ex);
            }
        }
        /// <summary>
        ///     This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public virtual void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
            m_perfMonMS = Util.EnvironmentTickCount();

            ++m_movementUpdateCount;
            if (m_movementUpdateCount < 1)
                m_movementUpdateCount = 1;

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                OutOfBoundsCall(Vector3.Zero);
                return;
            }

            #endregion Sanity Checking

            #region Inputs

            if (Frozen)
                return; //Do nothing, just end

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags) agentData.ControlFlags;
            Quaternion bodyRotation = agentData.BodyRotation;

            //Check to see whether ray casting needs done
            // We multiply by 10 so that we don't trigger it when the camera moves slightly (as its 2 meter change)
            if (Util.GetFlatDistanceTo(agentData.CameraCenter, m_lastCameraCenter) > SIGNIFICANT_MOVEMENT*10)
            {
                m_lastCameraCenter = agentData.CameraCenter;
                Scene.AuroraEventManager.FireGenericEventHandler("SignficantCameraMovement", this);
            }

            // Camera location in world.  We'll need to raytrace
            // from this location from time to time.
            m_CameraCenter = agentData.CameraCenter;

            // Use these three vectors to figure out what the agent is looking at
            // Convert it to a Matrix and/or Quaternion
            m_CameraAtAxis = agentData.CameraAtAxis;
            m_CameraLeftAxis = agentData.CameraLeftAxis;
            m_CameraUpAxis = agentData.CameraUpAxis;
            // The Agent's Draw distance setting
            DrawDistance = agentData.Far;

            // Check if Client has camera in 'follow cam' or 'build' mode.
            Vector3 camdif = (Vector3.One*m_bodyRot - Vector3.One*CameraRotation);

            m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
                               && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f));

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
            m_isAway = (flags & AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0;

            #endregion Inputs

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            //MainConsole.Instance.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
            // Raycast from the avatar's head to the camera to see if there's anything blocking the view
            if ((m_movementUpdateCount%NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
            {
                if (m_followCamAuto)
                {
                    Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
                    m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted),
                                                      Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f,
                                                      RayCastCameraCallback);
                }
            }
            if (!m_CameraCenter.IsFinite())
            {
                m_CameraCenter = new Vector3(128, 128, 128);
            }

            IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule>();
            if (m != null) //Tell any scripts about it
                m.OnNewMovement(ref flags);

            if (m_autopilotMoving)
                CheckAtSitTarget();

            // In the future, these values might need to go global.
            // Here's where you get them.
            if (!SitGround)
                SitGround = (flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0;
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            m_state = agentData.State;

            PhysicsActor actor = PhysicsActor;
            if (actor == null)
            {
                //This happens while sitting, don't spam it
                //MainConsole.Instance.Debug("Null physical actor in AgentUpdate in " + m_scene.RegionInfo.RegionName);
                return;
            }

            bool update_movementflag = false;
            bool update_rotation = false;

            if (AllowMovement && !SitGround && !Frozen)
            {
                if (FallenStandUp)
                {
                    //Poke the animator a bit
                    Animator.UpdateMovementAnimations(false);
                    m_bodyRot = bodyRotation;
                    AddNewMovement(Vector3.Zero, bodyRotation);
                    return;
                }
                if (agentData.UseClientAgentPosition)
                {
                    m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    m_moveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;

                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;
                Quaternion q = bodyRotation;

                bool oldflying = PhysicsActor.Flying;

                if (m_forceFly)
                    actor.Flying = true;
                else if (m_flyDisabled)
                    actor.Flying = false;
                else if (actor.Flying != ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0))
                    actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != oldflying)
                    update_movementflag = true;

                if (q != m_bodyRot)
                {
                    Quaternion delta = Quaternion.Inverse(m_bodyRot)*q;
                    m_bodyRot = q;
                    if (!(Math.Abs(delta.X) < 1e-5f && Math.Abs(delta.Y) < 1e-5f && Math.Abs(delta.Z) < 1e-5f))
                        update_rotation = true;
                }

                if (m_parentID == UUID.Zero)
                {
                    bool bAllowUpdateMoveToPosition = false;
                    bool bResetMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
                    if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying))
                        dirVectors = GetWalkDirectionVectors();
                    else
                        dirVectors = Dir_Vectors;

                    // The fact that m_movementflag is a byte needs to be fixed
                    // it really should be a uint
                    const uint nudgehack = 250;
                    //Do these two like this to block out all others because it will slow it down
                    if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) ==
                        AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)
                    {
                        bResetMoveToPosition = true;
                        DCFlagKeyPressed = true;
                        agent_control_v3 += dirVectors[8];
                    }
                    else if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) ==
                             AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)
                    {
                        bResetMoveToPosition = true;
                        DCFlagKeyPressed = true;
                        agent_control_v3 += dirVectors[9];
                    }
                    else
                    {
                        foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                        {
                            if (((uint) flags & (uint) DCF) != 0)
                            {
                                bResetMoveToPosition = true;
                                DCFlagKeyPressed = true;
                                agent_control_v3 += dirVectors[i];
                                //MainConsole.Instance.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);

                                if ((m_movementflag & (uint) DCF) == 0)
                                {
                                    if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE ||
                                        DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    {
                                        //                                        m_movementflag |= (byte)nudgehack;
                                        m_movementflag |= nudgehack;
                                    }
                                    m_movementflag += (uint) DCF;
                                    update_movementflag = true;
                                }
                            }
                            else
                            {
                                if ((m_movementflag & (uint) DCF) != 0 ||
                                    ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE ||
                                      DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                     && ((m_movementflag & nudgehack) == nudgehack))
                                    ) // This or is for Nudge forward
                                {
                                    m_movementflag -= ((uint) DCF);

                                    update_movementflag = true;
                                    /*
                                        if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                        && ((m_movementflag & (byte)nudgehack) == nudgehack))
                                        {
                                            MainConsole.Instance.Debug("Removed Hack flag");
                                        }
                                    */
                                }
                                else
                                {
                                    bAllowUpdateMoveToPosition = true;
                                }
                            }
                            i++;
                        }
                    }

                    //Paupaw:Do Proper PID for Autopilot here
                    if (bResetMoveToPosition)
                    {
                        m_moveToPositionTarget = Vector3.Zero;
                        m_moveToPositionInProgress = false;
                        update_movementflag = true;
                        bAllowUpdateMoveToPosition = false;
                    }

                    if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
                    {
                        //Check the error term of the current position in relation to the target position
                        if (Util.GetFlatDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
                        {
                            // we are close enough to the target
                            m_moveToPositionTarget = Vector3.Zero;
                            m_moveToPositionInProgress = false;
                            update_movementflag = true;
                        }
                        else
                        {
                            try
                            {
                                // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
                                // This movement vector gets added to the velocity through AddNewMovement().
                                // Theoretically we might need a more complex PID approach here if other
                                // unknown forces are acting on the avatar and we need to adaptively respond
                                // to such forces, but the following simple approach seems to works fine.
                                Vector3 LocalVectorToTarget3D =
                                    (m_moveToPositionTarget - AbsolutePosition)
                                    // vector from cur. pos to target in global coords
                                    //                                    * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
                                    *Quaternion.Inverse(bodyRotation);
                                    // mult by matix is faster but with creation, use *quarternion
                                // Ignore z component of vector
                                Vector3 LocalVectorToTarget2D;
                                LocalVectorToTarget2D.X = LocalVectorToTarget3D.X;
                                LocalVectorToTarget2D.Y = LocalVectorToTarget3D.Y;
                                LocalVectorToTarget2D.Z = 0f;

                                agent_control_v3 += LocalVectorToTarget2D;

                                // update avatar movement flags. the avatar coordinate system is as follows:
                                //
                                //                        +X (forward)
                                //
                                //                        ^
                                //                        |
                                //                        |
                                //                        |
                                //                        |
                                //     (left) +Y <--------o--------> -Y
                                //                       avatar
                                //                        |
                                //                        |
                                //                        |
                                //                        |
                                //                        v
                                //                        -X
                                //

                                // based on the above avatar coordinate system, classify the movement into
                                // one of left/right/back/forward.
                                if (LocalVectorToTarget2D.Y > 0) //MoveLeft
                                {
                                    m_movementflag += (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
                                    //AgentControlFlags
                                    AgentControlFlags |= (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
                                    update_movementflag = true;
                                }
                                else if (LocalVectorToTarget2D.Y < 0) //MoveRight
                                {
                                    m_movementflag += (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
                                    AgentControlFlags |= (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
                                    update_movementflag = true;
                                }
                                if (LocalVectorToTarget2D.X < 0) //MoveBack
                                {
                                    m_movementflag += (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
                                    AgentControlFlags |= (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
                                    update_movementflag = true;
                                }
                                else if (LocalVectorToTarget2D.X > 0) //Move Forward
                                {
                                    m_movementflag += (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
                                    AgentControlFlags |= (uint) Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
                                    update_movementflag = true;
                                }
                            }
                            catch (Exception e)
                            {
                                //Avoid system crash, can be slower but...
                                MainConsole.Instance.DebugFormat("Crash! {0}", e);
                            }
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // Only do this if we're flying
                if (m_physicsActor != null && m_physicsActor.Flying && !m_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));

                    // 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);
                    }

                    // Are the collision requirements fulfilled?
                    bool colliding = (m_physicsActor.IsColliding == true);

                    if (m_physicsActor.Flying && colliding && controlland)
                    {
                        // nesting this check because LengthSquared() is expensive and we don't
                        // want to do it every step when flying.
                        // then call it in the if...
                        //The == Zero and Z > 0.1 are to stop people from flying and then falling down because the physics engine hasn't calculted the push yet
                        if (Velocity != Vector3.Zero && Math.Abs(Velocity.Z) > 0.05 &&
                            (Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX))
                        {
                            StopFlying();
                            SendTerseUpdateToAllClients();
                        }
                    }
                }

                // 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))
                {
                    //                    MainConsole.Instance.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed));
                    //                    MainConsole.Instance.DebugFormat(
                    //                        "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);

                    AddNewMovement(agent_control_v3, q);
                }
            }

            if ((update_movementflag || update_rotation) && (m_parentID == UUID.Zero))
                Animator.UpdateMovementAnimations(false);

            IAgentUpdateMonitor reporter =
                m_scene.RequestModuleInterface<IMonitorModule>().GetMonitor<IAgentUpdateMonitor>(Scene);
            if (reporter != null)
                reporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
        }
Beispiel #13
0
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        private string DetermineMovementAnimation()
        {
            const float FALL_DELAY    = 800f;
            const float PREJUMP_DELAY = 200f;
            const float JUMP_PERIOD   = 800f;

            #region Inputs

            AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
            PhysicsActor actor = m_scenePresence.PhysicsActor;

            // Create forward and left vectors from the current avatar rotation
            Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
            Vector3 fwd       = Vector3.Transform(Vector3.UnitX, rotMatrix);
            Vector3 left      = Vector3.Transform(Vector3.UnitY, rotMatrix);

            // 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 heldBack      = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG);
            bool heldLeft      = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS);
            bool heldRight     = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_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;
            if (heldForward || heldBack || heldLeft || heldRight || heldUp || heldDown)
            {
                heldTurnLeft  = false;
                heldTurnRight = false;
            }

            // 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;
            }

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

            #region Flying

            if (actor != null && 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

                if (move.X != 0f || move.Y != 0f)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (move.Z > 0f)
                {
                    return("HOVER_UP");
                }
                else if (move.Z < 0f)
                {
                    if (actor != null && actor.IsColliding)
                    {
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if ((actor == null || !actor.IsColliding) && !m_jumping)
            {
                float fallElapsed  = (float)(Environment.TickCount - m_animTickFall);
                float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

                if (!m_jumping && (fallVelocity < -3.0f))
                {
                    Falling = true;
                }

                if (m_animTickFall == 0 || (fallVelocity >= 0.0f))
                {
                    // 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))
                {
                    // Falling long enough to trigger the animation
                    return("FALLDOWN");
                }

                // Check if the user has stopped walking just now
                if (CurrentMovementAnimation == "WALK" && (move == Vector3.Zero))
                {
                    return("STAND");
                }

                return(CurrentMovementAnimation);
            }

            #endregion Falling/Floating/Landing


            #region Jumping     // section added for jumping...

            int jumptime;
            jumptime = Environment.TickCount - m_animTickJump;

            if ((move.Z > 0f) && (!m_jumping))
            {
                // Start jumping, prejump
                m_animTickFall = 0;
                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 ((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;
                    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");
                }
            }

            #endregion Jumping

            #region Ground Movement

            if (CurrentMovementAnimation == "FALLDOWN")
            {
                Falling        = false;
                m_animTickFall = Environment.TickCount;
                // TODO: SOFT_LAND support
                float fallHeight = m_fallHeight - actor.Position.Z;
                if (fallHeight > 15.0f)
                {
                    return("STANDUP");
                }
                else if (fallHeight > 8.0f)
                {
                    return("SOFT_LAND");
                }
                else
                {
                    return("LAND");
                }
            }
            else if ((CurrentMovementAnimation == "LAND") || (CurrentMovementAnimation == "SOFT_LAND") || (CurrentMovementAnimation == "STANDUP"))
            {
                int landElapsed = Environment.TickCount - m_animTickFall;
                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))
                {
                    return(CurrentMovementAnimation);
                }
                else
                {
                    m_fallHeight = actor.Position.Z;    // save latest flying height
                    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
                Falling      = false;
                // Walking / crouchwalking / running
                if (move.Z < 0f)
                {
                    return("CROUCHWALK");
                }
                else if (m_scenePresence.SetAlwaysRun)
                {
                    return("RUN");
                }
                else
                {
                    return("WALK");
                }
            }
            else if (!m_jumping)
            {
                Falling = false;
                // Not walking
                if (move.Z < 0)
                {
                    return("CROUCH");
                }
                else if (heldTurnLeft)
                {
                    return("TURNLEFT");
                }
                else if (heldTurnRight)
                {
                    return("TURNRIGHT");
                }
                else
                {
                    return("STAND");
                }
            }
            #endregion Ground Movement

            Falling = false;

            return(CurrentMovementAnimation);
        }
        public void CopyFrom(AgentData cAgent)
        {
            m_originRegionID = cAgent.RegionID;

            m_callbackURI = cAgent.CallbackURI;

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            m_CameraCenter = cAgent.Center;
            m_CameraAtAxis = cAgent.AtAxis;
            m_CameraLeftAxis = cAgent.LeftAxis;
            m_CameraUpAxis = cAgent.UpAxis;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // m_DrawDistance = cAgent.Far;
            m_DrawDistance = Scene.DefaultDrawDistance;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            m_bodyRot = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                m_godLevel = cAgent.GodLevel;
            m_setAlwaysRun = cAgent.AlwaysRun;

            m_appearance = new AvatarAppearance(cAgent.Appearance);
            if (m_physicsActor != null)
            {
                bool isFlying = m_physicsActor.Flying;
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
            
/*
            uint i = 0;
            try
            {
                if (cAgent.Wearables == null)
                   cAgent.Wearables  = new UUID[0];
                AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
                for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
                {
                    UUID itemId = cAgent.Wearables[n];
                    UUID assetId = cAgent.Wearables[n + 1];
                    wears[i++] = new AvatarWearable(itemId, assetId);
                }
                // m_appearance.Wearables = wears;
                Primitive.TextureEntry textures = null;
                if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
                    textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);

                byte[] visuals = null;

                if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
                    visuals = (byte[])cAgent.VisualParams.Clone();

                m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
            }
            catch (Exception e)
            {
                m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
            }

            // Attachments
            try
            {
                if (cAgent.Attachments != null)
                {
                    m_appearance.ClearAttachments();
                    foreach (AvatarAttachment att in cAgent.Attachments)
                    {
                        m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
                    }
                }
            }
            catch { } 
*/
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }
            // Animations
            try
            {
                Animator.ResetAnimations();
                Animator.Animations.FromArray(cAgent.Anims);
            }
            catch {  }

            //cAgent.GroupID = ??
            //Groups???
        }
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        private string DetermineMovementAnimation()
        {
            const int FALL_DELAY    = 800;
            const int PREJUMP_DELAY = 200;
            const int JUMP_PERIOD   = 800;

            #region Inputs

            if (m_scenePresence.IsInTransit)
            {
                return(CurrentMovementAnimation);
            }

            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;

            const AgentManager.ControlFlags ANYXYMASK = (
                AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS |
                AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG |
                AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS |
                AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG
                );

            // Check control flags

            /* not in use
             *          bool heldForward = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)) != 0);
             *          bool heldBack = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG)) != 0);
             *          bool heldLeft = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS)) != 0);
             *          bool heldRight = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG)) != 0);
             */
            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_NUDGE_UP_POS)) != 0);
            // excluded nudge up so it doesn't trigger jump state
            bool heldUp   = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_POS)) != 0);
            bool heldDown = ((controlFlags & (AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG)) != 0);
            //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;

            bool heldOnXY = ((controlFlags & ANYXYMASK) != 0);
            if (heldOnXY || heldUp || heldDown)
            {
                heldTurnLeft  = false;
                heldTurnRight = false;
            }

            #endregion Inputs

            // no physics actor case
            if (actor == null)
            {
                // well what to do?

                currentControlState = motionControlStates.onsurface;
                if (heldOnXY)
                {
                    return("WALK");
                }

                return("STAND");
            }

            #region Flying

            bool isColliding = actor.IsColliding;

            if (actor.Flying)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;
                m_jumping      = false;
                Falling        = false;

                currentControlState = motionControlStates.flying;

                if (heldOnXY)
                {
                    return(m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
                }
                else if (heldUp)
                {
                    return("HOVER_UP");
                }
                else if (heldDown)
                {
                    if (isColliding)
                    {
                        actor.Flying        = false;
                        currentControlState = motionControlStates.landing;
                        m_animTickLand      = Environment.TickCount;
                        return("LAND");
                    }
                    else
                    {
                        return("HOVER_DOWN");
                    }
                }
                else
                {
                    return("HOVER");
                }
            }
            else
            {
                if (isColliding && currentControlState == motionControlStates.flying)
                {
                    currentControlState = motionControlStates.landing;
                    m_animTickLand      = Environment.TickCount;
                    return("LAND");
                }
            }

            #endregion Flying

            #region Falling/Floating/Landing

            if (!isColliding && currentControlState != motionControlStates.jumping)
            {
                float fallVelocity = actor.Velocity.Z;

                // if stable on Hover assume falling
                if (actor.PIDHoverActive && fallVelocity < 0.05f)
                {
                    Falling             = true;
                    currentControlState = motionControlStates.falling;
                    m_lastFallVelocity  = fallVelocity;
                    return("FALLDOWN");
                }

                if (fallVelocity < -2.5f)
                {
                    Falling = true;
                }

                if (m_animTickFall == 0 || (fallVelocity >= -0.5f))
                {
                    m_animTickFall = Environment.TickCount;
                }
                else
                {
                    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
                if (CurrentMovementAnimation == "WALK" && !heldOnXY && !heldDown && !heldUp)
                {
                    return("STAND");
                }

                return(CurrentMovementAnimation);
            }

            m_animTickFall = 0;

            #endregion Falling/Floating/Landing

            #region Jumping     // section added for jumping...

            if (isColliding && heldUp && currentControlState != motionControlStates.jumping && !actor.PIDHoverActive)
            {
                // Start jumping, prejump
                currentControlState = motionControlStates.jumping;
                m_jumping           = true;
                Falling             = false;
                m_animTickJump      = Environment.TickCount;
                return("PREJUMP");
            }

            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_animTickLand      = Environment.TickCount;
                    currentControlState = motionControlStates.landing;
                    return("LAND");
                }
                else if (jumptime > JUMP_PERIOD)
                {
                    // jump down
                    return("JUMP");
                }
                else if (jumptime > PREJUMP_DELAY)
                {
                    // jump up
                    m_jumping = true;
                    return("JUMP");
                }
                return(CurrentMovementAnimation);
            }

            #endregion Jumping

            #region Ground Movement

            if (currentControlState == motionControlStates.falling)
            {
                Falling             = false;
                currentControlState = motionControlStates.landing;
                m_animTickLand      = Environment.TickCount;
                // TODO: SOFT_LAND support
                float fallVsq = m_lastFallVelocity * m_lastFallVelocity;
                if (fallVsq > 300f) // aprox 20*h
                {
                    return("STANDUP");
                }
                else if (fallVsq > 160f)
                {
                    return("SOFT_LAND");
                }
                else
                {
                    return("LAND");
                }
            }


            if (currentControlState == motionControlStates.landing)
            {
                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_animTickLand != 0) && (landElapsed <= limit))
                {
                    return(CurrentMovementAnimation);
                }
                else
                {
                    currentControlState = motionControlStates.onsurface;
                    m_animTickLand      = 0;
                    return("STAND");
                }
            }

            // next section moved outside paren. and realigned for jumping

            if (heldOnXY)
            {
                currentControlState = motionControlStates.onsurface;
                Falling             = false;
                // Walking / crouchwalking / running
                if (heldDown)
                {
                    return("CROUCHWALK");
                }
                // 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
            {
                currentControlState = motionControlStates.onsurface;
                Falling             = false;
                // Not walking
                if (heldDown)
                {
                    return("CROUCH");
                }
                else if (heldTurnLeft)
                {
                    return("TURNLEFT");
                }
                else if (heldTurnRight)
                {
                    return("TURNRIGHT");
                }
                else
                {
                    return("STAND");
                }
            }
            #endregion Ground Movement

            return(CurrentMovementAnimation);
        }
Beispiel #16
0
        public void CopyFrom(AgentData cAgent)
        {
            try
            {
                m_callbackURI = cAgent.CallbackURI;
                m_pos = cAgent.Position;
                Velocity = cAgent.Velocity;
                m_CameraCenter = cAgent.Center;
                //m_avHeight = cAgent.Size.Z;
                m_CameraAtAxis = cAgent.AtAxis;
                m_CameraLeftAxis = cAgent.LeftAxis;
                m_CameraUpAxis = cAgent.UpAxis;

                DrawDistance = cAgent.Far;

                if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                    ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

                m_headrotation = cAgent.HeadRotation;
                m_bodyRot = cAgent.BodyRotation;
                m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;

                //if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                //    m_godLevel = cAgent.GodLevel;
                m_speedModifier = cAgent.Speed;
                DrawDistance = cAgent.DrawDistance;
                m_setAlwaysRun = cAgent.AlwaysRun;
                IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule> ();
                if (appearance != null)
                {
                    appearance.InitialHasWearablesBeenSent = cAgent.SentInitialWearables;
                    appearance.Appearance = new AvatarAppearance (cAgent.Appearance);
                }

                try
                {
                    IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule> ();
                    if (m != null)
                        if (cAgent.Controllers != null)
                            m.Deserialize(cAgent.Controllers);
                }
                catch { }
                // Animations
                try
                {
                    Animator.ResetAnimations();
                    Animator.Animations.FromArray(cAgent.Anims);
                }
                catch { }
            }
            catch(Exception ex)
            {
                m_log.Warn("[ScenePresence]: Error in CopyFrom: " + ex.ToString());
            }
        }
        public void CopyFrom(AgentData cAgent)
        {
            try
            {
                m_callbackURI = cAgent.CallbackURI;
                m_pos = cAgent.Position;
                Velocity = cAgent.Velocity;
                m_CameraCenter = cAgent.Center;
                SetHeight (cAgent.Size.Z);
                m_CameraAtAxis = cAgent.AtAxis;
                m_CameraLeftAxis = cAgent.LeftAxis;
                m_CameraUpAxis = cAgent.UpAxis;

                DrawDistance = cAgent.Far;

                if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                    ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

                m_headrotation = cAgent.HeadRotation;
                m_bodyRot = cAgent.BodyRotation;
                m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags;
                m_savedVelocity = cAgent.Velocity;
                 
                SpeedModifier = cAgent.Speed;
                DrawDistance = cAgent.DrawDistance;
                m_setAlwaysRun = cAgent.AlwaysRun;
                if(cAgent.IsCrossing)
                    ((Scene)m_scene).AuthenticateHandler.GetAgentCircuitData (UUID).teleportFlags |= (uint)OpenMetaverse.TeleportFlags.ViaRegionID;
                IAvatarAppearanceModule appearance = RequestModuleInterface<IAvatarAppearanceModule> ();
                if (appearance != null)
                {
                    appearance.InitialHasWearablesBeenSent = cAgent.SentInitialWearables;
                    appearance.Appearance = new AvatarAppearance (cAgent.Appearance);
                }

                try
                {
                    IScriptControllerModule m = RequestModuleInterface<IScriptControllerModule> ();
                    if (m != null)
                        if (cAgent.Controllers != null)
                            m.Deserialize(cAgent.Controllers);
                }
                catch { }
                // Animations
                try
                {
                    Animator.ResetAnimations();
                    Animator.Animations.FromArray(cAgent.Anims);
                }
                catch { }
            }
            catch(Exception ex)
            {
                m_log.Warn("[ScenePresence]: Error in CopyFrom: " + ex.ToString());
            }
        }
Beispiel #18
0
        /// <summary>
        /// This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
            //if (m_isChildAgent)
            //{
            //    // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
            //    return;
            //}

            m_perfMonMS = Util.EnvironmentTickCount();

            ++m_movementUpdateCount;
            if (m_movementUpdateCount < 1)
                m_movementUpdateCount = 1;

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                RemoveFromPhysicalScene();
                m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");

                m_pos = m_LastFinitePos;
                if (!m_pos.IsFinite())
                {
                    m_pos.X = 127f;
                    m_pos.Y = 127f;
                    m_pos.Z = 127f;
                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
                }

                AddToPhysicalScene(false);
            }
            else
            {
                m_LastFinitePos = m_pos;
            }

            #endregion Sanity Checking

            #region Inputs

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
            Quaternion bodyRotation = agentData.BodyRotation;

            // Camera location in world.  We'll need to raytrace
            // from this location from time to time.
            m_CameraCenter = agentData.CameraCenter;
            if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
            {
                ReprioritizeUpdates();
                m_lastCameraCenter = m_CameraCenter;
            }

            // Use these three vectors to figure out what the agent is looking at
            // Convert it to a Matrix and/or Quaternion
            m_CameraAtAxis = agentData.CameraAtAxis;
            m_CameraLeftAxis = agentData.CameraLeftAxis;
            m_CameraUpAxis = agentData.CameraUpAxis;

            // The Agent's Draw distance setting
            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // m_DrawDistance = agentData.Far;
            m_DrawDistance = Scene.DefaultDrawDistance;

            // Check if Client has camera in 'follow cam' or 'build' mode.
            Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);

            m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
               && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;

            #endregion Inputs

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
            // Raycast from the avatar's head to the camera to see if there's anything blocking the view
            if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
            {
                if (m_followCamAuto)
                {
                    Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
                    m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
                }
            }

            lock (scriptedcontrols)
            {
                if (scriptedcontrols.Count > 0)
                {
                    SendControlToScripts((uint)flags);
                    flags = RemoveIgnoredControls(flags, IgnoredControls);
                }
            }

            if (m_autopilotMoving)
                CheckAtSitTarget();

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
            {
                // TODO: This doesn't prevent the user from walking yet.
                // Setting parent ID would fix this, if we knew what value
                // to use.  Or we could add a m_isSitting variable.
                //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
                SitGround = true;
            }

            // In the future, these values might need to go global.
            // Here's where you get them.
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            m_state = agentData.State;

            PhysicsActor actor = PhysicsActor;
            if (actor == null)
            {
                return;
            }

            if (m_allowMovement && !SitGround)
            {
                bool update_movementflag = false;

                if (agentData.UseClientAgentPosition)
                {
                    MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    MoveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;
                
                bool update_rotation = false;
                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;
                Quaternion q = bodyRotation;

                bool oldflying = PhysicsActor.Flying;

                if (m_forceFly)
                    actor.Flying = true;
                else if (m_flyDisabled)
                    actor.Flying = false;
                else
                    actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != oldflying)
                    update_movementflag = true;

                if (q != m_bodyRot)
                {
                    m_bodyRot = q;
                    update_rotation = true;
                }

                if (m_parentID == 0)
                {
                    bool bAllowUpdateMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
                    if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying))
                        dirVectors = GetWalkDirectionVectors();
                    else
                        dirVectors = Dir_Vectors;

                    // The fact that m_movementflag is a byte needs to be fixed
                    // it really should be a uint
                    // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
                    uint nudgehack = 250;
                    foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                    {
                        if (((uint)flags & (uint)DCF) != 0)
                        {
                            DCFlagKeyPressed = true;

                            try
                            {
                                agent_control_v3 += dirVectors[i];
                                //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // Why did I get this?
                            }

                            if ((m_movementflag & (byte)(uint)DCF) == 0)
                            {
                                if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                {
                                    m_movementflag |= (byte)nudgehack;
                                }
                                m_movementflag += (byte)(uint)DCF;
                                update_movementflag = true;
                            }
                        }
                        else
                        {
                            if ((m_movementflag & (byte)(uint)DCF) != 0 ||
                                ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                && ((m_movementflag & (byte)nudgehack) == nudgehack))
                                ) // This or is for Nudge forward
                            {
                                m_movementflag -= ((byte)(uint)DCF);

                                update_movementflag = true;
                                /*
                                    if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    && ((m_movementflag & (byte)nudgehack) == nudgehack))
                                    {
                                        m_log.Debug("Removed Hack flag");
                                    }
                                */
                            }
                            else
                            {
                                bAllowUpdateMoveToPosition = true;
                            }
                        }

                        i++;
                    }

                    if (MovingToTarget)
                    {
                        // If the user has pressed a key then we want to cancel any move to target.
                        if (DCFlagKeyPressed)
                        {
                            ResetMoveToTarget();
                            update_movementflag = true;
                        }
                        else if (bAllowUpdateMoveToPosition)
                        {
                            if (HandleMoveToTargetUpdate(ref agent_control_v3, bodyRotation))
                                update_movementflag = true;
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // Only do this if we're flying
                if (m_physicsActor != null && m_physicsActor.Flying && !m_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));

                    // Are the collision requirements fulfilled?
                    bool colliding = (m_physicsActor.IsColliding == true);

                    if (m_physicsActor.Flying && colliding && 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();
                    }
                }

                // 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))
                {
                    //                    m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed));
                    //                    m_log.DebugFormat(
                    //                        "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);

                    AddNewMovement(agent_control_v3, q);
                }

                if (update_movementflag
                    && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0)
                    && (m_parentID == 0)
                    && !SitGround)
                    Animator.UpdateMovementAnimations();
            }

            m_scene.EventManager.TriggerOnClientMovement(this);

            m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
        }
        /// <summary>
        ///     This method determines the proper movement related animation
        /// </summary>
        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");
            }
            AgentManager.ControlFlags 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;

            // 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 && move.Z == 0 &&
                fallVelocity == 0.0f && !heldUp &&
                !heldDown && move.CompareTo(Vector3.Zero) == 0)
            {
                return("TURNLEFT");
            }
            if (heldTurnRight && yawNeg && !heldForward &&
                !heldBack && actor != null && !actor.IsJumping &&
                !actor.Flying && move.Z == 0 &&
                fallVelocity == 0.0f && !heldUp &&
                !heldDown && move.CompareTo(Vector3.Zero) == 0)
            {
                return("TURNRIGHT");
            }

            #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");
            }
            else if (standupElapsed < BRUSH_TIME &&
                     m_useSplatAnimation)
            {
                m_scenePresence.FallenStandUp = true;
                return("BRUSH");
            }
            else if (m_animTickStandup != 0 || 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 (move.X != 0f || move.Y != 0f)
                {
                    if (move.Z == 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_FORWARD");
                        }
                        else
                        {
                            if (m_timesBeforeSlowFlyIsOff < SLOWFLY_DELAY)
                            {
                                m_timesBeforeSlowFlyIsOff++;
                                return("FLYSLOW");
                            }
                            else
                            {
                                return("FLY");
                            }
                        }
                    }
                    else if (move.Z > 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_UP");
                        }
                        else
                        {
                            return("FLYSLOW");
                        }
                    }
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    {
                        return("SWIM_DOWN");
                    }
                    else
                    {
                        return("FLY");
                    }
                }
                else 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");
                    }
                    else
                    {
                        return("HOVER_UP");
                    }
                }
                else 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");
                    }
                    else
                    {
                        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");
                            }
                            else
                            {
                                return("HOVER_DOWN");
                            }
                        }
                        else
                        {
                            return("HOVER_DOWN");
                        }
                    }
                }
                else
                {
                    //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");
                    }
                    else
                    {
                        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 || m_animTickWalk == 0))//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 (m_animTickFall == 0)
                {
                    m_animTickFall = Util.EnvironmentTickCount();
                }
                return("FALLDOWN");
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

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

                    return("SOFT_LAND");
                }
                else if (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");
                }
                else
                {
                    if (m_useSplatAnimation)
                    {
                        m_animTickStandup = Util.EnvironmentTickCount();
                        return("STANDUP");
                    }
                    else
                    {
                        return("LAND");
                    }
                }
            }
            else if (m_movementAnimation == "LAND")
            {
                if (actor != null && actor.Velocity.Z < 0)
                {
                    if (actor.Velocity.Z < SOFTLAND_FORCE)
                    {
                        return("LAND");
                    }
                    return("SOFT_LAND");
                }
            }

            m_animTickFall = 0;

            if (move.Z <= 0f)
            {
                if (actor != null && (move.X != 0f || move.Y != 0f ||
                                      actor.Velocity.X != 0 && actor.Velocity.Y != 0))
                {
                    wasLastFlying = false;
                    if (actor.IsColliding)
                    {
                        m_animTickWalk = Util.EnvironmentTickCount();
                    }
                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                    {
                        return("CROUCHWALK");
                    }
                    else if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
                else
                {
                    // Not walking
                    if (move.Z < 0f && !wasLastFlying)
                    {
                        return("CROUCH");
                    }
                    else
                    {
                        return("STAND");
                    }
                }
            }

            #endregion Ground Movement

            return(m_movementAnimation);
        }
Beispiel #20
0
        private void CopyFrom(AgentData cAgent)
        {
            m_originRegionID = cAgent.RegionID;

            m_callbackURI = cAgent.CallbackURI;

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            CameraPosition = cAgent.Center;
            CameraAtAxis = cAgent.AtAxis;
            CameraLeftAxis = cAgent.LeftAxis;
            m_CameraUpAxis = cAgent.UpAxis;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // DrawDistance = cAgent.Far;
            DrawDistance = Scene.DefaultDrawDistance;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            Rotation = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                GodLevel = cAgent.GodLevel;
            SetAlwaysRun = cAgent.AlwaysRun;

            Appearance = new AvatarAppearance(cAgent.Appearance);
            if (PhysicsActor != null)
            {
                bool isFlying = Flying;
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
            
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }

            // FIXME: Why is this null check necessary?  Where are the cases where we get a null Anims object?
            if (cAgent.Anims != null)
                Animator.Animations.FromArray(cAgent.Anims);

            if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0)
            {
                m_attachments = new List<SceneObjectGroup>();
                int i = 0;
                foreach (ISceneObject so in cAgent.AttachmentObjects)
                {
                    ((SceneObjectGroup)so).LocalId = 0;
                    ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
                    so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
                    m_scene.IncomingCreateObject(so);
                }
            }
        }
        public virtual void InTransit()
        {
            m_inTransit = true;

            if ((m_physicsActor != null) && m_physicsActor.Flying)
                m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY;
            else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0)
                m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY;
        }
Beispiel #22
0
        /// <summary>
        /// This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
            //m_log.DebugFormat(
            //    "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
            //    Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);

            if (IsChildAgent)
            {
            //    // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
                return;
            }

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                RemoveFromPhysicalScene();
                m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");

                m_pos = m_LastFinitePos;
                if (!m_pos.IsFinite())
                {
                    m_pos.X = 127f;
                    m_pos.Y = 127f;
                    m_pos.Z = 127f;
                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
                }

                AddToPhysicalScene(false);
            }
            else
            {
                m_LastFinitePos = m_pos;
            }

            #endregion Sanity Checking

            #region Inputs

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;

            // The Agent's Draw distance setting
            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // DrawDistance = agentData.Far;
            DrawDistance = Scene.DefaultDrawDistance;

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;

            #endregion Inputs

//            // Make anims work for client side autopilot
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
//                m_updateCount = UPDATE_COUNT;
//
//            // Make turning in place work
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0 ||
//                (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
//                m_updateCount = UPDATE_COUNT;

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            uint flagsForScripts = (uint)flags;
            flags = RemoveIgnoredControls(flags, IgnoredControls);

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
                HandleAgentSitOnGround();

            // In the future, these values might need to go global.
            // Here's where you get them.
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            byte oldState = State;
            State = agentData.State;

            // We need to send this back to the client in order to stop the edit beams
            if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
                ControllingClient.SendAgentTerseUpdate(this);


            PhysicsActor actor = PhysicsActor;
            if (actor == null)
            {
                SendControlsToScripts(flagsForScripts);
                return;
            }

            if (AllowMovement && !SitGround)
            {
                Quaternion bodyRotation = agentData.BodyRotation;
                bool update_rotation = false;

                if (bodyRotation != Rotation)
                {
                    Rotation = bodyRotation;
                    update_rotation = true;
                }

                bool update_movementflag = false;

                if (agentData.UseClientAgentPosition)
                {
                    MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    MoveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;
                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;

                bool newFlying = actor.Flying;

                if (ForceFly)
                    newFlying = true;
                else if (FlyDisabled)
                    newFlying = false;
                else
                    newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != newFlying)
                {
                    // Note: ScenePresence.Flying is actually fetched from the physical actor
                    //     so setting PhysActor.Flying here also sets the ScenePresence's value.
                    actor.Flying = newFlying;
                    update_movementflag = true;
                }

                if (ParentID == 0)
                {
                    bool bAllowUpdateMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
                    if (!Flying && (m_mouseLook || m_leftButtonDown))
                        dirVectors = GetWalkDirectionVectors();
                    else
                        dirVectors = Dir_Vectors;

                    // The fact that MovementFlag is a byte needs to be fixed
                    // it really should be a uint
                    // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
                    uint nudgehack = 250;
                    foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                    {
                        if (((uint)flags & (uint)DCF) != 0)
                        {
                            DCFlagKeyPressed = true;

                            try
                            {
                                agent_control_v3 += dirVectors[i];
                                //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // Why did I get this?
                            }

                            if ((MovementFlag & (byte)(uint)DCF) == 0)
                            {
                                if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
                                    DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
                                {
                                    MovementFlag |= (byte)nudgehack;
                                }

                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
                                MovementFlag += (byte)(uint)DCF;
                                update_movementflag = true;
                            }
                        }
                        else
                        {
                            if ((MovementFlag & (byte)(uint)DCF) != 0 ||
                                ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
                                DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
                                && ((MovementFlag & (byte)nudgehack) == nudgehack))
                                ) // This or is for Nudge forward
                            {
                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
                                MovementFlag -= ((byte)(uint)DCF);
                                update_movementflag = true;

                                /*
                                    if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    && ((MovementFlag & (byte)nudgehack) == nudgehack))
                                    {
                                        m_log.Debug("Removed Hack flag");
                                    }
                                */
                            }
                            else
                            {
                                bAllowUpdateMoveToPosition = true;
                            }
                        }

                        i++;
                    }

                    if (MovingToTarget)
                    {
                        // If the user has pressed a key then we want to cancel any move to target.
                        if (DCFlagKeyPressed)
                        {
                            ResetMoveToTarget();
                            update_movementflag = true;
                        }
                        else if (bAllowUpdateMoveToPosition)
                        {
                            // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
                            // certain position.  It's only check for tolerance on returning to that position is 0.2
                            // rather than 1, at which point it removes its force target.
                            if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
                                update_movementflag = true;
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // 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)
                    {
                        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();
                    }
                }

                // 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))
                {
//                    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);

                    AddNewMovement(agent_control_v3);
                }
//                else
//                {
//                    if (!update_movementflag)
//                    {
//                        m_log.DebugFormat(
//                            "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
//                            m_scene.RegionInfo.RegionName, agent_control_v3, Name);
//                    }
//                }

                if (update_movementflag && ParentID == 0)
                    Animator.UpdateMovementAnimations();

                SendControlsToScripts(flagsForScripts);
            }

            // We need to send this back to the client in order to see the edit beams
            if ((State & (uint)AgentState.Editing) != 0)
                ControllingClient.SendAgentTerseUpdate(this);

            m_scene.EventManager.TriggerOnClientMovement(this);
        }
Beispiel #23
0
        /// <summary>
        /// This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
//                Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);

            if (IsChildAgent)
            {
            //    // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
                return;
            }

            ++m_movementUpdateCount;
            if (m_movementUpdateCount < 1)
                m_movementUpdateCount = 1;

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                RemoveFromPhysicalScene();
                m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");

                m_pos = m_LastFinitePos;
                if (!m_pos.IsFinite())
                {
                    m_pos.X = 127f;
                    m_pos.Y = 127f;
                    m_pos.Z = 127f;
                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
                }

                AddToPhysicalScene(false);
            }
            else
            {
                m_LastFinitePos = m_pos;
            }

            #endregion Sanity Checking

            #region Inputs

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;

            // Camera location in world.  We'll need to raytrace
            // from this location from time to time.
            CameraPosition = agentData.CameraCenter;
            if (Vector3.Distance(m_lastCameraPosition, CameraPosition) >= Scene.RootReprioritizationDistance)
            {
                ReprioritizeUpdates();
                m_lastCameraPosition = CameraPosition;
            }

            // Use these three vectors to figure out what the agent is looking at
            // Convert it to a Matrix and/or Quaternion
            CameraAtAxis = agentData.CameraAtAxis;
            CameraLeftAxis = agentData.CameraLeftAxis;
            CameraUpAxis = agentData.CameraUpAxis;

            // The Agent's Draw distance setting
            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            // DrawDistance = agentData.Far;
            DrawDistance = Scene.DefaultDrawDistance;

            // Check if Client has camera in 'follow cam' or 'build' mode.
            Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);

            m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
               && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;

            #endregion Inputs

//            // Make anims work for client side autopilot
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
//                m_updateCount = UPDATE_COUNT;
//
//            // Make turning in place work
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0 ||
//                (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
//                m_updateCount = UPDATE_COUNT;

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
            // Raycast from the avatar's head to the camera to see if there's anything blocking the view
            if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
            {
                if (m_followCamAuto)
                {
                    Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
                    m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
                }
            }

            uint flagsForScripts = (uint)flags;
            flags = RemoveIgnoredControls(flags, IgnoredControls);

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
                HandleAgentSitOnGround();

            // In the future, these values might need to go global.
            // Here's where you get them.
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            State = agentData.State;

            PhysicsActor actor = PhysicsActor;
            if (actor == null)
            {
                SendControlsToScripts(flagsForScripts);
                return;
            }

            if (AllowMovement && !SitGround)
            {
                Quaternion bodyRotation = agentData.BodyRotation;
                bool update_rotation = false;

                if (bodyRotation != Rotation)
                {
                    Rotation = bodyRotation;
                    update_rotation = true;
                }

                bool update_movementflag = false;

                if (agentData.UseClientAgentPosition)
                {
                    MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    MoveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;
                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;

                bool newFlying = actor.Flying;

                if (ForceFly)
                    newFlying = true;
                else if (FlyDisabled)
                    newFlying = false;
                else
                    newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != newFlying)
                {
                    // Note: ScenePresence.Flying is actually fetched from the physical actor
                    //     so setting PhysActor.Flying here also sets the ScenePresence's value.
                    actor.Flying = newFlying;
                    update_movementflag = true;
                }

                if (ParentID == 0)
                {
                    bool bAllowUpdateMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
                    if (!Flying && (m_mouseLook || m_leftButtonDown))
                        dirVectors = GetWalkDirectionVectors();
                    else
                        dirVectors = Dir_Vectors;

                    // The fact that MovementFlag is a byte needs to be fixed
                    // it really should be a uint
                    // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
                    uint nudgehack = 250;
                    foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                    {
                        if (((uint)flags & (uint)DCF) != 0)
                        {
                            DCFlagKeyPressed = true;

                            try
                            {
                                agent_control_v3 += dirVectors[i];
                                //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // Why did I get this?
                            }

                            if ((MovementFlag & (byte)(uint)DCF) == 0)
                            {
                                if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
                                    DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
                                {
                                    MovementFlag |= (byte)nudgehack;
                                }

                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
                                MovementFlag += (byte)(uint)DCF;
                                update_movementflag = true;
                            }
                        }
                        else
                        {
                            if ((MovementFlag & (byte)(uint)DCF) != 0 ||
                                ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE ||
                                DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT_NUDGE)
                                && ((MovementFlag & (byte)nudgehack) == nudgehack))
                                ) // This or is for Nudge forward
                            {
                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
                                MovementFlag -= ((byte)(uint)DCF);
                                update_movementflag = true;

                                /*
                                    if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    && ((MovementFlag & (byte)nudgehack) == nudgehack))
                                    {
                                        m_log.Debug("Removed Hack flag");
                                    }
                                */
                            }
                            else
                            {
                                bAllowUpdateMoveToPosition = true;
                            }
                        }

                        i++;
                    }

                    if (MovingToTarget)
                    {
                        // If the user has pressed a key then we want to cancel any move to target.
                        if (DCFlagKeyPressed)
                        {
                            ResetMoveToTarget();
                            update_movementflag = true;
                        }
                        else if (bAllowUpdateMoveToPosition)
                        {
                            // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
                            // certain position.  It's only check for tolerance on returning to that position is 0.2
                            // rather than 1, at which point it removes its force target.
                            if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
                                update_movementflag = true;
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // 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));

                    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();
                    }
                }

                // 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))
                {
//                    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);

                    AddNewMovement(agent_control_v3);
                }
//                else
//                {
//                    if (!update_movementflag)
//                    {
//                        m_log.DebugFormat(
//                            "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
//                            m_scene.RegionInfo.RegionName, agent_control_v3, Name);
//                    }
//                }

                if (update_movementflag && ParentID == 0)
                    Animator.UpdateMovementAnimations();

                SendControlsToScripts(flagsForScripts);
            }

            m_scene.EventManager.TriggerOnClientMovement(this);
            TriggerScenePresenceUpdated();
        }
Beispiel #24
0
        private void CopyFrom(AgentData cAgent)
        {
            m_callbackURI = cAgent.CallbackURI;
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
//                Name, m_scene.RegionInfo.RegionName, m_callbackURI);

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            CameraPosition = cAgent.Center;
            CameraAtAxis = cAgent.AtAxis;
            CameraLeftAxis = cAgent.LeftAxis;
            CameraUpAxis = cAgent.UpAxis;
            ParentUUID = cAgent.ParentPart;
            PrevSitOffset = cAgent.SitOffset;

            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.
            DrawDistance = cAgent.Far;
            // DrawDistance = Scene.DefaultDrawDistance;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            Rotation = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                GodLevel = cAgent.GodLevel;
            SetAlwaysRun = cAgent.AlwaysRun;

            Appearance = new AvatarAppearance(cAgent.Appearance);
            if (PhysicsActor != null)
            {
                bool isFlying = Flying;
                RemoveFromPhysicalScene();
                AddToPhysicalScene(isFlying);
            }
            
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.objectID = c.ObjectID;
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }

            // FIXME: Why is this null check necessary?  Where are the cases where we get a null Anims object?
            if (cAgent.Anims != null)
                Animator.Animations.FromArray(cAgent.Anims);
            if (cAgent.DefaultAnim != null)
                Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
            if (cAgent.AnimState != null)
                Animator.Animations.SetImplicitDefaultAnimation(cAgent.AnimState.AnimID, cAgent.AnimState.SequenceNum, UUID.Zero);

            if (Scene.AttachmentsModule != null)
            {
                // If the JobEngine is running we can schedule this job now and continue rather than waiting for all
                // attachments to copy, which might take a long time in the Hypergrid case as the entire inventory
                // graph is inspected for each attachments and assets possibly fetched.
                // 
                // We don't need to worry about a race condition as the job to later start the scripts is also 
                // JobEngine scheduled and so will always occur after this task.
                // XXX: This will not be true if JobEngine ever gets more than one thread.
                WorkManager.RunJob(
                    "CopyAttachments", 
                    o => Scene.AttachmentsModule.CopyAttachments(cAgent, this), 
                    null,
                    string.Format("Copy attachments for {0} entering {1}", Name, Scene.Name),
                    true);
            }

            // This must occur after attachments are copied or scheduled to be copied, as it releases the CompleteMovement() calling thread
            // originating from the client completing a teleport.  Otherwise, CompleteMovement() code to restart
            // script attachments can outrace this thread.
            lock (m_originRegionIDAccessLock)
                m_originRegionID = cAgent.RegionID;
        }
Beispiel #25
0
        /// <summary>
        /// This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
//            m_log.DebugFormat(
//                "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
//                Scene.Name, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);

            if (IsChildAgent)
            {
//                m_log.DebugFormat("DEBUG: HandleAgentUpdate: child agent in {0}", Scene.Name);
                return;
            }

            if (IsInTransit)
                return;

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                RemoveFromPhysicalScene();
                m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");

                m_pos = m_LastFinitePos;
                if (!m_pos.IsFinite())
                {
                    m_pos.X = 127f;
                    m_pos.Y = 127f;
                    m_pos.Z = 127f;
                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
                }

                AddToPhysicalScene(false);
            }
            else
            {
                m_LastFinitePos = m_pos;
            }

            #endregion Sanity Checking

            #region Inputs

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;

            // The Agent's Draw distance setting
            // When we get to the point of re-computing neighbors everytime this
            // changes, then start using the agent's drawdistance rather than the 
            // region's draw distance.

            DrawDistance = agentData.Far;

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;

            // FIXME: This does not work as intended because the viewer only sends the lbutton down when the button
            // is first pressed, not whilst it is held down.  If this is required in the future then need to look
            // for an AGENT_CONTROL_LBUTTON_UP event and make sure to handle cases where an initial DOWN is not 
            // received (e.g. on holding LMB down on the avatar in a viewer).
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;

            #endregion Inputs

//            // Make anims work for client side autopilot
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0)
//                m_updateCount = UPDATE_COUNT;
//
//            // Make turning in place work
//            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0 ||
//                (flags & AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
//                m_updateCount = UPDATE_COUNT;


            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            // Raycast from the avatar's head to the camera to see if there's anything blocking the view
            // this exclude checks may not be complete

            if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
            {
                if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
                {
                    Vector3 posAdjusted = AbsolutePosition;
//                    posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
                    posAdjusted.Z += 1.0f; // viewer current camera focus point
                    Vector3 tocam = CameraPosition - posAdjusted;
                    tocam.X = (float)Math.Round(tocam.X, 1);
                    tocam.Y = (float)Math.Round(tocam.Y, 1);
                    tocam.Z = (float)Math.Round(tocam.Z, 1);

                    float distTocamlen = tocam.Length();
                    if (distTocamlen > 0.3f)
                    {
                        tocam *= (1.0f / distTocamlen);
                        posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
                        posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
                        posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);

                        m_doingCamRayCast = true;
                        m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
                    }
                }
                else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
                {
                    Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
                    UpdateCameraCollisionPlane(plane);
                    CameraConstraintActive = false;
                }
            }

            uint flagsForScripts = (uint)flags;
            flags = RemoveIgnoredControls(flags, IgnoredControls);

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
                HandleAgentSitOnGround();

            // In the future, these values might need to go global.
            // Here's where you get them.
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            byte oldState = State;
            State = agentData.State;

            // We need to send this back to the client in order to stop the edit beams
            if ((oldState & (uint)AgentState.Editing) != 0 && State == (uint)AgentState.None)
                SendAgentTerseUpdate(this);

            PhysicsActor actor = PhysicsActor;

            // This will be the case if the agent is sitting on the groudn or on an object.
            if (actor == null)
            {
                SendControlsToScripts(flagsForScripts);
                return;
            }

            if (AllowMovement && !SitGround)
            {
//                m_log.DebugFormat("[SCENE PRESENCE]: Initial body rotation {0} for {1}", agentData.BodyRotation, Name);              
                bool update_rotation = false;
                if (agentData.BodyRotation != Rotation)
                {
                    Rotation = agentData.BodyRotation;
                    update_rotation = true;
                }

                bool update_movementflag = false;

                if (agentData.UseClientAgentPosition)
                {
                    MovingToTarget = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    MoveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;
                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;

                bool newFlying = false;

                if (ForceFly)
                    newFlying = true;
                else if (FlyDisabled)
                    newFlying = false;
                else
                    newFlying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != newFlying)
                {
                    // Note: ScenePresence.Flying is actually fetched from the physical actor
                    //     so setting PhysActor.Flying here also sets the ScenePresence's value.
                    actor.Flying = newFlying;
                    update_movementflag = true;
                }

                if (ParentID == 0)
                {
                    bool bAllowUpdateMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
//                    if (!Flying && (m_mouseLook || m_leftButtonDown))
//                        dirVectors = GetWalkDirectionVectors();
//                    else
                        dirVectors = Dir_Vectors;

                    // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
                    foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                    {
                        if (((uint)flags & (uint)DCF) != 0)
                        {
                            DCFlagKeyPressed = true;

                            try
                            {
                                agent_control_v3 += Dir_Vectors[i];
                                //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // Why did I get this?
                            }

                            if (((MovementFlag & (uint)DCF) == 0))
                            {   
                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
                                MovementFlag |= (uint)DCF;
                                update_movementflag = true;
                            }
                        }
                        else
                        {
                            if ((MovementFlag & (uint)DCF) != 0)
                            {
                                //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
                                MovementFlag &= (uint)~DCF;
                                update_movementflag = true;

                                /*
                                    if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    && ((MovementFlag & (byte)nudgehack) == nudgehack))
                                    {
                                        m_log.Debug("Removed Hack flag");
                                    }
                                */
                            }
                            else
                            {
                                bAllowUpdateMoveToPosition = true;
                            }
                        }

                        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.
                        if (DCFlagKeyPressed)
                        {
                            ResetMoveToTarget();
                            update_movementflag = true;
                        }
                        else if (bAllowUpdateMoveToPosition)
                        {
                            // The UseClientAgentPosition is set if parcel ban is forcing the avatar to move to a
                            // certain position.  It's only check for tolerance on returning to that position is 0.2
                            // rather than 1, at which point it removes its force target.
                            if (HandleMoveToTargetUpdate(agentData.UseClientAgentPosition ? 0.2 : 1, ref agent_control_v3))
                                update_movementflag = true;
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // Only do this if we're flying
                if (Flying && !ForceFly)
                {
                    // Need to stop in mid air if user holds down AGENT_CONTROL_STOP
                    //                    if (AgentControlStopActive)
                    //                    {
                    //                        agent_control_v3 = Vector3.Zero;
                    //                    }
                    //                    else
                    {
                        // 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)
                        {
                            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();
                                                }
                         */
                    }
                }
                else if (IsColliding && agent_control_v3.Z < 0f)
                    agent_control_v3.Z = 0;
//                else if(AgentControlStopActive %% Velocity.Z <0.01f)
                    

//                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
                // 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)))
                {

                    if (AgentControlStopActive)
                    {
                        //                        if (MovementFlag == 0 && Animator.Falling)
                        if (MovementFlag == 0 && Animator.currentControlState == ScenePresenceAnimator.motionControlStates.falling)
                        {
                            AddNewMovement(agent_control_v3, AgentControlStopSlowVel, true);
                        }
                        else
                            AddNewMovement(agent_control_v3, AgentControlStopSlowVel);
                    }
                    else
                    {
                        AddNewMovement(agent_control_v3);
                    }

                }

                if (update_movementflag && ParentID == 0)
                {
//                    m_log.DebugFormat("[SCENE PRESENCE]: Updating movement animations for {0}", Name);
                    Animator.UpdateMovementAnimations();
                }

                SendControlsToScripts(flagsForScripts);
            }

            // We need to send this back to the client in order to see the edit beams
            if ((State & (uint)AgentState.Editing) != 0)
                SendAgentTerseUpdate(this);

            m_scene.EventManager.TriggerOnClientMovement(this);
        }
        /// <summary>
        /// This is the event handler for client movement. If a client is moving, this event is triggering.
        /// </summary>
        public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
        {
            //if (m_isChildAgent)
            //{
            //    // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
            //    return;
            //}

            m_perfMonMS = Util.EnvironmentTickCount();

            ++m_movementUpdateCount;
            if (m_movementUpdateCount < 1)
                m_movementUpdateCount = 1;

            #region Sanity Checking

            // This is irritating.  Really.
            if (!AbsolutePosition.IsFinite())
            {
                RemoveFromPhysicalScene();
                m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");

                m_pos = m_LastFinitePos;
                if (!m_pos.IsFinite())
                {
                    m_pos.X = 127f;
                    m_pos.Y = 127f;
                    m_pos.Z = 127f;
                    m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903");
                }

                AddToPhysicalScene(false);
            }
            else
            {
                m_LastFinitePos = m_pos;
            }

            #endregion Sanity Checking

            #region Inputs

            AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags;
            Quaternion bodyRotation = agentData.BodyRotation;

            // Camera location in world.  We'll need to raytrace
            // from this location from time to time.
            m_CameraCenter = agentData.CameraCenter;
            if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance)
            {
                ReprioritizeUpdates();
                m_lastCameraCenter = m_CameraCenter;
            }

            // Use these three vectors to figure out what the agent is looking at
            // Convert it to a Matrix and/or Quaternion
            m_CameraAtAxis = agentData.CameraAtAxis;
            m_CameraLeftAxis = agentData.CameraLeftAxis;
            m_CameraUpAxis = agentData.CameraUpAxis;

            // The Agent's Draw distance setting
            m_DrawDistance = agentData.Far;

            // Check if Client has camera in 'follow cam' or 'build' mode.
            Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);

            m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
               && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;

            m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
            m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;

            #endregion Inputs

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0)
            {
                StandUp();
            }

            //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
            // Raycast from the avatar's head to the camera to see if there's anything blocking the view
            if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
            {
                if (m_followCamAuto)
                {
                    Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
                    m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
                }
            }

            lock (scriptedcontrols)
            {
                if (scriptedcontrols.Count > 0)
                {
                    SendControlToScripts((uint)flags);
                    flags = RemoveIgnoredControls(flags, IgnoredControls);
                }
            }

            if (m_autopilotMoving)
                CheckAtSitTarget();

            if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
            {
                // TODO: This doesn't prevent the user from walking yet.
                // Setting parent ID would fix this, if we knew what value
                // to use.  Or we could add a m_isSitting variable.
                //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
                SitGround = true;
                
            }

            // In the future, these values might need to go global.
            // Here's where you get them.
            m_AgentControlFlags = flags;
            m_headrotation = agentData.HeadRotation;
            m_state = agentData.State;

            PhysicsActor actor = PhysicsActor;
            if (actor == null)
            {
                return;
            }
            
            bool update_movementflag = false;

            if (m_allowMovement)
            {
                if (agentData.UseClientAgentPosition)
                {
                    m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f;
                    m_moveToPositionTarget = agentData.ClientAgentPosition;
                }

                int i = 0;
                
                bool update_rotation = false;
                bool DCFlagKeyPressed = false;
                Vector3 agent_control_v3 = Vector3.Zero;
                Quaternion q = bodyRotation;

                bool oldflying = PhysicsActor.Flying;

                if (m_forceFly)
                    actor.Flying = true;
                else if (m_flyDisabled)
                    actor.Flying = false;
                else
                    actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);

                if (actor.Flying != oldflying)
                    update_movementflag = true;

                if (q != m_bodyRot)
                {
                    m_bodyRot = q;
                    update_rotation = true;
                }

                if (m_parentID == 0)
                {
                    bool bAllowUpdateMoveToPosition = false;
                    bool bResetMoveToPosition = false;

                    Vector3[] dirVectors;

                    // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying
                    // this prevents 'jumping' in inappropriate situations.
                    if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying))
                        dirVectors = GetWalkDirectionVectors();
                    else
                        dirVectors = Dir_Vectors;

                    // The fact that m_movementflag is a byte needs to be fixed
                    // it really should be a uint
                    uint nudgehack = 250;
                    foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
                    {
                        if (((uint)flags & (uint)DCF) != 0)
                        {
                            bResetMoveToPosition = true;
                            DCFlagKeyPressed = true;
                            try
                            {
                                agent_control_v3 += dirVectors[i];
                                //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
                            }
                            catch (IndexOutOfRangeException)
                            {
                                // Why did I get this?
                            }

                            if ((m_movementflag & (byte)(uint)DCF) == 0)
                            {
                                if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                {
                                    m_movementflag |= (byte)nudgehack;
                                }
                                m_movementflag += (byte)(uint)DCF;
                                update_movementflag = true;
                            }
                        }
                        else
                        {
                            if ((m_movementflag & (byte)(uint)DCF) != 0 ||
                                ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                && ((m_movementflag & (byte)nudgehack) == nudgehack))
                                ) // This or is for Nudge forward
                            {
                                m_movementflag -= ((byte)(uint)DCF);

                                update_movementflag = true;
                                /*
                                    if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
                                    && ((m_movementflag & (byte)nudgehack) == nudgehack))
                                    {
                                        m_log.Debug("Removed Hack flag");
                                    }
                                */
                            }
                            else
                            {
                                bAllowUpdateMoveToPosition = true;
                            }
                        }
                        i++;
                    }

                    //Paupaw:Do Proper PID for Autopilot here
                    if (bResetMoveToPosition)
                    {
                        m_moveToPositionTarget = Vector3.Zero;
                        m_moveToPositionInProgress = false;
                        update_movementflag = true;
                        bAllowUpdateMoveToPosition = false;
                    }

                    if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving))
                    {
                        //Check the error term of the current position in relation to the target position
                        if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
                        {
                            // we are close enough to the target
                            m_moveToPositionTarget = Vector3.Zero;
                            m_moveToPositionInProgress = false;
                            update_movementflag = true;
                        }
                        else
                        {
                            try
                            {
                                // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
                                // This movement vector gets added to the velocity through AddNewMovement().
                                // Theoretically we might need a more complex PID approach here if other 
                                // unknown forces are acting on the avatar and we need to adaptively respond
                                // to such forces, but the following simple approach seems to works fine.
                                Vector3 LocalVectorToTarget3D =
                                    (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
                                    * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
                                // Ignore z component of vector
                                Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
                                LocalVectorToTarget2D.Normalize();
                                agent_control_v3 += LocalVectorToTarget2D;

                                // update avatar movement flags. the avatar coordinate system is as follows:
                                //
                                //                        +X (forward)
                                //
                                //                        ^
                                //                        |
                                //                        |
                                //                        |
                                //                        |
                                //     (left) +Y <--------o--------> -Y
                                //                       avatar
                                //                        |
                                //                        |
                                //                        |
                                //                        |
                                //                        v
                                //                        -X
                                //

                                // based on the above avatar coordinate system, classify the movement into 
                                // one of left/right/back/forward.
                                if (LocalVectorToTarget2D.Y > 0)//MoveLeft
                                {
                                    m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
                                    //AgentControlFlags
                                    AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
                                    update_movementflag = true;
                                }
                                else if (LocalVectorToTarget2D.Y < 0) //MoveRight
                                {
                                    m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
                                    AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
                                    update_movementflag = true;
                                }
                                if (LocalVectorToTarget2D.X < 0) //MoveBack
                                {
                                    m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
                                    AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
                                    update_movementflag = true;
                                }
                                else if (LocalVectorToTarget2D.X > 0) //Move Forward
                                {
                                    m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
                                    AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
                                    update_movementflag = true;
                                }
                            }
                            catch (Exception e)
                            {
                                //Avoid system crash, can be slower but...
                                m_log.DebugFormat("Crash! {0}", e.ToString());
                            }
                        }
                    }
                }

                // Cause the avatar to stop flying if it's colliding
                // with something with the down arrow pressed.

                // Only do this if we're flying
                if (m_physicsActor != null && m_physicsActor.Flying && !m_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));

                    // Are the collision requirements fulfilled?
                    bool colliding = (m_physicsActor.IsColliding == true);

                    if (m_physicsActor.Flying && colliding && 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();
                    }
                }

                if (update_movementflag || (update_rotation && DCFlagKeyPressed))
                {
                    //                    m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed));
                    //                    m_log.DebugFormat(
                    //                        "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3);

                    AddNewMovement(agent_control_v3, q);

                    
                }
            }

            if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround)
                Animator.UpdateMovementAnimations();

            m_scene.EventManager.TriggerOnClientMovement(this);

            m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
        }
Beispiel #27
0
        /// <summary>
        /// This method determines the proper movement related animation
        /// </summary>
        private string GetMovementAnimation()
        {
            const float SLOWFLY_DELAY = 15f;
            const float STANDUP_TIME  = 2f;
            const float BRUSH_TIME    = 3.5f;

            const float SOFTLAND_FORCE = 80;

            const float PREJUMP_DELAY = 0.35f;

            #region Inputs

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

            // Create forward and left vectors from the current avatar rotation

            /*
             *          Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
             *          Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
             *          Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
             */

            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;
            }
            bool  jumping      = m_animTickJump != 0;
            float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;

            if (heldTurnLeft && yawPos && !heldForward &&
                !heldBack && !jumping && actor != null &&
                !actor.Flying && move.Z == 0 &&
                fallVelocity == 0.0f && !heldUp &&
                !heldDown && move.CompareTo(Vector3.Zero) == 0)
            {
                return("TURNLEFT");
            }
            if (heldTurnRight && yawNeg && !heldForward &&
                !heldBack && !jumping && actor != null &&
                !actor.Flying && move.Z == 0 &&
                fallVelocity == 0.0f && !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 = (float)(Util.EnvironmentTickCount() - m_animTickStandup) / 1000f;
            if (standupElapsed < STANDUP_TIME &&
                m_useSplatAnimation)
            {
                // Falling long enough to trigger the animation
                m_scenePresence.AllowMovement         = false;
                m_scenePresence.PhysicsActor.Velocity = Vector3.Zero;
                return("STANDUP");
            }
            else if (standupElapsed < BRUSH_TIME &&
                     m_useSplatAnimation)
            {
                m_scenePresence.AllowMovement = false;
                return("BRUSH");
            }
            else if (m_animTickStandup != 0)
            {
                m_animTickStandup             = 0;
                m_scenePresence.AllowMovement = true;
            }

            #endregion Standup

            #region Flying

//            if (actor != null && actor.Flying)
            if (actor != null && (m_scenePresence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) == (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY)
            {
                m_animTickFall = 0;
                m_animTickJump = 0;
                if (move.X != 0f || move.Y != 0f)
                {
                    if (move.Z == 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_FORWARD");
                        }
                        else
                        {
                            if (m_timesBeforeSlowFlyIsOff < SLOWFLY_DELAY)
                            {
                                m_timesBeforeSlowFlyIsOff++;
                                return("FLYSLOW");
                            }
                            else
                            {
                                return("FLY");
                            }
                        }
                    }
                    else if (move.Z > 0)
                    {
                        if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                            actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                        {
                            return("SWIM_UP");
                        }
                        else
                        {
                            return("FLYSLOW");
                        }
                    }
                    if (m_scenePresence.Scene.PhysicsScene.UseUnderWaterPhysics &&
                        actor.Position.Z < m_scenePresence.Scene.RegionInfo.RegionSettings.WaterHeight)
                    {
                        return("SWIM_DOWN");
                    }
                    else
                    {
                        return("FLY");
                    }
                }
                else 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");
                    }
                    else
                    {
                        return("HOVER_UP");
                    }
                }
                else 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_DOWN");
                    }
                    else
                    {
                        ITerrainChannel channel      = m_scenePresence.Scene.RequestModuleInterface <ITerrainChannel>();
                        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");
                        }
                        else
                        {
                            return("HOVER_DOWN");
                        }
                    }
                }
                else
                {
                    //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");
                    }
                    else
                    {
                        return("HOVER");
                    }
                }
            }

            m_timesBeforeSlowFlyIsOff = 0;
            #endregion Flying

            #region Falling/Floating/Landing

            if (actor == null && !jumping && move.Z == 0 || (actor != null && (!actor.CollidingObj && !actor.CollidingGround) && m_scenePresence.Velocity.Z < -2))
            {
                //Always return falldown immediately as there shouldn't be a waiting period
                if (m_animTickFall == 0)
                {
                    m_animTickFall = Util.EnvironmentTickCount();
                }
                return("FALLDOWN");
            }

            #endregion Falling/Floating/Landing

            #region Ground Movement

            //This needs to be in front of landing, otherwise you get odd landing effects sometimes when one jumps
            // -- Revolution
            if (move.Z > 0f || m_animTickJump != 0)
            {
                if (m_usePreJump)
                {
                    //This is to check to make sure they arn't trying to fly up by holding down jump
                    if ((m_scenePresence.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) == 0)
                    {
                        // Jumping
                        float jumpChange = (((float)Util.EnvironmentTickCount()) - m_animTickJump) / 1000;
                        if (!jumping || (jumpChange < PREJUMP_DELAY && m_animTickJump > 0))
                        {
                            // Begin prejump
                            if (m_animTickJump == 0)
                            {
                                m_animTickJump = (float)Util.EnvironmentTickCount();
                            }
                            return("PREJUMP");
                        }
                        else if (m_animTickJump != 0)
                        {
                            #region PreJump

                            /*m_hasPreJumped = true;
                             * if (m_scenePresence.PreJumpForce.Z != 0 && !m_hasJumpAddedForce)
                             * {
                             *  m_hasJumpAddedForce = true;
                             *  m_scenePresence.PreJumpForce.X /= 2f;
                             *  m_scenePresence.PreJumpForce.Y /= 2f;
                             *  //m_scenePresence.PreJumpForce.Z *= 1.75f;
                             *  if(m_scenePresence.Scene.m_UseNewStyleMovement)
                             *      m_scenePresence.m_velocityIsDecaying = false;
                             *
                             *  m_scenePresence.PhysicsActor.Velocity = m_scenePresence.PreJumpForce;
                             *  //m_scenePresence.m_forceToApply = m_scenePresence.PreJumpForce;
                             *
                             *  m_scenePresence.PreJumpForce = new Vector3(
                             *      m_scenePresence.PreJumpForce.X > 0 ? 7 : (m_scenePresence.PreJumpForce.X < 0 ? -3 : 0),
                             *      m_scenePresence.PreJumpForce.Y > 0 ? 7 : (m_scenePresence.PreJumpForce.Y < 0 ? -3 : 0),
                             *      0);
                             *
                             *  m_jumpZ = 0;
                             *  return "JUMP";
                             * }
                             *
                             * if (jumpChange >= 3) //Kill this if it takes too long
                             * {
                             *  m_scenePresence.PhysicsActor.Velocity = Vector3.Zero;
                             *  m_animTickJump = 0;
                             *  m_scenePresence.AllowMovement = true;
                             *  if (m_scenePresence.Scene.m_UseNewStyleMovement)
                             *      m_scenePresence.m_velocityIsDecaying = true;
                             *  m_animTickNextJump = Util.TickCount();
                             *  return "STAND";
                             * }
                             *
                             * //Check #1: Going up.
                             * if (m_jumpZ == 0 &&
                             *  m_scenePresence.Velocity.Z >= -0.3)
                             * {
                             *  //This stops from double jump when you jump straight up and doesn't break jumping with X and Y velocity
                             *  //This particular check makes sure that we do not break jumping straight up
                             *  if (!m_scenePresence.m_forceToApply.HasValue ||
                             *       (m_scenePresence.m_forceToApply.HasValue &&
                             *       m_scenePresence.m_forceToApply.Value.X != 0 &&
                             *       m_scenePresence.m_forceToApply.Value.Y != 0))
                             *  {
                             *      m_scenePresence.PreJumpForce.Z = -1f;
                             *
                             *      m_scenePresence.m_forceToApply = m_scenePresence.PreJumpForce;
                             *  }
                             *
                             *  m_scenePresence.AllowMovement = false;
                             *  return "JUMP";
                             * }
                             * //Check #2: Coming down
                             * else if (m_jumpZ <= 1 &&
                             *  m_scenePresence.Velocity.Z < 0)
                             * {
                             *  m_jumpZ = 1;
                             *  //This stops from double jump when you jump straight up and doesn't break jumping with X and Y velocity
                             *  //This particular check makes sure that we do not break jumping straight up
                             *  if (!m_scenePresence.m_forceToApply.HasValue ||
                             *       (m_scenePresence.m_forceToApply.HasValue &&
                             *       m_scenePresence.m_forceToApply.Value.X != 0 &&
                             *       m_scenePresence.m_forceToApply.Value.Y != 0))
                             *  {
                             *      m_scenePresence.PreJumpForce.Z = -0.1f;
                             *
                             *      m_scenePresence.m_forceToApply = m_scenePresence.PreJumpForce;
                             *  }
                             *
                             *  m_scenePresence.AllowMovement = false;
                             *  return "JUMP";
                             * }
                             * else
                             * {
                             *  //m_scenePresence.m_forceToApply = Vector3.Zero;
                             *  m_scenePresence.PhysicsActor.Velocity = Vector3.Zero;
                             *  m_animTickJump = 0;
                             *  m_scenePresence.AllowMovement = true;
                             *  if (m_scenePresence.Scene.m_UseNewStyleMovement)
                             *      m_scenePresence.m_velocityIsDecaying = true;
                             *  m_animTickNextJump = Util.EnvironmentTickCount();
                             *  return "STAND";
                             * }*/
                            #endregion
                            if (m_scenePresence.PreJumpForce != Vector3.Zero)
                            {
                                Vector3 jumpForce = m_scenePresence.PreJumpForce;
                                m_scenePresence.PreJumpForce = Vector3.Zero;
                                m_scenePresence.AddNewMovement(jumpForce, Quaternion.Identity);
                                m_animTickJump = -42;
                                return("JUMP");
                            }

                            m_animTickJump++;
                            //This never gets hit as velocity is really broken
                            //if (m_scenePresence.Velocity.Z < -0.50)
                            //{
                            //    m_scenePresence.m_forceToApply = Vector3.Zero;
                            //    m_scenePresence.m_overrideUserInput = false;
                            //}
                            return("JUMP");
                        }
                    }
                }
                else
                {
                    // Jumping
                    //float jumpChange = (((float)Util.EnvironmentTickCount()) - m_animTickJump) / 1000;
                    if (!jumping)
                    {
                        m_animTickJump = Util.EnvironmentTickCount();
                        return("JUMP");
                    }
                    else
                    {
                        // Start actual jump
                        if (m_animTickJump > 0)
                        {
                            m_animTickJump = -20;
                            return("JUMP");
                        }

                        m_animTickJump++;
                        return("JUMP");
                    }
                }
            }
            if (m_scenePresence.IsJumping)
            {
                m_scenePresence.IsJumping     = false;
                m_scenePresence.AllowMovement = true;
            }

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

                    return("SOFT_LAND");
                }
                else if (fallElapsed < 1.1)
                {
                    m_animTickFall = Util.EnvironmentTickCount();

                    return("LAND");
                }
                else
                {
                    if (m_useSplatAnimation)
                    {
                        m_animTickStandup = Util.EnvironmentTickCount();
                        return("STANDUP");
                    }
                    else
                    {
                        return("LAND");
                    }
                }

                /*//Experimentally found variables, but it makes soft landings look good.
                 * // -- Revolution
                 * //Note: we use m_scenePresence.LastVelocity for a reason! The PhysActor and SP Velocity are both cleared before this is called.
                 *
                 * float Z = m_scenePresence.LastVelocity.Z * m_scenePresence.LastVelocity.Z;
                 * if (Math.Abs(m_scenePresence.LastVelocity.X) < 0.1 && Math.Abs(m_scenePresence.LastVelocity.Y) < 0.1)
                 *  Z *= Z; //If you are falling down, the calculation is different..
                 * if (Z < SOFTLAND_FORCE)
                 * {
                 *  m_animTickFall = Util.EnvironmentTickCount();
                 *
                 *  return "SOFT_LAND";
                 * }
                 * else if (Z < LAND_FORCE)
                 * {
                 *  m_animTickFall = Util.EnvironmentTickCount();
                 *
                 *  return "LAND";
                 * }
                 * else
                 * {
                 *  if (m_scenePresence.Scene.m_useSplatAnimation)
                 *  {
                 *      m_animTickStandup = Util.EnvironmentTickCount();
                 *      return "STANDUP";
                 *  }
                 *  else
                 *      return "LAND";
                 * }*/
            }
            else if (m_movementAnimation == "LAND")
            {
                if (actor.Velocity.Z != 0)
                {
                    if (actor.Velocity.Z < SOFTLAND_FORCE)
                    {
                        return("LAND");
                    }
                    return("SOFT_LAND");
                }
            }

            m_animTickFall = 0;

            if (move.Z <= 0f)
            {
                // Not jumping
                m_animTickJump = 0;

                if (move.X != 0f || move.Y != 0f ||
                    actor.Velocity.X != 0 && actor.Velocity.Y != 0)
                {
                    // Walking / crouchwalking / running
                    if (move.Z < 0f)
                    {
                        return("CROUCHWALK");
                    }
                    else if (m_scenePresence.SetAlwaysRun)
                    {
                        return("RUN");
                    }
                    else
                    {
                        return("WALK");
                    }
                }
                else
                {
                    // Not walking
                    if (move.Z < 0f)
                    {
                        return("CROUCH");
                    }
                    else
                    {
                        return("STAND");
                    }
                }
            }

            #endregion Ground Movement

            return(m_movementAnimation);
        }
        public void CopyFrom(AgentData cAgent)
        {
// DEBUG ON
            m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM");
// DEBUG OFF
            m_originRegionID = cAgent.RegionID;

            m_callbackURI = cAgent.CallbackURI;

            m_pos = cAgent.Position;
            m_velocity = cAgent.Velocity;
            m_CameraCenter = cAgent.Center;
            //m_avHeight = cAgent.Size.Z;
            m_CameraAtAxis = cAgent.AtAxis;
            m_CameraLeftAxis = cAgent.LeftAxis;
            m_CameraUpAxis = cAgent.UpAxis;

            m_DrawDistance = cAgent.Far;

            if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0)
                ControllingClient.SetChildAgentThrottle(cAgent.Throttles);

            m_headrotation = cAgent.HeadRotation;
            m_bodyRot = cAgent.BodyRotation;
            m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; 

            if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID)))
                m_godLevel = cAgent.GodLevel;
            m_setAlwaysRun = cAgent.AlwaysRun;

            m_appearance = new AvatarAppearance(cAgent.Appearance);
            
/*
            uint i = 0;
            try
            {
                if (cAgent.Wearables == null)
                   cAgent.Wearables  = new UUID[0];
                AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2];
                for (uint n = 0; n < cAgent.Wearables.Length; n += 2)
                {
                    UUID itemId = cAgent.Wearables[n];
                    UUID assetId = cAgent.Wearables[n + 1];
                    wears[i++] = new AvatarWearable(itemId, assetId);
                }
                // m_appearance.Wearables = wears;
                Primitive.TextureEntry textures = null;
                if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1)
                    textures = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length);

                byte[] visuals = null;

                if ((cAgent.VisualParams != null) && (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT))
                    visuals = (byte[])cAgent.VisualParams.Clone();

                m_appearance = new AvatarAppearance(cAgent.AgentID,wears,textures,visuals);
            }
            catch (Exception e)
            {
                m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message);
            }

            // Attachments
            try
            {
                if (cAgent.Attachments != null)
                {
                    m_appearance.ClearAttachments();
                    foreach (AvatarAttachment att in cAgent.Attachments)
                    {
                        m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID);
                    }
                }
            }
            catch { } 
*/
            try
            {
                lock (scriptedcontrols)
                {
                    if (cAgent.Controllers != null)
                    {
                        scriptedcontrols.Clear();

                        foreach (ControllerData c in cAgent.Controllers)
                        {
                            ScriptControllers sc = new ScriptControllers();
                            sc.itemID = c.ItemID;
                            sc.ignoreControls = (ScriptControlled)c.IgnoreControls;
                            sc.eventControls = (ScriptControlled)c.EventControls;

                            scriptedcontrols[sc.itemID] = sc;
                        }
                    }
                }
            }
            catch { }
            // Animations
            try
            {
                Animator.ResetAnimations();
                Animator.Animations.FromArray(cAgent.Anims);
            }
            catch {  }

            //cAgent.GroupID = ??
            //Groups???
        }