From dce5c470b682fc94a8f2d2fb4c0dc7c6f4d8b2eb Mon Sep 17 00:00:00 2001 From: Jeff Ames Date: Mon, 12 May 2008 17:00:47 +0000 Subject: Move animation handling from ScenePresence into its own class. --- OpenSim/Region/Environment/Scenes/Animation.cs | 59 ++++++ OpenSim/Region/Environment/Scenes/AnimationSet.cs | 151 ++++++++++++++++ OpenSim/Region/Environment/Scenes/ScenePresence.cs | 201 +++++---------------- 3 files changed, 259 insertions(+), 152 deletions(-) create mode 100644 OpenSim/Region/Environment/Scenes/Animation.cs create mode 100644 OpenSim/Region/Environment/Scenes/AnimationSet.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Environment/Scenes/Animation.cs b/OpenSim/Region/Environment/Scenes/Animation.cs new file mode 100644 index 0000000..b2fca90 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/Animation.cs @@ -0,0 +1,59 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using libsecondlife; + +namespace OpenSim.Region.Environment.Scenes +{ + public class Animation + { + private LLUUID animID; + public LLUUID AnimID + { + get { return animID; } + set { animID = value; } + } + + private int sequenceNum; + public int SequenceNum + { + get { return sequenceNum; } + set { sequenceNum = value; } + } + + public Animation() + { + } + + public Animation(LLUUID animID, int sequenceNum) + { + this.animID = animID; + this.sequenceNum = sequenceNum; + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/AnimationSet.cs b/OpenSim/Region/Environment/Scenes/AnimationSet.cs new file mode 100644 index 0000000..c485d30 --- /dev/null +++ b/OpenSim/Region/Environment/Scenes/AnimationSet.cs @@ -0,0 +1,151 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using libsecondlife; + +namespace OpenSim.Region.Environment.Scenes +{ + public class AnimationSet + { + public static AvatarAnimations Animations = new AvatarAnimations(); + + private Animation m_defaultAnimation = new Animation(); + private List m_animations = new List(); + + public AnimationSet() + { + ResetDefaultAnimation(); + } + + public bool HasAnimation(LLUUID animID) + { + if (m_defaultAnimation.AnimID == animID) + return true; + + for (int i = 0; i < m_animations.Count; ++i) + { + if (m_animations[i].AnimID == animID) + return true; + } + + return false; + } + + public bool Add(LLUUID animID, int sequenceNum) + { + lock (m_animations) + { + if (!HasAnimation(animID)) + { + m_animations.Add(new Animation(animID, sequenceNum)); + return true; + } + } + return false; + } + + public bool Remove(LLUUID animID) + { + lock (m_animations) + { + if (m_defaultAnimation.AnimID == animID) + { + ResetDefaultAnimation(); + } + else if (HasAnimation(animID)) + { + for (int i = 0; i < m_animations.Count; i++) + { + if (m_animations[i].AnimID == animID) + { + m_animations.RemoveAt(i); + return true; + } + } + } + } + return false; + } + + public void Clear() + { + ResetDefaultAnimation(); + m_animations.Clear(); + } + + /// + /// The default animation is reserved for "main" animations + /// that are mutually exclusive, e.g. flying and sitting. + /// + public bool SetDefaultAnimation(LLUUID animID, int sequenceNum) + { + if (m_defaultAnimation.AnimID != animID) + { + m_defaultAnimation = new Animation(animID, sequenceNum); + return true; + } + return false; + } + + protected bool ResetDefaultAnimation() + { + return TrySetDefaultAnimation("STAND", 1); + } + + /// + /// Set the animation as the default animation if it's known + /// + public bool TrySetDefaultAnimation(string anim, int sequenceNum) + { + if (Animations.AnimsLLUUID.ContainsKey(anim)) + { + return SetDefaultAnimation(Animations.AnimsLLUUID[anim], sequenceNum); + } + return false; + } + + public void GetArrays(out LLUUID[] animIDs, out int[] sequenceNums) + { + lock (m_animations) + { + animIDs = new LLUUID[m_animations.Count + 1]; + sequenceNums = new int[m_animations.Count + 1]; + + animIDs[0] = m_defaultAnimation.AnimID; + sequenceNums[0] = m_defaultAnimation.SequenceNum; + + for (int i = 0; i < m_animations.Count; ++i) + { + animIDs[i + 1] = m_animations[i].AnimID; + sequenceNums[i + 1] = m_animations[i].SequenceNum; + } + } + } + } +} diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index ef55bd2..5b10bfc 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -73,12 +73,10 @@ namespace OpenSim.Region.Environment.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public static AvatarAnimations Animations = new AvatarAnimations(); public static byte[] DefaultTexture; public LLUUID currentParcelUUID = LLUUID.Zero; - private List m_animations = new List(); - private List m_animationSeqs = new List(); + private AnimationSet m_animations = new AnimationSet(); private Dictionary scriptedcontrols = new Dictionary(); private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; @@ -608,15 +606,8 @@ namespace OpenSim.Region.Environment.Scenes /// public void MakeChildAgent() { - if (m_animations.Count > 0) - { - LLUUID movementAnim = m_animations[0]; - - m_animations.Clear(); - m_animationSeqs.Clear(); + m_animations.Clear(); - SetMovementAnimation(movementAnim); - } // m_log.DebugFormat( // "[SCENEPRESENCE]: Downgrading child agent {0}, {1} to a root agent in {2}", // Name, UUID, m_scene.RegionInfo.RegionName); @@ -1104,66 +1095,31 @@ namespace OpenSim.Region.Environment.Scenes if (m_isChildAgent) return; - // Don't let this animation become the movement animation - if (m_animations.Count < 1) - TrySetMovementAnimation("STAND"); - - if (!m_animations.Contains(animID)) + if (m_animations.Add(animID, m_controllingClient.NextAnimationSequenceNumber)) { - m_animations.Add(animID); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); SendAnimPack(); } } - public void RemoveAnimation(LLUUID animID) + public void AddAnimation(string name) { if (m_isChildAgent) return; - if (m_animations.Contains(animID)) - { - if (m_animations[0] == animID) - { - TrySetMovementAnimation("STAND"); - } - else - { - // What a HACK!! Anim list really needs to be an object! - int idx; - - for(idx=0;idx < m_animations.Count;idx++) - { - if (m_animations[idx] == animID) - { - int seq=m_animationSeqs[idx]; + LLUUID animID = m_controllingClient.GetDefaultAnimation(name); + if (animID == LLUUID.Zero) + return; - m_animations.Remove(animID); - m_animationSeqs.Remove(seq); - SendAnimPack(); - break; - } - } - } - } + AddAnimation(animID); } - public void AddAnimation(string name) + + public void RemoveAnimation(LLUUID animID) { if (m_isChildAgent) return; - // Don't let this animation become the movement animation - if (m_animations.Count < 1) - TrySetMovementAnimation("STAND"); - - LLUUID animID = m_controllingClient.GetDefaultAnimation(name); - if (animID == LLUUID.Zero) - return; - - if (!m_animations.Contains(animID)) + if (m_animations.Remove(animID)) { - m_animations.Add(animID); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); SendAnimPack(); } } @@ -1177,34 +1133,9 @@ namespace OpenSim.Region.Environment.Scenes if (animID == LLUUID.Zero) return; - if (m_animations.Contains(animID)) - { - if (m_animations[0] == animID) - { - TrySetMovementAnimation("STAND"); - } - else - { - // What a HACK!! Anim list really needs to be an object! - int idx; - - for(idx = 0; idx < m_animations.Count; idx++) - { - if (m_animations[idx] == animID) - { - int seq = m_animationSeqs[idx]; - - m_animations.Remove(animID); - m_animationSeqs.Remove(seq); - SendAnimPack(); - break; - } - } - } - } + RemoveAnimation(animID); } - public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID) { AddAnimation(animID); @@ -1216,88 +1147,63 @@ namespace OpenSim.Region.Environment.Scenes } /// - /// 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. + /// The movement animation is reserved for "main" animations + /// that are mutually exclusive, e.g. flying and sitting. /// protected void SetMovementAnimation(LLUUID animID) { - if (m_animations.Count < 1) + if (m_animations.SetDefaultAnimation(animID, m_controllingClient.NextAnimationSequenceNumber)) { - m_animations.Add(Animations.AnimsLLUUID["STAND"]); - m_animationSeqs.Add(1); SendAnimPack(); } - else - { - try - { - if (m_animations[0] != animID) - { - m_animations[0] = animID; - m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; - SendAnimPack(); - } - } - catch - { - m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery..."); - m_animations[0] = animID; - m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; - SendAnimPack(); - } - } } /// - /// Set the first known animation in the given list as the movement animation + /// The movement animation is reserved for "main" animations + /// that are mutually exclusive, e.g. flying and sitting. /// - protected void TrySetMovementAnimation(params string[] anims) + protected void TrySetMovementAnimation(string anim) { - foreach (string anim in anims) + if (m_animations.TrySetDefaultAnimation(anim, m_controllingClient.NextAnimationSequenceNumber)) { - if (Animations.AnimsLLUUID.ContainsKey(anim)) - { - SetMovementAnimation(Animations.AnimsLLUUID[anim]); - break; - } + SendAnimPack(); } } /// - /// This method handles agent movement related animations + /// This method determines the proper movement related animation /// - protected void UpdateMovementAnimations() + protected string GetMovementAnimation() { if (m_movementflag != 0) { // We are moving if (m_physicsActor.Flying) { - TrySetMovementAnimation("FLY"); + return "FLY"; } else if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && PhysicsActor.IsColliding) { - TrySetMovementAnimation("CROUCHWALK"); + return "CROUCHWALK"; } else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) { // Client is moving and falling at a velocity greater then 6 meters per unit - TrySetMovementAnimation("FALLDOWN"); + return "FALLDOWN"; } else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) { - TrySetMovementAnimation("JUMP"); + return "JUMP"; } else if (m_setAlwaysRun) { - TrySetMovementAnimation("RUN"); + return "RUN"; } else { - TrySetMovementAnimation("WALK"); + return "WALK"; } } else @@ -1307,29 +1213,34 @@ namespace OpenSim.Region.Environment.Scenes if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && PhysicsActor.IsColliding) { - TrySetMovementAnimation("CROUCH"); + return "CROUCH"; } else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) { - TrySetMovementAnimation("FALLDOWN"); + return "FALLDOWN"; } else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && !m_physicsActor.Flying && (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) { // This is the standing jump - TrySetMovementAnimation("JUMP"); + return "JUMP"; } else if (m_physicsActor.Flying) { - TrySetMovementAnimation("HOVER"); + return "HOVER"; } else { - TrySetMovementAnimation("STAND"); + return "STAND"; } } } + protected void UpdateMovementAnimations() + { + TrySetMovementAnimation(GetMovementAnimation()); + } + /// /// Adds a new movement /// @@ -1422,21 +1333,15 @@ namespace OpenSim.Region.Environment.Scenes } else if ((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02) || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)) // physics-related movement { - - // Send Terse Update to all clients updates lastPhysPos and m_lastVelocity // doing the above assures us that we know what we sent the clients last SendTerseUpdateToAllClients(); m_updateCount = 0; - - - } // followed suggestion from mic bowman. reversed the two lines below. CheckForBorderCrossing(); CheckForSignificantMovement(); // sends update to the modules. - } } @@ -1621,7 +1526,15 @@ namespace OpenSim.Region.Environment.Scenes /// public void SendAnimPack() { - SendAnimPack(m_animations.ToArray(), m_animationSeqs.ToArray()); + if (m_isChildAgent) + return; + + LLUUID[] animIDs; + int[] sequenceNums; + + m_animations.GetArrays(out animIDs, out sequenceNums); + + SendAnimPack(animIDs, sequenceNums); } #endregion @@ -2142,14 +2055,7 @@ namespace OpenSim.Region.Environment.Scenes DefaultTexture = textu.ToBytes(); } - List animations_work = (List)info.GetValue("m_animations", typeof(List)); - - foreach (Guid guid in animations_work) - { - m_animations.Add(new LLUUID(guid)); - } - - m_animationSeqs = (List)info.GetValue("m_animationSeqs", typeof(List)); + m_animations = (AnimationSet)info.GetValue("m_animations", typeof(AnimationSet)); m_updateflag = (bool)info.GetValue("m_updateflag", typeof(bool)); m_movementflag = (byte)info.GetValue("m_movementflag", typeof(byte)); m_forcesList = (List)info.GetValue("m_forcesList", typeof(List)); @@ -2304,16 +2210,7 @@ namespace OpenSim.Region.Environment.Scenes base.GetObjectData(info, context); - List animations_work = new List(); - - foreach (LLUUID uuid in m_animations) - { - animations_work.Add(uuid.UUID); - } - - info.AddValue("m_animations", animations_work); - - info.AddValue("m_animationSeqs", m_animationSeqs); + info.AddValue("m_animations", m_animations); info.AddValue("m_updateflag", m_updateflag); info.AddValue("m_movementflag", m_movementflag); info.AddValue("m_forcesList", m_forcesList); -- cgit v1.1