From b1d0fab954545e1ed9aa13c0c760b3371042c437 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Sun, 26 Aug 2012 20:33:45 +0100 Subject: fix incoerence btw KFM_TRANSLATION and ROTATION LSL constants and internal DataFormat enum, using values from the KFM constants --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index b7b0d27..6ee09b7 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -38,8 +38,8 @@ namespace OpenSim.Region.Framework.Scenes [Flags] public enum DataFormat : int { - Translation = 1, - Rotation = 2 + Translation = 2, + Rotation = 1 } [Serializable] -- cgit v1.1 From ef6e007a4c7301dbd7a1a0392a07664e7034201b Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 28 Aug 2012 03:21:03 +0100 Subject: [possible still very broken] mess around keyframes. timer events threads overlaps, some null objects exceptions, region crossing... --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 368 +++++++++++++++------ OpenSim/Region/Framework/Scenes/Scene.cs | 6 + .../Region/Framework/Scenes/SceneObjectGroup.cs | 29 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 +- .../Scenes/Serialization/SceneObjectSerializer.cs | 2 +- 5 files changed, 299 insertions(+), 111 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 6ee09b7..4e6425f 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -58,12 +58,31 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_serializedPosition; private Keyframe m_currentFrame; + private List m_frames = new List(); private Keyframe[] m_keyframes; [NonSerialized()] - protected Timer m_timer = new Timer(); + protected Timer m_timer = null; + + // timer lock + [NonSerialized()] + private object m_onTimerLock; + + // timer overrun detect + // prevents overlap or timer events threads frozen on the lock + [NonSerialized()] + private bool m_inOnTimer; + + // skip timer events. + //timer.stop doesn't assure there aren't event threads still being fired + [NonSerialized()] + private bool m_skipOnTimer; + + // retry position for cross fail + [NonSerialized()] + private Vector3 m_nextPosition; [NonSerialized()] private SceneObjectGroup m_group; @@ -88,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes { set { - if (value) + if (!value) { // Once we're let go, recompute positions if (m_selected) @@ -100,7 +119,8 @@ namespace OpenSim.Region.Framework.Scenes if (!m_selected) m_serializedPosition = m_group.AbsolutePosition; } - m_selected = value; } + m_selected = value; + } } public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) @@ -111,31 +131,65 @@ namespace OpenSim.Region.Framework.Scenes KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms); +/* + * create timer in start() + * this was creating unneeded timers + // This will be started when position is updated + newMotion.m_timer = new Timer(); newMotion.m_timer.Interval = (int)timerInterval; newMotion.m_timer.AutoReset = true; newMotion.m_timer.Elapsed += newMotion.OnTimer; +*/ + newMotion.m_group = grp; + if (grp != null && grp.IsSelected) + newMotion.m_selected = true; + + newMotion.m_onTimerLock = new object(); + newMotion.m_skipOnTimer = false; + newMotion.m_inOnTimer = false; return newMotion; } public void UpdateSceneObject(SceneObjectGroup grp) { - m_group = grp; - Vector3 offset = grp.AbsolutePosition - m_serializedPosition; - - m_basePosition += offset; - m_currentFrame.Position += offset; - for (int i = 0 ; i < m_frames.Count ; i++) +// lock (m_onTimerLock) { - Keyframe k = m_frames[i]; - k.Position += offset; - m_frames[i] = k; - } + m_skipOnTimer = true; + if (m_timer != null) + m_timer.Stop(); + + m_group = grp; + Vector3 grppos = grp.AbsolutePosition; + Vector3 offset = grppos - m_serializedPosition; + // avoid doing it more than once + // current this will happen draging a prim to other region + m_serializedPosition = grppos; + + m_basePosition += offset; + m_currentFrame.Position += offset; + + m_nextPosition += offset; +/* + for (int i = 0; i < m_frames.Count; i++) + { + Keyframe k = m_frames[i]; + k.Position += offset; + m_frames[i] = k; + } +*/ + for (int i = 0; i < m_frames.Count; i++) + { + Keyframe k = m_frames[i]; + k.Position += offset; + m_frames[i]=k; + } - if (m_running) - Start(); + if (m_running) + Start(); + } } public KeyframeMotion(SceneObjectGroup grp, PlayMode mode, DataFormat data) @@ -143,13 +197,16 @@ namespace OpenSim.Region.Framework.Scenes m_mode = mode; m_data = data; + m_onTimerLock = new object(); + m_group = grp; m_basePosition = grp.AbsolutePosition; m_baseRotation = grp.GroupRotation; - +/* m_timer.Interval = (int)timerInterval; m_timer.AutoReset = true; m_timer.Elapsed += OnTimer; + */ } public void SetKeyframes(Keyframe[] frames) @@ -157,19 +214,63 @@ namespace OpenSim.Region.Framework.Scenes m_keyframes = frames; } + public void Delete() + { + m_skipOnTimer = true; + m_frames.Clear(); + m_keyframes = null; + m_running = false; + + if (m_timer == null) + return; + + m_timer.Stop(); + m_timer.Elapsed -= OnTimer; + m_timer = null; + } + public void Start() { if (m_keyframes.Length > 0) + { + if (m_timer == null) + { + m_timer = new Timer(); + m_timer.Interval = (int)timerInterval; + m_timer.AutoReset = true; + m_timer.Elapsed += OnTimer; + } + + m_skipOnTimer = false; + m_inOnTimer = false; + m_timer.Start(); - m_running = true; + m_running = true; + } + else + { + m_running = false; + m_skipOnTimer = true; + if (m_timer != null) + { + m_timer.Stop(); + m_timer.Elapsed -= OnTimer; + m_timer = null; + } + } } public void Stop() { + m_skipOnTimer = true; + // Failed object creation if (m_timer == null) return; + m_timer.Stop(); + m_timer.Elapsed -= OnTimer; + m_timer = null; m_basePosition = m_group.AbsolutePosition; m_baseRotation = m_group.GroupRotation; @@ -184,6 +285,8 @@ namespace OpenSim.Region.Framework.Scenes public void Pause() { + m_skipOnTimer = true; + m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); m_group.SendGroupRootTerseUpdate(); @@ -284,138 +387,197 @@ namespace OpenSim.Region.Framework.Scenes protected void OnTimer(object sender, ElapsedEventArgs e) { - if (m_frames.Count == 0) - { - GetNextList(); - - if (m_frames.Count == 0) - { - Stop(); - return; - } - - m_currentFrame = m_frames[0]; - } - - if (m_selected) + if (m_inOnTimer) { - if (m_group.RootPart.Velocity != Vector3.Zero) - { - m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); - } + m_log.Error("[KeyFrame]: timer overrun"); return; } - // Do the frame processing - double steps = (double)m_currentFrame.TimeMS / timerInterval; - float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; - - if (steps <= 1.0) +// lock (m_onTimerLock) { - m_currentFrame.TimeMS = 0; - - m_group.AbsolutePosition = (Vector3)m_currentFrame.Position; - m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); - } - else - { - Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; - Vector3 motionThisFrame = v / (float)steps; - v = v * 1000 / m_currentFrame.TimeMS; - - bool update = false; + if (m_skipOnTimer) + return; - if (Vector3.Mag(motionThisFrame) >= 0.05f) + m_inOnTimer = true; + try { - m_group.AbsolutePosition += motionThisFrame; - m_group.RootPart.Velocity = v; - update = true; - } + if (m_frames.Count == 0) + { + GetNextList(); - if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) - { - Quaternion current = m_group.GroupRotation; + if (m_frames.Count == 0) + { + Stop(); + m_inOnTimer = false; + return; + } - Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); + m_currentFrame = m_frames[0]; + } - float angle = 0; + if (m_selected) + { + if (m_group.RootPart.Velocity != Vector3.Zero) + { + m_group.RootPart.Velocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + } + m_inOnTimer = false; + return; + } - float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; - float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; - float aa_bb = aa * bb; + // Do the frame processing + double steps = (double)m_currentFrame.TimeMS / timerInterval; + float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; - if (aa_bb == 0) + if (steps <= 1.0) { - angle = 0; + m_currentFrame.TimeMS = 0; + + // m_group.AbsolutePosition = (Vector3)m_currentFrame.Position; + m_nextPosition = (Vector3)m_currentFrame.Position; + m_group.AbsolutePosition = m_nextPosition; + + m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); } else { - float ab = current.X * step.X + - current.Y * step.Y + - current.Z * step.Z + - current.W * step.W; - float q = (ab * ab) / aa_bb; + Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; + Vector3 motionThisFrame = v / (float)steps; + v = v * 1000 / m_currentFrame.TimeMS; - if (q > 1.0f) + bool update = false; + + if (Vector3.Mag(motionThisFrame) >= 0.05f) { - angle = 0; + // m_group.AbsolutePosition += motionThisFrame; + m_nextPosition = m_group.AbsolutePosition + motionThisFrame; + m_group.AbsolutePosition = m_nextPosition; + + m_group.RootPart.Velocity = v; + update = true; } - else + + if ((Quaternion)m_currentFrame.Rotation != m_group.GroupRotation) { - angle = (float)Math.Acos(2 * q - 1); + Quaternion current = m_group.GroupRotation; + + Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); + + float angle = 0; + + float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; + float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; + float aa_bb = aa * bb; + + if (aa_bb == 0) + { + angle = 0; + } + else + { + float ab = current.X * step.X + + current.Y * step.Y + + current.Z * step.Z + + current.W * step.W; + float q = (ab * ab) / aa_bb; + + if (q > 1.0f) + { + angle = 0; + } + else + { + angle = (float)Math.Acos(2 * q - 1); + } + } + + if (angle > 0.01f) + { + m_group.UpdateGroupRotationR(step); + //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); + update = true; + } } + + if (update) + m_group.SendGroupRootTerseUpdate(); } - if (angle > 0.01f) + m_currentFrame.TimeMS -= (int)timerInterval; + + if (m_currentFrame.TimeMS <= 0) { - m_group.UpdateGroupRotationR(step); - //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); - update = true; + m_group.RootPart.Velocity = Vector3.Zero; + m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); + m_group.SendGroupRootTerseUpdate(); + + m_frames.RemoveAt(0); + if (m_frames.Count > 0) + m_currentFrame = m_frames[0]; } } - - if (update) - m_group.SendGroupRootTerseUpdate(); + finally + { + m_inOnTimer = false; + } } + } - m_currentFrame.TimeMS -= (int)timerInterval; - - if (m_currentFrame.TimeMS <= 0) + public Byte[] Serialize(bool StopMoveTimer) + { + MemoryStream ms = new MemoryStream(); + if (StopMoveTimer && m_timer != null) { - m_group.RootPart.Velocity = Vector3.Zero; - m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); - m_group.SendGroupRootTerseUpdate(); + m_skipOnTimer = true; + m_timer.Stop(); + } - m_frames.RemoveAt(0); - if (m_frames.Count > 0) - m_currentFrame = m_frames[0]; +// lock (m_onTimerLock) + { + BinaryFormatter fmt = new BinaryFormatter(); + SceneObjectGroup tmp = m_group; + m_group = null; + if(!m_selected) + m_serializedPosition = tmp.AbsolutePosition; + fmt.Serialize(ms, this); + m_group = tmp; + return ms.ToArray(); } } - public Byte[] Serialize() + public void StartCrossingCheck() { - MemoryStream ms = new MemoryStream(); - m_timer.Stop(); + m_skipOnTimer = true; + if (m_timer != null) + m_timer.Stop(); - BinaryFormatter fmt = new BinaryFormatter(); - SceneObjectGroup tmp = m_group; - m_group = null; - m_serializedPosition = tmp.AbsolutePosition; - fmt.Serialize(ms, this); - m_group = tmp; - return ms.ToArray(); + if (m_group.RootPart.Velocity != Vector3.Zero) + { + m_group.RootPart.Velocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + } } public void CrossingFailure() { // The serialization has stopped the timer, so let's wait a moment // then retry the crossing. We'll get back here if it fails. + // if it is a open border there is no serialization + // so make sure timer is actually stopped + + m_group.RootPart.Velocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + Util.FireAndForget(delegate (object x) { Thread.Sleep(60000); if (m_running) + { + m_skipOnTimer = false; m_timer.Start(); + m_group.AbsolutePosition = m_nextPosition; + } }); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 57fcf51..0237021 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2346,6 +2346,12 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in partList) { + if (part.KeyframeMotion != null) + { + part.KeyframeMotion.Delete(); + part.KeyframeMotion = null; + } + if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) { PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index eee53d7..65a1da2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -509,6 +509,9 @@ namespace OpenSim.Region.Framework.Scenes Vector3 newpos = Vector3.Zero; OpenSim.Services.Interfaces.GridRegion destination = null; + if (m_rootPart.KeyframeMotion != null) + m_rootPart.KeyframeMotion.StartCrossingCheck(); + bool canCross = true; foreach (ScenePresence av in m_linkedAvatars) { @@ -551,7 +554,7 @@ namespace OpenSim.Region.Framework.Scenes av.ParentID = 0; } -// m_linkedAvatars.Clear(); + // m_linkedAvatars.Clear(); m_scene.CrossPrimGroupIntoNewRegion(val, this, true); // Normalize @@ -599,11 +602,16 @@ namespace OpenSim.Region.Framework.Scenes avsToCross.Clear(); } - else if (RootPart.PhysActor != null) + else { - RootPart.PhysActor.CrossingFailure(); - } + if (m_rootPart.KeyframeMotion != null) + m_rootPart.KeyframeMotion.CrossingFailure(); + if (RootPart.PhysActor != null) + { + RootPart.PhysActor.CrossingFailure(); + } + } Vector3 oldp = AbsolutePosition; val.X = Util.Clamp(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f); val.Y = Util.Clamp(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f); @@ -2058,8 +2066,8 @@ namespace OpenSim.Region.Framework.Scenes { if (part.KeyframeMotion != null) { - part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize()); - part.KeyframeMotion.UpdateSceneObject(this); + part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize(false)); +// part.KeyframeMotion.UpdateSceneObject(this); } }); @@ -4407,6 +4415,15 @@ namespace OpenSim.Region.Framework.Scenes public virtual ISceneObject CloneForNewScene() { SceneObjectGroup sog = Copy(false); + sog.ForEachPart(delegate(SceneObjectPart part) + { + if (part.KeyframeMotion != null) + { + part.KeyframeMotion = KeyframeMotion.FromData(sog, part.KeyframeMotion.Serialize(true)); + // this is called later +// part.KeyframeMotion.UpdateSceneObject(this); + } + }); sog.IsDeleted = false; return sog; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ed626d0..bf5fc99 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -769,7 +769,7 @@ namespace OpenSim.Region.Framework.Scenes { m_groupPosition = value; PhysicsActor actor = PhysActor; - if (actor != null) + if (actor != null && ParentGroup.Scene.PhysicsScene != null) { try { @@ -3408,6 +3408,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendTerseUpdateToAllClients() { + if (ParentGroup == null || ParentGroup.Scene == null) + return; + ParentGroup.Scene.ForEachClient(delegate(IClientAPI client) { SendTerseUpdateToClient(client); diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 134bd9d..1c75607 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1241,7 +1241,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (sog.RootPart.KeyframeMotion != null) { - Byte[] data = sog.RootPart.KeyframeMotion.Serialize(); + Byte[] data = sog.RootPart.KeyframeMotion.Serialize(true); writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); writer.WriteBase64(data, 0, data.Length); -- cgit v1.1 From 5284e514d5e71e6f1637bff133db6de73e6ff7ef Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 28 Aug 2012 22:16:01 +0200 Subject: Fix a nullref while object is being created --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index eee53d7..da312f3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3025,7 +3025,8 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void DetachFromBackup() { - m_scene.SceneGraph.FireDetachFromBackup(this); + if (m_scene != null) + m_scene.SceneGraph.FireDetachFromBackup(this); if (m_isBackedUp && Scene != null) m_scene.EventManager.OnBackup -= ProcessBackup; -- cgit v1.1 From 72ac0665b207f7f840b861086b3a620a9942775f Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Aug 2012 00:35:06 +0100 Subject: [Potentially broken] keyframes changes.. since it's there, use timer for crossing retries and not still another thread, etc... --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 280 +++++++++++++--------- 1 file changed, 165 insertions(+), 115 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 4e6425f..5333177 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -53,9 +53,9 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 AngularVelocity; }; + private Vector3 m_serializedPosition; private Vector3 m_basePosition; private Quaternion m_baseRotation; - private Vector3 m_serializedPosition; private Keyframe m_currentFrame; @@ -78,7 +78,13 @@ namespace OpenSim.Region.Framework.Scenes // skip timer events. //timer.stop doesn't assure there aren't event threads still being fired [NonSerialized()] - private bool m_skipOnTimer; + private bool m_timerStopped; + + [NonSerialized()] + private bool m_crossing; + + [NonSerialized()] + private int m_crossFailcntr; // retry position for cross fail [NonSerialized()] @@ -107,6 +113,8 @@ namespace OpenSim.Region.Framework.Scenes { set { + m_crossing = false; + m_crossFailcntr = 0; if (!value) { // Once we're let go, recompute positions @@ -117,39 +125,58 @@ namespace OpenSim.Region.Framework.Scenes { // Save selection position in case we get moved if (!m_selected) + { + StopTimer(); m_serializedPosition = m_group.AbsolutePosition; + } } m_selected = value; } } - public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) + private void StartTimer() + { + if (m_timer == null) + return; + m_timerStopped = false; + m_timer.Start(); + } + + private void StopTimer() { - MemoryStream ms = new MemoryStream(data); + if (m_timer == null || m_timerStopped) + return; + m_timerStopped = true; + m_timer.Stop(); + } - BinaryFormatter fmt = new BinaryFormatter(); + public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) + { + KeyframeMotion newMotion = null; - KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms); + try + { + MemoryStream ms = new MemoryStream(data); + BinaryFormatter fmt = new BinaryFormatter(); -/* - * create timer in start() - * this was creating unneeded timers + newMotion = (KeyframeMotion)fmt.Deserialize(ms); - // This will be started when position is updated + newMotion.m_group = grp; - newMotion.m_timer = new Timer(); - newMotion.m_timer.Interval = (int)timerInterval; - newMotion.m_timer.AutoReset = true; - newMotion.m_timer.Elapsed += newMotion.OnTimer; -*/ - newMotion.m_group = grp; + if (grp != null && grp.IsSelected) + newMotion.m_selected = true; - if (grp != null && grp.IsSelected) - newMotion.m_selected = true; + newMotion.m_onTimerLock = new object(); + newMotion.m_timerStopped = false; + newMotion.m_inOnTimer = false; + newMotion.m_crossing = false; + newMotion.m_crossFailcntr = 0; + } + catch + { + newMotion = null; + } - newMotion.m_onTimerLock = new object(); - newMotion.m_skipOnTimer = false; - newMotion.m_inOnTimer = false; return newMotion; } @@ -157,9 +184,9 @@ namespace OpenSim.Region.Framework.Scenes { // lock (m_onTimerLock) { - m_skipOnTimer = true; - if (m_timer != null) - m_timer.Stop(); + m_crossing = false; + m_crossFailcntr = 0; + StopTimer(); m_group = grp; Vector3 grppos = grp.AbsolutePosition; @@ -172,14 +199,7 @@ namespace OpenSim.Region.Framework.Scenes m_currentFrame.Position += offset; m_nextPosition += offset; -/* - for (int i = 0; i < m_frames.Count; i++) - { - Keyframe k = m_frames[i]; - k.Position += offset; - m_frames[i] = k; - } -*/ + for (int i = 0; i < m_frames.Count; i++) { Keyframe k = m_frames[i]; @@ -202,11 +222,8 @@ namespace OpenSim.Region.Framework.Scenes m_group = grp; m_basePosition = grp.AbsolutePosition; m_baseRotation = grp.GroupRotation; -/* - m_timer.Interval = (int)timerInterval; - m_timer.AutoReset = true; - m_timer.Elapsed += OnTimer; - */ + m_crossing = false; + m_crossFailcntr = 0; } public void SetKeyframes(Keyframe[] frames) @@ -216,21 +233,23 @@ namespace OpenSim.Region.Framework.Scenes public void Delete() { - m_skipOnTimer = true; + m_running = false; + m_crossing = false; + m_crossFailcntr = 0; + StopTimer(); m_frames.Clear(); m_keyframes = null; - m_running = false; if (m_timer == null) return; - - m_timer.Stop(); m_timer.Elapsed -= OnTimer; m_timer = null; } public void Start() { + m_crossing = false; + m_crossFailcntr = 0; if (m_keyframes.Length > 0) { if (m_timer == null) @@ -241,19 +260,16 @@ namespace OpenSim.Region.Framework.Scenes m_timer.Elapsed += OnTimer; } - m_skipOnTimer = false; m_inOnTimer = false; - - m_timer.Start(); + StartTimer(); m_running = true; } else { m_running = false; - m_skipOnTimer = true; if (m_timer != null) { - m_timer.Stop(); + StopTimer(); m_timer.Elapsed -= OnTimer; m_timer = null; } @@ -262,13 +278,11 @@ namespace OpenSim.Region.Framework.Scenes public void Stop() { - m_skipOnTimer = true; - - // Failed object creation - if (m_timer == null) - return; + m_running = false; + m_crossing = false; + m_crossFailcntr = 0; - m_timer.Stop(); + StopTimer(); m_timer.Elapsed -= OnTimer; m_timer = null; @@ -280,19 +294,17 @@ namespace OpenSim.Region.Framework.Scenes m_group.SendGroupRootTerseUpdate(); m_frames.Clear(); - m_running = false; } public void Pause() { - m_skipOnTimer = true; + m_running = false; + m_crossFailcntr = 0; + StopTimer(); m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); m_group.SendGroupRootTerseUpdate(); - - m_timer.Stop(); - m_running = false; } private void GetNextList() @@ -325,9 +337,16 @@ namespace OpenSim.Region.Framework.Scenes Keyframe k = m_keyframes[i]; if (k.Position.HasValue) - k.Position = (k.Position * direction) + pos; + { + k.Position = (k.Position * direction); +// k.Velocity = (Vector3)k.Position / (k.TimeMS / 1000.0f); + k.Position += pos; + } else + { k.Position = pos; +// k.Velocity = Vector3.Zero; + } k.StartRotation = rot; if (k.Rotation.HasValue) @@ -341,6 +360,8 @@ namespace OpenSim.Region.Framework.Scenes k.Rotation = rot; } +/* ang vel not in use for now + float angle = 0; float aa = k.StartRotation.X * k.StartRotation.X + k.StartRotation.Y * k.StartRotation.Y + k.StartRotation.Z * k.StartRotation.Z + k.StartRotation.W * k.StartRotation.W; @@ -370,6 +391,7 @@ namespace OpenSim.Region.Framework.Scenes } k.AngularVelocity = (new Vector3(0, 0, 1) * (Quaternion)k.Rotation) * (angle / (k.TimeMS / 1000)); + */ k.TimeTotal = k.TimeMS; m_frames.Add(k); @@ -387,20 +409,56 @@ namespace OpenSim.Region.Framework.Scenes protected void OnTimer(object sender, ElapsedEventArgs e) { - if (m_inOnTimer) + if (m_timerStopped) // trap events still in air even after a timer.stop + return; + + if (m_inOnTimer) // don't let overruns to happen { - m_log.Error("[KeyFrame]: timer overrun"); + m_log.Warn("[KeyFrame]: timer overrun"); return; } + if (m_group == null) + return; + // lock (m_onTimerLock) { - if (m_skipOnTimer) - return; m_inOnTimer = true; + + bool update = false; + try { + if (m_selected) + { + if (m_group.RootPart.Velocity != Vector3.Zero) + { + m_group.RootPart.Velocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + } + m_inOnTimer = false; + return; + } + + if (m_crossing) + { + // if crossing and timer running then cross failed + // wait some time then + // retry to set the position that evtually caused the outbound + // if still outside region this will call startCrossing below + m_crossing = false; + m_group.AbsolutePosition = m_nextPosition; + if (!m_crossing) + { + StopTimer(); + m_timer.Interval = timerInterval; + StartTimer(); + } + m_inOnTimer = false; + return; + } + if (m_frames.Count == 0) { GetNextList(); @@ -413,41 +471,41 @@ namespace OpenSim.Region.Framework.Scenes } m_currentFrame = m_frames[0]; - } + m_currentFrame.TimeMS += (int)timerInterval; - if (m_selected) - { - if (m_group.RootPart.Velocity != Vector3.Zero) - { - m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); - } - m_inOnTimer = false; - return; + //force a update on a keyframe transition + update = true; } + m_currentFrame.TimeMS -= (int)timerInterval; + // Do the frame processing double steps = (double)m_currentFrame.TimeMS / timerInterval; - float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; - if (steps <= 1.0) + if (steps <= 0.0) { - m_currentFrame.TimeMS = 0; + m_group.RootPart.Velocity = Vector3.Zero; + m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); - // m_group.AbsolutePosition = (Vector3)m_currentFrame.Position; m_nextPosition = (Vector3)m_currentFrame.Position; m_group.AbsolutePosition = m_nextPosition; m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); + + m_frames.RemoveAt(0); + if (m_frames.Count > 0) + m_currentFrame = m_frames[0]; + + update = true; } else { + float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal; + Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; Vector3 motionThisFrame = v / (float)steps; v = v * 1000 / m_currentFrame.TimeMS; - bool update = false; - if (Vector3.Mag(motionThisFrame) >= 0.05f) { // m_group.AbsolutePosition += motionThisFrame; @@ -463,8 +521,8 @@ namespace OpenSim.Region.Framework.Scenes Quaternion current = m_group.GroupRotation; Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); - - float angle = 0; +/* use simpler change detection + * float angle = 0; float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; @@ -493,6 +551,12 @@ namespace OpenSim.Region.Framework.Scenes } if (angle > 0.01f) + */ + if(Math.Abs(step.X -current.X) > 0.001f + || Math.Abs(step.Y -current.Y) > 0.001f + || Math.Abs(step.Z -current.Z) > 0.001f) + // assuming w is a dependente var + { m_group.UpdateGroupRotationR(step); //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); @@ -500,25 +564,22 @@ namespace OpenSim.Region.Framework.Scenes } } - if (update) - m_group.SendGroupRootTerseUpdate(); } - m_currentFrame.TimeMS -= (int)timerInterval; - - if (m_currentFrame.TimeMS <= 0) - { - m_group.RootPart.Velocity = Vector3.Zero; - m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); + if (update) m_group.SendGroupRootTerseUpdate(); - m_frames.RemoveAt(0); - if (m_frames.Count > 0) - m_currentFrame = m_frames[0]; - } } + catch ( Exception ex) + { + // still happening sometimes + // lets try to see what + m_log.Warn("[KeyFrame]: timer overrun" + ex.Message); + } + finally { + // make sure we do not let this frozen m_inOnTimer = false; } } @@ -528,10 +589,7 @@ namespace OpenSim.Region.Framework.Scenes { MemoryStream ms = new MemoryStream(); if (StopMoveTimer && m_timer != null) - { - m_skipOnTimer = true; - m_timer.Stop(); - } + StopTimer(); // lock (m_onTimerLock) { @@ -548,10 +606,9 @@ namespace OpenSim.Region.Framework.Scenes public void StartCrossingCheck() { - m_skipOnTimer = true; - if (m_timer != null) - m_timer.Stop(); - + StopTimer(); + m_crossing = true; +// to remove / retune to smoth crossings if (m_group.RootPart.Velocity != Vector3.Zero) { m_group.RootPart.Velocity = Vector3.Zero; @@ -561,24 +618,17 @@ namespace OpenSim.Region.Framework.Scenes public void CrossingFailure() { - // The serialization has stopped the timer, so let's wait a moment - // then retry the crossing. We'll get back here if it fails. - // if it is a open border there is no serialization - // so make sure timer is actually stopped - - m_group.RootPart.Velocity = Vector3.Zero; - m_group.SendGroupRootTerseUpdate(); - - Util.FireAndForget(delegate (object x) + if (m_group != null) { - Thread.Sleep(60000); - if (m_running) + m_group.RootPart.Velocity = Vector3.Zero; + m_group.SendGroupRootTerseUpdate(); + + if (m_running && m_timer != null) { - m_skipOnTimer = false; - m_timer.Start(); - m_group.AbsolutePosition = m_nextPosition; + m_timer.Interval = 60000; + StartTimer(); } - }); + } } } } -- cgit v1.1 From 2e54c3cc8f4caf6b6d056ae04419b171942a17d7 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Wed, 29 Aug 2012 03:19:47 +0100 Subject: A few more changes to keyframes --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 174 +++++++++++++-------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 4 +- .../Scenes/Serialization/SceneObjectSerializer.cs | 2 +- 3 files changed, 116 insertions(+), 64 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 5333177..42e3860 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -81,10 +81,10 @@ namespace OpenSim.Region.Framework.Scenes private bool m_timerStopped; [NonSerialized()] - private bool m_crossing; + private bool m_isCrossing; [NonSerialized()] - private int m_crossFailcntr; + private bool m_waitingCrossing; // retry position for cross fail [NonSerialized()] @@ -112,9 +112,7 @@ namespace OpenSim.Region.Framework.Scenes public bool Selected { set - { - m_crossing = false; - m_crossFailcntr = 0; + { if (!value) { // Once we're let go, recompute positions @@ -130,6 +128,8 @@ namespace OpenSim.Region.Framework.Scenes m_serializedPosition = m_group.AbsolutePosition; } } + m_isCrossing = false; + m_waitingCrossing = false; m_selected = value; } } @@ -150,6 +150,17 @@ namespace OpenSim.Region.Framework.Scenes m_timer.Stop(); } + private void RemoveTimer() + { + if (m_timer == null) + return; + m_timerStopped = true; + m_timer.Stop(); + m_timer.Elapsed -= OnTimer; + m_timer = null; + } + + public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) { KeyframeMotion newMotion = null; @@ -169,8 +180,8 @@ namespace OpenSim.Region.Framework.Scenes newMotion.m_onTimerLock = new object(); newMotion.m_timerStopped = false; newMotion.m_inOnTimer = false; - newMotion.m_crossing = false; - newMotion.m_crossFailcntr = 0; + newMotion.m_isCrossing = false; + newMotion.m_waitingCrossing = false; } catch { @@ -184,8 +195,8 @@ namespace OpenSim.Region.Framework.Scenes { // lock (m_onTimerLock) { - m_crossing = false; - m_crossFailcntr = 0; + m_isCrossing = false; + m_waitingCrossing = false; StopTimer(); m_group = grp; @@ -220,10 +231,13 @@ namespace OpenSim.Region.Framework.Scenes m_onTimerLock = new object(); m_group = grp; - m_basePosition = grp.AbsolutePosition; - m_baseRotation = grp.GroupRotation; - m_crossing = false; - m_crossFailcntr = 0; + if (grp != null) + { + m_basePosition = grp.AbsolutePosition; + m_baseRotation = grp.GroupRotation; + } + m_isCrossing = false; + m_waitingCrossing = false; } public void SetKeyframes(Keyframe[] frames) @@ -231,34 +245,74 @@ namespace OpenSim.Region.Framework.Scenes m_keyframes = frames; } + public KeyframeMotion Copy(SceneObjectGroup newgrp) + { + StopTimer(); + + KeyframeMotion newmotion = new KeyframeMotion(newgrp, m_mode, m_data); + + if (newgrp != null && newgrp.IsSelected) + newmotion.m_selected = true; + + if (m_keyframes != null) + m_keyframes.CopyTo(newmotion.m_keyframes, 0); + + newmotion.m_frames = new List(m_frames); + newmotion.m_currentFrame = m_currentFrame; + + newmotion.m_nextPosition = m_nextPosition; + if (m_selected) + newmotion.m_serializedPosition = m_serializedPosition; + else + { + if (m_group != null) + newmotion.m_serializedPosition = m_group.AbsolutePosition; + else + newmotion.m_serializedPosition = m_serializedPosition; + } + + newmotion.m_iterations = m_iterations; + + newmotion.m_onTimerLock = new object(); + newmotion.m_timerStopped = false; + newmotion.m_inOnTimer = false; + newmotion.m_isCrossing = false; + newmotion.m_waitingCrossing = false; + + if (m_running && !m_waitingCrossing) + StartTimer(); + + return newmotion; + } + public void Delete() { m_running = false; - m_crossing = false; - m_crossFailcntr = 0; - StopTimer(); + RemoveTimer(); + m_isCrossing = false; + m_waitingCrossing = false; m_frames.Clear(); m_keyframes = null; - - if (m_timer == null) - return; - m_timer.Elapsed -= OnTimer; - m_timer = null; } public void Start() { - m_crossing = false; - m_crossFailcntr = 0; + m_isCrossing = false; + m_waitingCrossing = false; if (m_keyframes.Length > 0) { if (m_timer == null) { m_timer = new Timer(); - m_timer.Interval = (int)timerInterval; + m_timer.Interval = timerInterval; m_timer.AutoReset = true; m_timer.Elapsed += OnTimer; } + else + { + StopTimer(); + m_timer.Interval = timerInterval; + } m_inOnTimer = false; StartTimer(); @@ -267,24 +321,17 @@ namespace OpenSim.Region.Framework.Scenes else { m_running = false; - if (m_timer != null) - { - StopTimer(); - m_timer.Elapsed -= OnTimer; - m_timer = null; - } + RemoveTimer(); } } public void Stop() { m_running = false; - m_crossing = false; - m_crossFailcntr = 0; + m_isCrossing = false; + m_waitingCrossing = false; - StopTimer(); - m_timer.Elapsed -= OnTimer; - m_timer = null; + RemoveTimer(); m_basePosition = m_group.AbsolutePosition; m_baseRotation = m_group.GroupRotation; @@ -299,8 +346,7 @@ namespace OpenSim.Region.Framework.Scenes public void Pause() { m_running = false; - m_crossFailcntr = 0; - StopTimer(); + RemoveTimer(); m_group.RootPart.Velocity = Vector3.Zero; m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); @@ -421,7 +467,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_group == null) return; -// lock (m_onTimerLock) + lock (m_onTimerLock) { m_inOnTimer = true; @@ -441,15 +487,15 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (m_crossing) + if (m_isCrossing) { // if crossing and timer running then cross failed // wait some time then // retry to set the position that evtually caused the outbound // if still outside region this will call startCrossing below - m_crossing = false; + m_isCrossing = false; m_group.AbsolutePosition = m_nextPosition; - if (!m_crossing) + if (!m_isCrossing) { StopTimer(); m_timer.Interval = timerInterval; @@ -552,9 +598,9 @@ namespace OpenSim.Region.Framework.Scenes if (angle > 0.01f) */ - if(Math.Abs(step.X -current.X) > 0.001f - || Math.Abs(step.Y -current.Y) > 0.001f - || Math.Abs(step.Z -current.Z) > 0.001f) + if(Math.Abs(step.X - current.X) > 0.001f + || Math.Abs(step.Y - current.Y) > 0.001f + || Math.Abs(step.Z - current.Z) > 0.001f) // assuming w is a dependente var { @@ -563,7 +609,6 @@ namespace OpenSim.Region.Framework.Scenes update = true; } } - } if (update) @@ -573,7 +618,7 @@ namespace OpenSim.Region.Framework.Scenes catch ( Exception ex) { // still happening sometimes - // lets try to see what + // lets try to see where m_log.Warn("[KeyFrame]: timer overrun" + ex.Message); } @@ -585,29 +630,34 @@ namespace OpenSim.Region.Framework.Scenes } } - public Byte[] Serialize(bool StopMoveTimer) + public Byte[] Serialize() { + StopTimer(); MemoryStream ms = new MemoryStream(); - if (StopMoveTimer && m_timer != null) - StopTimer(); -// lock (m_onTimerLock) - { - BinaryFormatter fmt = new BinaryFormatter(); - SceneObjectGroup tmp = m_group; - m_group = null; - if(!m_selected) - m_serializedPosition = tmp.AbsolutePosition; - fmt.Serialize(ms, this); - m_group = tmp; - return ms.ToArray(); - } + BinaryFormatter fmt = new BinaryFormatter(); + SceneObjectGroup tmp = m_group; + m_group = null; + if (!m_selected && tmp != null) + m_serializedPosition = tmp.AbsolutePosition; + fmt.Serialize(ms, this); + m_group = tmp; + if (m_running && !m_waitingCrossing) + StartTimer(); + + return ms.ToArray(); } public void StartCrossingCheck() { + // timer will be restart by crossingFailure + // or never since crossing worked and this + // should be deleted StopTimer(); - m_crossing = true; + + m_isCrossing = true; + m_waitingCrossing = true; + // to remove / retune to smoth crossings if (m_group.RootPart.Velocity != Vector3.Zero) { @@ -618,6 +668,8 @@ namespace OpenSim.Region.Framework.Scenes public void CrossingFailure() { + m_waitingCrossing = false; + if (m_group != null) { m_group.RootPart.Velocity = Vector3.Zero; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 65a1da2..834d27b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2066,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes { if (part.KeyframeMotion != null) { - part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize(false)); + part.KeyframeMotion = KeyframeMotion.FromData(backup_group, part.KeyframeMotion.Serialize()); // part.KeyframeMotion.UpdateSceneObject(this); } }); @@ -4419,7 +4419,7 @@ namespace OpenSim.Region.Framework.Scenes { if (part.KeyframeMotion != null) { - part.KeyframeMotion = KeyframeMotion.FromData(sog, part.KeyframeMotion.Serialize(true)); + part.KeyframeMotion = KeyframeMotion.FromData(sog, part.KeyframeMotion.Serialize()); // this is called later // part.KeyframeMotion.UpdateSceneObject(this); } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 1c75607..123c158 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1241,7 +1241,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (sog.RootPart.KeyframeMotion != null) { - Byte[] data = sog.RootPart.KeyframeMotion.Serialize(true); + Byte[] data = sog.RootPart.KeyframeMotion.Serialize(); writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty); writer.WriteBase64(data, 0, data.Length); -- cgit v1.1 From 211f4fb4114b2b26abe9c056bca9f6159ccbd125 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 30 Aug 2012 00:34:12 +0200 Subject: Sequence inventory descendents requests to reduce inventory server load and movement lag. --- .../Framework/Scenes/Scene.PacketHandlers.cs | 60 ++++++++++++++++++++-- 1 file changed, 55 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 431b903..e970543 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -422,6 +422,20 @@ namespace OpenSim.Region.Framework.Scenes ); } + private class DescendentsRequestData + { + public IClientAPI RemoteClient; + public UUID FolderID; + public UUID OwnerID; + public bool FetchFolders; + public bool FetchItems; + public int SortOrder; + } + + private Queue m_descendentsRequestQueue = new Queue(); + private Object m_descendentsRequestLock = new Object(); + private bool m_descendentsRequestProcessing = false; + /// /// Tell the client about the various child items and folders contained in the requested folder. /// @@ -458,17 +472,38 @@ namespace OpenSim.Region.Framework.Scenes } } - // We're going to send the reply async, because there may be - // an enormous quantity of packets -- basically the entire inventory! - // We don't want to block the client thread while all that is happening. - SendInventoryDelegate d = SendInventoryAsync; - d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); + lock (m_descendentsRequestLock) + { + if (!m_descendentsRequestProcessing) + { + m_descendentsRequestProcessing = true; + + // We're going to send the reply async, because there may be + // an enormous quantity of packets -- basically the entire inventory! + // We don't want to block the client thread while all that is happening. + SendInventoryDelegate d = SendInventoryAsync; + d.BeginInvoke(remoteClient, folderID, ownerID, fetchFolders, fetchItems, sortOrder, SendInventoryComplete, d); + + return; + } + + DescendentsRequestData req = new DescendentsRequestData(); + req.RemoteClient = remoteClient; + req.FolderID = folderID; + req.OwnerID = ownerID; + req.FetchFolders = fetchFolders; + req.FetchItems = fetchItems; + req.SortOrder = sortOrder; + + m_descendentsRequestQueue.Enqueue(req); + } } delegate void SendInventoryDelegate(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder); void SendInventoryAsync(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) { + Thread.Sleep(20); SendInventoryUpdate(remoteClient, new InventoryFolderBase(folderID), fetchFolders, fetchItems); } @@ -476,6 +511,21 @@ namespace OpenSim.Region.Framework.Scenes { SendInventoryDelegate d = (SendInventoryDelegate)iar.AsyncState; d.EndInvoke(iar); + + lock (m_descendentsRequestLock) + { + if (m_descendentsRequestQueue.Count > 0) + { + DescendentsRequestData req = m_descendentsRequestQueue.Dequeue(); + + d = SendInventoryAsync; + d.BeginInvoke(req.RemoteClient, req.FolderID, req.OwnerID, req.FetchFolders, req.FetchItems, req.SortOrder, SendInventoryComplete, d); + + return; + } + + m_descendentsRequestProcessing = false; + } } /// -- cgit v1.1 From c821153a4fcc0a0d806d2c9be63cf48494e4dd06 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 30 Aug 2012 00:15:46 +0100 Subject: [possible still bad] make use of keyframemotion.copy on sop.copy, replacing fromdata(seralize). for now its called with null group since sop.copy() hasn't usable new group information, so for copied keyframes be fully operational UpdateSceneObject(newgroup) needs to be called on them. --- OpenSim/Region/Framework/Scenes/KeyframeMotion.cs | 58 ++++++++++++---------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 12 +---- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++ 3 files changed, 38 insertions(+), 35 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs index 42e3860..e4e6f2c 100644 --- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs +++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs @@ -112,20 +112,23 @@ namespace OpenSim.Region.Framework.Scenes public bool Selected { set - { - if (!value) - { - // Once we're let go, recompute positions - if (m_selected) - UpdateSceneObject(m_group); - } - else + { + if (m_group != null) { - // Save selection position in case we get moved - if (!m_selected) + if (!value) { - StopTimer(); - m_serializedPosition = m_group.AbsolutePosition; + // Once we're let go, recompute positions + if (m_selected) + UpdateSceneObject(m_group); + } + else + { + // Save selection position in case we get moved + if (!m_selected) + { + StopTimer(); + m_serializedPosition = m_group.AbsolutePosition; + } } } m_isCrossing = false; @@ -199,6 +202,9 @@ namespace OpenSim.Region.Framework.Scenes m_waitingCrossing = false; StopTimer(); + if (grp == null) + return; + m_group = grp; Vector3 grppos = grp.AbsolutePosition; Vector3 offset = grppos - m_serializedPosition; @@ -228,14 +234,16 @@ namespace OpenSim.Region.Framework.Scenes m_mode = mode; m_data = data; - m_onTimerLock = new object(); - m_group = grp; if (grp != null) { m_basePosition = grp.AbsolutePosition; m_baseRotation = grp.GroupRotation; } + + m_onTimerLock = new object(); + m_timerStopped = true; + m_inOnTimer = false; m_isCrossing = false; m_waitingCrossing = false; } @@ -249,18 +257,23 @@ namespace OpenSim.Region.Framework.Scenes { StopTimer(); - KeyframeMotion newmotion = new KeyframeMotion(newgrp, m_mode, m_data); + KeyframeMotion newmotion = new KeyframeMotion(null, m_mode, m_data); - if (newgrp != null && newgrp.IsSelected) - newmotion.m_selected = true; + newmotion.m_group = newgrp; if (m_keyframes != null) + { + newmotion.m_keyframes = new Keyframe[m_keyframes.Length]; m_keyframes.CopyTo(newmotion.m_keyframes, 0); + } newmotion.m_frames = new List(m_frames); + + newmotion.m_basePosition = m_basePosition; + newmotion.m_baseRotation = m_baseRotation; + newmotion.m_currentFrame = m_currentFrame; - newmotion.m_nextPosition = m_nextPosition; if (m_selected) newmotion.m_serializedPosition = m_serializedPosition; else @@ -272,12 +285,7 @@ namespace OpenSim.Region.Framework.Scenes } newmotion.m_iterations = m_iterations; - - newmotion.m_onTimerLock = new object(); - newmotion.m_timerStopped = false; - newmotion.m_inOnTimer = false; - newmotion.m_isCrossing = false; - newmotion.m_waitingCrossing = false; + newmotion.m_running = m_running; if (m_running && !m_waitingCrossing) StartTimer(); @@ -299,7 +307,7 @@ namespace OpenSim.Region.Framework.Scenes { m_isCrossing = false; m_waitingCrossing = false; - if (m_keyframes.Length > 0) + if (m_keyframes != null && m_group != null && m_keyframes.Length > 0) { if (m_timer == null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 834d27b..fe34ad4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2062,6 +2062,7 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChangedDueToDelink = false; m_scene.EventManager.TriggerOnSceneObjectPreSave(backup_group, this); +/* backup_group.ForEachPart(delegate(SceneObjectPart part) { if (part.KeyframeMotion != null) @@ -2070,7 +2071,7 @@ namespace OpenSim.Region.Framework.Scenes // part.KeyframeMotion.UpdateSceneObject(this); } }); - +*/ datastore.StoreObject(backup_group, m_scene.RegionInfo.RegionID); backup_group.ForEachPart(delegate(SceneObjectPart part) @@ -4415,15 +4416,6 @@ namespace OpenSim.Region.Framework.Scenes public virtual ISceneObject CloneForNewScene() { SceneObjectGroup sog = Copy(false); - sog.ForEachPart(delegate(SceneObjectPart part) - { - if (part.KeyframeMotion != null) - { - part.KeyframeMotion = KeyframeMotion.FromData(sog, part.KeyframeMotion.Serialize()); - // this is called later -// part.KeyframeMotion.UpdateSceneObject(this); - } - }); sog.IsDeleted = false; return sog; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index bf5fc99..4788a24 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2110,6 +2110,9 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(Shape.ExtraParams, extraP, extraP.Length); dupe.Shape.ExtraParams = extraP; + if (KeyframeMotion != null) + dupe.KeyframeMotion = KeyframeMotion.Copy(null); + if (userExposed) { if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero) -- cgit v1.1