From 8f9a726465c5bb7528d6ae7d74f20818d4ee3094 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 May 2013 19:27:20 +0100 Subject: If on a sit request we sit the avatar on a different prim in a linkset for some reason (e.g. because it has a sit target), then send the actual sit prim UUID to the viewer rather than the requested one. This purports to fix the issue described in http://opensimulator.org/mantis/view.php?id=6653 where the camera can end up following the requested sit prim rather than the actual. The original spot was by Vegaslon, this commit just goes about it in a slightly different way This commit also makes m_requestedSitTargetUUID to be the actual UUID, which is consistent with m_requestedSitTargetID which was already doing this. However, this adjustment has no practical effect since we only currently need to know that there's any requested sit UUID at all, not which one it is. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ab7fd5b..e8aa52e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2138,9 +2138,9 @@ namespace OpenSim.Region.Framework.Scenes forceMouselook = part.GetForceMouselook(); ControllingClient.SendSitResponse( - targetID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); + part.UUID, offset, sitOrientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook); - m_requestedSitTargetUUID = targetID; + m_requestedSitTargetUUID = part.UUID; HandleAgentSit(ControllingClient, UUID); @@ -2165,7 +2165,7 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { m_requestedSitTargetID = part.LocalId; - m_requestedSitTargetUUID = targetID; + m_requestedSitTargetUUID = part.UUID; // m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); -- cgit v1.1 From 439f11cc3cf2ab8f7fdc1d8746f1d8ab44c911eb Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 30 May 2013 09:21:58 -0700 Subject: Add region heartbeat start event to complement heartbeat end event. This allows object modification before the usual heartbeat operation. --- OpenSim/Region/Framework/Scenes/EventManager.cs | 23 +++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ 2 files changed, 25 insertions(+) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 59d0148..a246319 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -969,6 +969,8 @@ namespace OpenSim.Region.Framework.Scenes public delegate void RegionStarted(Scene scene); public event RegionStarted OnRegionStarted; + public delegate void RegionHeartbeatStart(Scene scene); + public event RegionHeartbeatStart OnRegionHeartbeatStart; public delegate void RegionHeartbeatEnd(Scene scene); public event RegionHeartbeatEnd OnRegionHeartbeatEnd; @@ -3068,6 +3070,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerRegionHeartbeatStart(Scene scene) + { + RegionHeartbeatStart handler = OnRegionHeartbeatStart; + + if (handler != null) + { + foreach (RegionHeartbeatStart d in handler.GetInvocationList()) + { + try + { + d(scene); + } + catch (Exception e) + { + m_log.ErrorFormat("[EVENT MANAGER]: Delegate for OnRegionHeartbeatStart failed - continuing {0} - {1}", + e.Message, e.StackTrace); + } + } + } + } + public void TriggerRegionHeartbeatEnd(Scene scene) { RegionHeartbeatEnd handler = OnRegionHeartbeatEnd; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5dea634..0743ce7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1517,6 +1517,8 @@ namespace OpenSim.Region.Framework.Scenes try { + EventManager.TriggerRegionHeartbeatStart(this); + // Apply taints in terrain module to terrain in physics scene if (Frame % m_update_terrain == 0) { -- cgit v1.1 From 48a175eff760e04f8096acd404058755d7c2919c Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 30 May 2013 14:30:45 -0700 Subject: Add methods to Animation and AnimationSet for easier manipulation and display of groups of animations (Equal(), ToString(), FromOSDArray(), ...). No functional change to animations. --- .../Framework/Scenes/Animation/AnimationSet.cs | 110 +++++++++++++++++++++ .../Scenes/Animation/DefaultAvatarAnimations.cs | 26 +++++ 2 files changed, 136 insertions(+) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs index 66edfed..5dee64d 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs @@ -28,8 +28,11 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Text; using log4net; using OpenMetaverse; +using OpenMetaverse.StructuredData; + using OpenSim.Framework; using Animation = OpenSim.Framework.Animation; @@ -60,6 +63,12 @@ namespace OpenSim.Region.Framework.Scenes.Animation ResetDefaultAnimation(); } + public AnimationSet(OSDArray pArray) + { + ResetDefaultAnimation(); + FromOSDArray(pArray); + } + public bool HasAnimation(UUID animID) { if (m_defaultAnimation.AnimID == animID) @@ -218,5 +227,106 @@ namespace OpenSim.Region.Framework.Scenes.Animation foreach (OpenSim.Framework.Animation anim in theArray) m_animations.Add(anim); } + + // Create representation of this AnimationSet as an OSDArray. + // First two entries in the array are the default and implicitDefault animations + // followed by the other animations. + public OSDArray ToOSDArray() + { + OSDArray ret = new OSDArray(); + ret.Add(DefaultAnimation.PackUpdateMessage()); + ret.Add(ImplicitDefaultAnimation.PackUpdateMessage()); + + foreach (OpenSim.Framework.Animation anim in m_animations) + ret.Add(anim.PackUpdateMessage()); + + return ret; + } + + public void FromOSDArray(OSDArray pArray) + { + this.Clear(); + + if (pArray.Count >= 1) + { + m_defaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[0]); + } + if (pArray.Count >= 2) + { + m_implicitDefaultAnimation = new OpenSim.Framework.Animation((OSDMap)pArray[1]); + } + for (int ii = 2; ii < pArray.Count; ii++) + { + m_animations.Add(new OpenSim.Framework.Animation((OSDMap)pArray[ii])); + } + } + + // Compare two AnimationSets and return 'true' if the default animations are the same + // and all of the animations in the list are equal. + public override bool Equals(object obj) + { + AnimationSet other = obj as AnimationSet; + if (other != null) + { + if (this.DefaultAnimation.Equals(other.DefaultAnimation) + && this.ImplicitDefaultAnimation.Equals(other.ImplicitDefaultAnimation)) + { + // The defaults are the same. Is the list of animations the same? + OpenSim.Framework.Animation[] thisAnims = this.ToArray(); + OpenSim.Framework.Animation[] otherAnims = other.ToArray(); + if (thisAnims.Length == 0 && otherAnims.Length == 0) + return true; // the common case + if (thisAnims.Length == otherAnims.Length) + { + // Do this the hard way but since the list is usually short this won't take long. + foreach (OpenSim.Framework.Animation thisAnim in thisAnims) + { + bool found = false; + foreach (OpenSim.Framework.Animation otherAnim in otherAnims) + { + if (thisAnim.Equals(otherAnim)) + { + found = true; + break; + } + } + if (!found) + { + // If anything is not in the other list, these are not equal + return false; + } + } + // Found everything in the other list. Since lists are equal length, they must be equal. + return true; + } + } + return false; + } + // Don't know what was passed, but the base system will figure it out for me. + return base.Equals(obj); + } + + public override string ToString() + { + StringBuilder buff = new StringBuilder(); + buff.Append("dflt="); + buff.Append(DefaultAnimation.ToString()); + buff.Append(",iDflt="); + if (DefaultAnimation == ImplicitDefaultAnimation) + buff.Append("same"); + else + buff.Append(ImplicitDefaultAnimation.ToString()); + if (m_animations.Count > 0) + { + buff.Append(",anims="); + foreach (OpenSim.Framework.Animation anim in m_animations) + { + buff.Append("<"); + buff.Append(anim.ToString()); + buff.Append(">,"); + } + } + return buff.ToString(); + } } } diff --git a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs index c2b0468..b79dd8f 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/DefaultAvatarAnimations.cs @@ -104,5 +104,31 @@ namespace OpenSim.Region.Framework.Scenes.Animation return UUID.Zero; } + + /// + /// Get the name of the animation given a UUID. If there is no matching animation + /// return the UUID as a string. + /// + public static string GetDefaultAnimationName(UUID uuid) + { + string ret = "unknown"; + if (AnimsUUID.ContainsValue(uuid)) + { + foreach (KeyValuePair kvp in AnimsUUID) + { + if (kvp.Value == uuid) + { + ret = kvp.Key; + break; + } + } + } + else + { + ret = uuid.ToString(); + } + + return ret; + } } } \ No newline at end of file -- cgit v1.1 From 4d32ca19bf27048105aeb01c67f0f9647ed3e700 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Thu, 30 May 2013 19:15:14 -0700 Subject: Trigger OnScenePresenceUpdated when the avatar's animations change. --- .../Framework/Scenes/Animation/ScenePresenceAnimator.cs | 17 ++++++++++++++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 +++++++- 2 files changed, 21 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/Framework') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index e92a087..a701a79 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -92,7 +92,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID)) + { SendAnimPack(); + } } // Called from scripts @@ -131,7 +133,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation GetAnimName(animID), animID, m_scenePresence.Name); if (m_animations.Remove(animID, allowNoDefault)) + { SendAnimPack(); + } } // Called from scripts @@ -163,8 +167,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// The movement animation is reserved for "main" animations /// that are mutually exclusive, e.g. flying and sitting. /// - public void TrySetMovementAnimation(string anim) + /// 'true' if the animation was updated + public bool TrySetMovementAnimation(string anim) { + bool ret = false; if (!m_scenePresence.IsChildAgent) { // m_log.DebugFormat( @@ -181,6 +187,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation // 16384 is CHANGED_ANIMATION m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); SendAnimPack(); + ret = true; } } else @@ -189,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation "[SCENE PRESENCE ANIMATOR]: Tried to set movement animation {0} on child presence {1}", anim, m_scenePresence.Name); } + return ret; } /// @@ -422,8 +430,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// /// Update the movement animation of this avatar according to its current state /// - public void UpdateMovementAnimations() + /// 'true' if the animation was changed + public bool UpdateMovementAnimations() { + bool ret = false; lock (m_animations) { string newMovementAnimation = DetermineMovementAnimation(); @@ -437,9 +447,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation // Only set it if it's actually changed, give a script // a chance to stop a default animation - TrySetMovementAnimation(CurrentMovementAnimation); + ret = TrySetMovementAnimation(CurrentMovementAnimation); } } + return ret; } public UUID[] GetAnimationArray() diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e8aa52e..b8ff7f7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2039,6 +2039,7 @@ namespace OpenSim.Region.Framework.Scenes } Animator.TrySetMovementAnimation("STAND"); + TriggerScenePresenceUpdated(); } private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) @@ -2432,6 +2433,7 @@ namespace OpenSim.Region.Framework.Scenes } Animator.TrySetMovementAnimation(sitAnimation); SendAvatarDataToAllAgents(); + TriggerScenePresenceUpdated(); } } @@ -2440,6 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes // m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.. m_AngularVelocity = Vector3.Zero; Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + TriggerScenePresenceUpdated(); SitGround = true; RemoveFromPhysicalScene(); } @@ -2456,11 +2459,13 @@ namespace OpenSim.Region.Framework.Scenes public void HandleStartAnim(IClientAPI remoteClient, UUID animID) { Animator.AddAnimation(animID, UUID.Zero); + TriggerScenePresenceUpdated(); } public void HandleStopAnim(IClientAPI remoteClient, UUID animID) { Animator.RemoveAnimation(animID, false); + TriggerScenePresenceUpdated(); } /// @@ -3465,7 +3470,8 @@ namespace OpenSim.Region.Framework.Scenes // if (m_updateCount > 0) // { - Animator.UpdateMovementAnimations(); + if (Animator.UpdateMovementAnimations()) + TriggerScenePresenceUpdated(); // m_updateCount--; // } -- cgit v1.1