From 40fd37f95af68a213b0c3a465858c27fa7c8cfdf Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Mon, 10 Dec 2007 15:08:44 +0000 Subject: [PATCH] Refactored animation handling in ScenePresence. Now maintains a list of current animations. * Fixes weirdness when typing and sitting at the same time * Should fix bug #32 (getting stuck in edit appearance pose) * Crouchwalk and possibly jump may need more looking into --- OpenSim/Framework/IClientAPI.cs | 6 +- OpenSim/Region/ClientStack/ClientView.cs | 23 ++- .../Scenes/Scene.PacketHandlers.cs | 5 - OpenSim/Region/Environment/Scenes/Scene.cs | 1 - .../Environment/Scenes/ScenePresence.cs | 191 ++++++++++-------- .../Examples/SimpleApp/MyNpcCharacter.cs | 7 +- 6 files changed, 135 insertions(+), 98 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 6898f91d68..98c7a18d59 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -235,6 +235,8 @@ namespace OpenSim.Framework public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq); + public delegate void StopAnim(IClientAPI remoteClient, LLUUID animID); + public delegate void LinkObjects(uint parent, List children); public delegate void DelinkObjects(List primIds); @@ -249,6 +251,7 @@ namespace OpenSim.Framework public delegate void DisconnectUser(); public delegate void RequestAvatarProperties(IClientAPI remoteClient, LLUUID avatarID); + public delegate void SetAlwaysRun(IClientAPI remoteClient, bool SetAlwaysRun); public delegate void GenericCall2(); @@ -375,6 +378,7 @@ namespace OpenSim.Framework event SetAppearance OnSetAppearance; event AvatarNowWearing OnAvatarNowWearing; event StartAnim OnStartAnim; + event StopAnim OnStopAnim; event LinkObjects OnLinkObjects; event DelinkObjects OnDelinkObjects; event RequestMapBlocks OnRequestMapBlocks; @@ -468,7 +472,7 @@ namespace OpenSim.Framework void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry); void SendStartPingCheck(byte seq); void SendKillObject(ulong regionHandle, uint localID); - void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId); + void SendAnimations(LLUUID[] animID, int[] seqs, LLUUID sourceAgentId); void SendRegionHandshake(RegionInfo regionInfo); void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 1a544b8a7a..db25ee686e 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -392,6 +392,7 @@ namespace OpenSim.Region.ClientStack public event AgentSit OnAgentSit; public event AvatarPickerRequest OnAvatarPickerRequest; public event StartAnim OnStartAnim; + public event StopAnim OnStopAnim; public event Action OnRequestAvatarsData; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; @@ -1265,7 +1266,7 @@ namespace OpenSim.Region.ClientStack OutPacket(avp, ThrottleOutPacketType.Task); } - public void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId) + public void SendAnimations(LLUUID[] animations, int[] seqs, LLUUID sourceAgentId) { AvatarAnimationPacket ani = new AvatarAnimationPacket(); ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1]; @@ -1273,10 +1274,15 @@ namespace OpenSim.Region.ClientStack ani.AnimationSourceList[0].ObjectID = sourceAgentId; ani.Sender = new AvatarAnimationPacket.SenderBlock(); ani.Sender.ID = sourceAgentId; - ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1]; - ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock(); - ani.AnimationList[0].AnimID = animID; - ani.AnimationList[0].AnimSequenceID = seq; + ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[animations.Length]; + + for (int i = 0; i < animations.Length; ++i) + { + ani.AnimationList[i] = new AvatarAnimationPacket.AnimationListBlock(); + ani.AnimationList[i].AnimID = animations[i]; + ani.AnimationList[i].AnimSequenceID = seqs[i]; + } + OutPacket(ani, ThrottleOutPacketType.Task); } @@ -2485,6 +2491,13 @@ namespace OpenSim.Region.ClientStack OnStartAnim(this, AgentAni.AnimationList[i].AnimID, 1); } } + else + { + if (OnStopAnim != null) + { + OnStopAnim(this, AgentAni.AnimationList[i].AnimID); + } + } } break; case PacketType.AgentRequestSit: diff --git a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs index 4fdfc32797..07e5362e40 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.PacketHandlers.cs @@ -133,11 +133,6 @@ namespace OpenSim.Region.Environment.Scenes } } - public void StartAnimation(LLUUID animID, int seq, LLUUID agentId) - { - Broadcast(delegate(IClientAPI client) { client.SendAnimation(animID, seq, agentId); }); - } - public virtual void ProcessObjectGrab(uint localID, LLVector3 offsetPos, IClientAPI remoteClient) { EventManager.TriggerObjectGrab(localID, offsetPos, remoteClient); diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index e9d83a1f2f..01bcd83c03 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -950,7 +950,6 @@ namespace OpenSim.Region.Environment.Scenes protected virtual void SubscribeToClientEvents(IClientAPI client) { - // client.OnStartAnim += StartAnimation; client.OnRegionHandShakeReply += SendLayerData; //remoteClient.OnRequestWearables += new GenericCall(this.GetInitialPrims); client.OnModifyTerrain += ModifyTerrain; diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 21c0f3fecc..c277011d24 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -43,8 +43,8 @@ namespace OpenSim.Region.Environment.Scenes public static AvatarAnimations Animations; public static byte[] DefaultTexture; - public LLUUID CurrentAnimation; - public int AnimationSeq; + private List m_animations = new List(); + private List m_animationSeqs = new List(); private bool m_updateflag = false; private byte m_movementflag = 0; @@ -55,7 +55,6 @@ namespace OpenSim.Region.Environment.Scenes private float m_sitAvatarHeight = 2.0f; private float m_godlevel = 0; - private bool m_isTyping = false; private bool m_setAlwaysRun = false; private Quaternion m_bodyRot; @@ -74,7 +73,6 @@ namespace OpenSim.Region.Environment.Scenes private readonly Vector3[] Dir_Vectors = new Vector3[6]; private LLVector3 lastPhysPos = new LLVector3(); - // Position of agent's camera in world protected Vector3 m_CameraCenter = new Vector3(0, 0, 0); @@ -286,6 +284,9 @@ namespace OpenSim.Region.Environment.Scenes Animations = new AvatarAnimations(); Animations.LoadAnims(); + m_animations.Add(Animations.AnimsLLUUID["STAND"]); + m_animationSeqs.Add(1); + RegisterToEvents(); SetDirectionVectors(); @@ -303,7 +304,6 @@ namespace OpenSim.Region.Environment.Scenes m_scene.LandManager.sendLandUpdate(this); } - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) { //couldn't move the following into SetInitialValues as they are readonly @@ -319,6 +319,9 @@ namespace OpenSim.Region.Environment.Scenes Animations = new AvatarAnimations(); Animations.LoadAnims(); + m_animations.Add(Animations.AnimsLLUUID["STAND"]); + m_animationSeqs.Add(1); + RegisterToEvents(); SetDirectionVectors(); @@ -350,8 +353,9 @@ namespace OpenSim.Region.Environment.Scenes m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; m_controllingClient.OnAgentSit += HandleAgentSit; m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; + m_controllingClient.OnStartAnim += HandleStartAnim; + m_controllingClient.OnStopAnim += HandleStopAnim; - // ControllingClient.OnStartAnim += new StartAnim(this.SendAnimPack); // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); //ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); } @@ -786,7 +790,7 @@ namespace OpenSim.Region.Environment.Scenes Velocity = new LLVector3(0, 0, 0); RemoveFromPhysicalScene(); - SendAnimPack(Animations.AnimsLLUUID["SIT"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["SIT"], 1); SendFullUpdateToAllClients(); } @@ -799,6 +803,57 @@ namespace OpenSim.Region.Environment.Scenes } } + public void AddAnimation(LLUUID animID, int seq) + { + if (!m_animations.Contains(animID)) + { + m_animations.Add(animID); + m_animationSeqs.Add(seq); + SendAnimPack(); + } + } + + public void RemoveAnimation(LLUUID animID) + { + if (m_animations.Contains(animID)) + { + if (m_animations[0] == animID) + { + SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1); + } + else + { + m_animations.Remove(animID); + SendAnimPack(); + } + } + } + + public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID, int seq) + { + AddAnimation(animID, seq); + } + + public void HandleStopAnim(IClientAPI remoteClient, LLUUID animID) + { + RemoveAnimation(animID); + } + + /// + /// The movement animation is the first element of the animation list, + /// reserved for "main" animations that are mutually exclusive, + /// like flying and sitting, for example. + /// + protected void SetMovementAnimation(LLUUID anim, int seq) + { + if (m_animations[0] != anim) + { + m_animations[0] = anim; + m_animationSeqs[0] = seq; + SendAnimPack(); + } + } + protected void UpdateMovementAnimations(bool update_movementflag) { if (update_movementflag) @@ -807,81 +862,49 @@ namespace OpenSim.Region.Environment.Scenes { if (m_physicsActor.Flying) { - SendAnimPack(Animations.AnimsLLUUID["FLY"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["FLY"], 1); + } + else if (((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && + PhysicsActor.IsColliding) + { + SetMovementAnimation(Animations.AnimsLLUUID["CROUCHWALK"], 1); + } + else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) + { + SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"], 1); + } + else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) + { + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); + } + else if (m_setAlwaysRun) + { + SetMovementAnimation(Animations.AnimsLLUUID["RUN"], 1); } else - { - if (((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && - PhysicsActor.IsColliding) - { - SendAnimPack(Animations.AnimsLLUUID["CROUCHWALK"], 1); - } - else - { - if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) - { - SendAnimPack(Animations.AnimsLLUUID["FALLDOWN"], 1); - } - else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1); - } - else - { - if (!m_setAlwaysRun) - { - SendAnimPack(Animations.AnimsLLUUID["WALK"], 1); - } - else - { - SendAnimPack(Animations.AnimsLLUUID["RUN"], 1); - } - } - } - } - } - else if (m_parentID != 0) - { - if (m_isTyping) - { - SendAnimPack(Animations.AnimsLLUUID["TYPE"], 1); - } - else - { - // TODO: stop the typing animation, continue sitting - SendAnimPack(Animations.AnimsLLUUID["SIT"], 1); - } + SetMovementAnimation(Animations.AnimsLLUUID["WALK"], 1); } else { if (((m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && PhysicsActor.IsColliding) { - SendAnimPack(Animations.AnimsLLUUID["CROUCH"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["CROUCH"], 1); } - else if (m_isTyping) + else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) { - SendAnimPack(Animations.AnimsLLUUID["TYPE"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"], 1); + } + else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) + { + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); + } + else if (m_physicsActor.Flying) + { + SetMovementAnimation(Animations.AnimsLLUUID["FLY"], 1); } else - { - if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) - { - SendAnimPack(Animations.AnimsLLUUID["FALLDOWN"], 1); - } - else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying && (m_movementflag & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) - { - SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1); - } - else - { - if (!m_physicsActor.Flying) - { - SendAnimPack(Animations.AnimsLLUUID["STAND"], 1); - } - } - - } + SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1); } } } @@ -912,8 +935,8 @@ namespace OpenSim.Region.Environment.Scenes { direc.z *= 3; //System.Console.WriteLine("Jump"); - SendAnimPack(Animations.AnimsLLUUID["PREJUMP"], 1); - SendAnimPack(Animations.AnimsLLUUID["JUMP"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); } } } @@ -932,9 +955,10 @@ namespace OpenSim.Region.Environment.Scenes return; } - m_isTyping = typing; - - UpdateMovementAnimations(true); + if (typing) + AddAnimation(Animations.AnimsLLUUID["TYPE"], 1); + else + RemoveAnimation(Animations.AnimsLLUUID["TYPE"]); } #endregion @@ -1122,15 +1146,14 @@ namespace OpenSim.Region.Environment.Scenes /// /// /// - /// - /// - public void SendAnimPack(LLUUID animID, int seq) + /// + /// + public void SendAnimPack(LLUUID[] animations, int[] seqs) { - CurrentAnimation = animID; - AnimationSeq = seq; - LLUUID sourceAgentId = m_controllingClient.AgentId; - - m_scene.Broadcast(delegate(IClientAPI client) { client.SendAnimation(animID, seq, sourceAgentId); }); + m_scene.Broadcast(delegate(IClientAPI client) + { + client.SendAnimations(animations, seqs, m_controllingClient.AgentId); + }); } /// @@ -1138,7 +1161,7 @@ namespace OpenSim.Region.Environment.Scenes /// public void SendAnimPack() { - SendAnimPack(CurrentAnimation, AnimationSeq); + SendAnimPack(m_animations.ToArray(), m_animationSeqs.ToArray()); } #endregion diff --git a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs index 82272f896d..530b9332c8 100644 --- a/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleApp/MyNpcCharacter.cs @@ -58,6 +58,7 @@ namespace SimpleApp public event SetAppearance OnSetAppearance; public event AvatarNowWearing OnAvatarNowWearing; public event StartAnim OnStartAnim; + public event StopAnim OnStopAnim; public event LinkObjects OnLinkObjects; public event DelinkObjects OnDelinkObjects; public event RequestMapBlocks OnRequestMapBlocks; @@ -198,18 +199,20 @@ namespace SimpleApp public virtual void SendStartPingCheck(byte seq) { } + public virtual void SendAvatarPickerReply(AvatarPickerReplyPacket response) { - } public virtual void SendKillObject(ulong regionHandle, uint localID) { } + public virtual void SetChildAgentThrottle(byte[] throttle) { } - public virtual void SendAnimation(LLUUID animID, int seq, LLUUID sourceAgentId) + + public virtual void SendAnimations(LLUUID[] animations, int[] seqs, LLUUID sourceAgentId) { }