From bca7ab7e363e9c9874a9ab137b60a042b9d1139c Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Wed, 23 Apr 2008 11:52:25 +0000 Subject: [PATCH] * Applying Mantis #1020 (Animations) - Thanks Melanie. --- OpenSim/Framework/IClientAPI.cs | 4 +- OpenSim/Framework/TaskInventoryItem.cs | 48 +++++-- OpenSim/Region/ClientStack/ClientView.cs | 9 +- .../Environment/Scenes/Scene.Inventory.cs | 24 +--- .../Scenes/SceneObjectPart.Inventory.cs | 33 +++++ .../Environment/Scenes/ScenePresence.cs | 136 ++++++++++++------ .../Examples/SimpleModule/MyNpcCharacter.cs | 4 + .../Common/OSSL_BuilIn_Commands.cs | 2 +- 8 files changed, 178 insertions(+), 82 deletions(-) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index b8264ba72d..53c75b007c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -245,7 +245,7 @@ namespace OpenSim.Framework public delegate void SetAppearance(byte[] texture, AgentSetAppearancePacket.VisualParamBlock[] visualParam); - public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID, int seq); + public delegate void StartAnim(IClientAPI remoteClient, LLUUID animID); public delegate void StopAnim(IClientAPI remoteClient, LLUUID animID); @@ -572,6 +572,8 @@ namespace OpenSim.Framework string FirstName { get; } string LastName { get; } + + int NextAnimationSequenceNumber { get; } /// /// Returns the full name of the agent/avatar represented by this client diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index 1cf2e58e4a..5453eb3521 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -143,16 +143,26 @@ namespace OpenSim.Framework { "texture", "sound", + "calling_card", + "landmark", String.Empty, String.Empty, - String.Empty, - String.Empty, - String.Empty, - String.Empty, + "object", + "notecard", String.Empty, String.Empty, "lsl_text", - String.Empty + String.Empty, + String.Empty, + "bodypart", + String.Empty, + "snapshot", + String.Empty, + String.Empty, + "wearable", + "animation", + "gesture" + }; /// @@ -162,16 +172,26 @@ namespace OpenSim.Framework { "texture", "sound", - String.Empty, - String.Empty, - String.Empty, - String.Empty, - String.Empty, - String.Empty, - String.Empty, - String.Empty, + "callcard", + "landmark", + "clothing", // Deprecated + "clothing", + "object", + "notecard", + "category", + "root", "lsltext", - String.Empty + "lslbyte", + "txtr_tga", + "bodypart", + "trash", + "snapshot", + "lstndfnd", + "snd_wav", + "img_tga", + "jpeg", + "animatn", + "gesture" }; public LLUUID ItemID = LLUUID.Zero; diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 7ff1f23ff6..a58f88fedb 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -91,6 +91,8 @@ namespace OpenSim.Region.ClientStack private readonly uint m_circuitCode; private int m_moneyBalance; + private int m_animationSequenceNumber = 1; + private byte[] m_channelVersion = Helpers.StringToField("OpenSimulator 0.5"); // Dummy value needed by libSL /* protected variables */ @@ -302,6 +304,11 @@ namespace OpenSim.Region.ClientStack get { return m_moneyBalance; } } + public int NextAnimationSequenceNumber + { + get { return m_animationSequenceNumber++; } + } + /* METHODS */ public ClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, PacketServer packServer, @@ -3429,7 +3436,7 @@ namespace OpenSim.Region.ClientStack handlerStartAnim = OnStartAnim; if (handlerStartAnim != null) { - handlerStartAnim(this, AgentAni.AnimationList[i].AnimID, 1); + handlerStartAnim(this, AgentAni.AnimationList[i].AnimID); } } else diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index c5a1be1522..e4a955123e 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -730,25 +730,11 @@ namespace OpenSim.Region.Environment.Scenes if (item != null) { - if (item.AssetType == 0 || item.AssetType == 1 || item.AssetType == 10) - { - group.AddInventoryItem(remoteClient, primLocalID, item, copyID); - m_log.InfoFormat( - "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", - item.Name, primLocalID, remoteClient.Name); - group.GetProperties(remoteClient); - } - else - { - // XXX Nasty temporary way of stopping things other than sounds, textures and scripts - // from going in a prim's inventory, since other things will not currently work - // See http://opensimulator.org/mantis/view.php?id=711 for the error caused later on - // - to implement requires changes to TaskInventoryItem (which really requires the current - // nasty way it is done to be changed). - m_log.WarnFormat( - "[PRIM INVENTORY]: Sorry, prim inventory storage of asset type {0} is not yet supported", - item.AssetType); - } + group.AddInventoryItem(remoteClient, primLocalID, item, copyID); + m_log.InfoFormat( + "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", + item.Name, primLocalID, remoteClient.Name); + group.GetProperties(remoteClient); } else { diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs index 72f78f3c93..9b99df7ece 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs @@ -233,6 +233,33 @@ namespace OpenSim.Region.Environment.Scenes } } + // Assumes a lock is held on the inventory + private bool InventoryContainsName(string name) + { + foreach (TaskInventoryItem item in m_taskInventory.Values) + { + if(item.Name == name) + return true; + } + return false; + } + + private string FindAvailableInventoryName(string name) + { + if(!InventoryContainsName(name)) + return name; + + int suffix=1; + while(suffix < 256) + { + string tryName=String.Format("{0} {1}", name, suffix); + if(!InventoryContainsName(tryName)) + return tryName; + suffix++; + } + return String.Empty; + } + /// /// Add an item to this prim's inventory. /// @@ -243,6 +270,12 @@ namespace OpenSim.Region.Environment.Scenes item.CreationDate = 1000; item.ParentPartID = UUID; + string name=FindAvailableInventoryName(item.Name); + if(name == String.Empty) + return; + + item.Name=name; + lock (m_taskInventory) { m_taskInventory.Add(item.ItemID, item); diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index d85eea6631..3f70108253 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -359,17 +359,15 @@ namespace OpenSim.Region.Environment.Scenes AbsolutePosition = m_controllingClient.StartPos; - // TODO: m_animations and m_animationSeqs should always be of the same length. // Move them into an object to (hopefully) avoid threading issues. try { - m_animations.Add(Animations.AnimsLLUUID["STAND"]); + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); } catch (KeyNotFoundException) { m_log.Warn("[AVATAR]: KeyNotFound Exception playing avatar stand animation"); } - m_animationSeqs.Add(1); RegisterToEvents(); SetDirectionVectors(); @@ -549,6 +547,7 @@ namespace OpenSim.Region.Environment.Scenes AddToPhysicalScene(); m_physicsActor.Flying = isFlying; + SendAnimPack(); m_scene.SwapRootAgentCount(false); m_scene.CommsManager.UserProfileCacheService.RequestInventoryForUser(m_uuid); @@ -571,6 +570,15 @@ namespace OpenSim.Region.Environment.Scenes /// public void MakeChildAgent() { + if(m_animations.Count > 0) + { + LLUUID movement=m_animations[0]; + + m_animations.Clear(); + m_animationSeqs.Clear(); + + SetMovementAnimation(movement); + } // m_log.DebugFormat( // "[SCENEPRESENCE]: Downgrading child agent {0}, {1} to a root agent in {2}", // Name, UUID, m_scene.RegionInfo.RegionName); @@ -634,7 +642,7 @@ namespace OpenSim.Region.Environment.Scenes { AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (1.56f / 6)); } - SetMovementAnimation(Animations.AnimsLLUUID["LAND"], 2); + SetMovementAnimation(Animations.AnimsLLUUID["LAND"]); SendFullUpdateToAllClients(); } @@ -754,7 +762,7 @@ namespace OpenSim.Region.Environment.Scenes { // TODO: This doesn't quite work yet -- probably a parent ID problem // m_parentID = (what should this be?) - SetMovementAnimation(Animations.AnimsLLUUID["SIT_GROUND"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["SIT_GROUND"]); } // In the future, these values might need to go global. // Here's where you get them. @@ -891,7 +899,7 @@ namespace OpenSim.Region.Environment.Scenes } } - SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); } private void SendSitResponse(IClientAPI remoteClient, LLUUID targetID, LLVector3 offset) @@ -1025,7 +1033,7 @@ namespace OpenSim.Region.Environment.Scenes Velocity = new LLVector3(0, 0, 0); RemoveFromPhysicalScene(); - SetMovementAnimation(Animations.AnimsLLUUID["SIT"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["SIT"]); SendFullUpdateToAllClients(); // This may seem stupid, but Our Full updates don't send avatar rotation :P // So we're also sending a terse update (which has avatar rotation) @@ -1045,35 +1053,58 @@ namespace OpenSim.Region.Environment.Scenes } } - public void AddAnimation(LLUUID animID, int seq) + public void AddAnimation(LLUUID animID) { + if(m_isChildAgent) + return; + + // Don't let this animation become the movement animation + if(m_animations.Count < 1) + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); + if (!m_animations.Contains(animID)) { m_animations.Add(animID); - m_animationSeqs.Add(seq); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); SendAnimPack(); } } public void RemoveAnimation(LLUUID animID) { + if(m_isChildAgent) + return; + if (m_animations.Contains(animID)) { if (m_animations[0] == animID) { - SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); } else { - m_animations.Remove(animID); - SendAnimPack(); + // 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; + } + } } } } - public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID, int seq) + public void HandleStartAnim(IClientAPI remoteClient, LLUUID animID) { - AddAnimation(animID, seq); + AddAnimation(animID); } public void HandleStopAnim(IClientAPI remoteClient, LLUUID animID) @@ -1086,25 +1117,35 @@ namespace OpenSim.Region.Environment.Scenes /// reserved for "main" animations that are mutually exclusive, /// like flying and sitting, for example. /// - protected void SetMovementAnimation(LLUUID anim, int seq) + protected void SetMovementAnimation(LLUUID anim) { - try - { - if (m_animations[0] != anim) - { - m_animations[0] = anim; - m_animationSeqs[0] = seq; - SendAnimPack(); - } - } - catch - { - m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery..."); - m_animations[0] = anim; - m_animationSeqs[0] = seq; - SendAnimPack(); - } - } + if(m_animations.Count < 1) + { + m_animations.Add(Animations.AnimsLLUUID["STAND"]); + m_animationSeqs.Add(1); + + SendAnimPack(); + } + else + { + try + { + if (m_animations[0] != anim) + { + m_animations[0] = anim; + m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; + } + SendAnimPack(); + } + catch + { + m_log.Warn("[AVATAR]: SetMovementAnimation for avatar failed. Attempting recovery..."); + m_animations[0] = anim; + m_animationSeqs[0] = m_controllingClient.NextAnimationSequenceNumber; + SendAnimPack(); + } + } + } /// /// This method handles agent movement related animations @@ -1123,18 +1164,18 @@ namespace OpenSim.Region.Environment.Scenes if (m_physicsActor.Flying) { // We are flying - SetMovementAnimation(Animations.AnimsLLUUID["FLY"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["FLY"]); } else if (((m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) && PhysicsActor.IsColliding) { // Client is pressing the page down button and moving and is colliding with something - SetMovementAnimation(Animations.AnimsLLUUID["CROUCHWALK"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["CROUCHWALK"]); } else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6) { // Client is moving and falling at a velocity greater then 6 meters per unit - SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"]); } else if (!PhysicsActor.IsColliding && Velocity.Z > 0 && (m_movementflag & (uint) AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0) @@ -1142,7 +1183,7 @@ namespace OpenSim.Region.Environment.Scenes // Client is moving, and colliding and pressing the page up button but isn't flying try { - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); } catch (KeyNotFoundException) { } @@ -1152,7 +1193,7 @@ namespace OpenSim.Region.Environment.Scenes // We are running try { - SetMovementAnimation(Animations.AnimsLLUUID["RUN"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["RUN"]); } catch (KeyNotFoundException) { } @@ -1162,7 +1203,7 @@ namespace OpenSim.Region.Environment.Scenes // We're moving, but we're not doing anything else.. so play the stand animation try { - SetMovementAnimation(Animations.AnimsLLUUID["WALK"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["WALK"]); } catch (KeyNotFoundException) { } @@ -1177,23 +1218,23 @@ namespace OpenSim.Region.Environment.Scenes PhysicsActor.IsColliding) { // Client pressing the page down button - SetMovementAnimation(Animations.AnimsLLUUID["CROUCH"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["CROUCH"]); } else if (!PhysicsActor.IsColliding && m_physicsActor.Velocity.Z < -6 && !m_physicsActor.Flying) { // Not colliding and not flying, and we're falling at high speed - SetMovementAnimation(Animations.AnimsLLUUID["FALLDOWN"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["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 - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); } else if (m_physicsActor.Flying) { // We're flying but not moving - SetMovementAnimation(Animations.AnimsLLUUID["HOVER"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["HOVER"]); } else { @@ -1201,7 +1242,7 @@ namespace OpenSim.Region.Environment.Scenes try { - SetMovementAnimation(Animations.AnimsLLUUID["STAND"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["STAND"]); } catch (KeyNotFoundException) { } @@ -1257,8 +1298,8 @@ namespace OpenSim.Region.Environment.Scenes // PreJump and jump happen too quickly. Many times prejump gets ignored. try { - SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"], 1); - SetMovementAnimation(Animations.AnimsLLUUID["JUMP"], 1); + SetMovementAnimation(Animations.AnimsLLUUID["PREJUMP"]); + SetMovementAnimation(Animations.AnimsLLUUID["JUMP"]); } catch (KeyNotFoundException) { } @@ -1495,6 +1536,9 @@ namespace OpenSim.Region.Environment.Scenes /// public void SendAnimPack(LLUUID[] animations, int[] seqs) { + if(m_isChildAgent) + return; + m_scene.Broadcast( delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId); }); } @@ -1915,7 +1959,7 @@ namespace OpenSim.Region.Environment.Scenes m_animations = new List(); m_animations.Add(Animations.AnimsLLUUID["STAND"]); - m_animationSeqs.Add(1); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); SetDirectionVectors(); */ diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 4ce68dabb8..199653dba9 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -217,6 +217,10 @@ namespace OpenSim.Region.Examples.SimpleModule get { return FirstName + LastName; } } + public virtual int NextAnimationSequenceNumber + { + get { return 1; } + } public virtual void OutPacket(Packet newPack, ThrottleOutPacketType packType) { diff --git a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs index b919f8d2ab..e403a12395 100644 --- a/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/OSSL_BuilIn_Commands.cs @@ -434,7 +434,7 @@ namespace OpenSim.Region.ScriptEngine.Common if (World.Entities.ContainsKey(avatar) && World.Entities[avatar] is ScenePresence) { ScenePresence target = (ScenePresence)World.Entities[avatar]; - target.AddAnimation(avatar, 0); + target.AddAnimation(avatar); } }