From b6873a7b5d8bbb4936550b38b0fbc9b0a8463b63 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 2 Nov 2011 13:16:02 +0000 Subject: [PATCH 1/4] Catch any exceptions exiting the top of the robust console, as we already do for the main simulator. This prevents issues such as transient mono console problems from crashing the server. --- OpenSim/Server/Base/ServicesServerBase.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 36e66650c2..aeba35ff1c 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -266,7 +266,14 @@ namespace OpenSim.Server.Base { while (m_Running) { - MainConsole.Instance.Prompt(); + try + { + MainConsole.Instance.Prompt(); + } + catch (Exception e) + { + m_log.ErrorFormat("Command error: {0}", e); + } } if (m_pidFile != String.Empty) From 03993d0b14599358ac30a001cebd5b2145881c65 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 2 Nov 2011 18:12:12 +0000 Subject: [PATCH 2/4] Fix race condition that would sometimes send or save appearance for the wrong avatar. In AvatarFactoryModule.HandleAppearanceUpdateTimer(), we loop through appearance save and send requests and dispatch via a FireAndForget thread. If there was more than one request in the save or send queue, then this led to a subtle race condition where the foreach loop would load in the next KeyValuePair before the thread was dispatched. This gave the thread the wrong avatar ID, leaving some avatar appearance cloudy since appearance data was never sent. This change loads the fields into local references so that this doesn't happen. --- .../AvatarFactory/AvatarFactoryModule.cs | 28 ++++++++++++++----- .../Region/Framework/Scenes/ScenePresence.cs | 5 ++-- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 236a47c604..07d1cb3581 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -169,6 +169,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public bool SendAppearance(UUID agentId) { +// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); + ScenePresence sp = m_scene.GetScenePresence(agentId); if (sp == null) { @@ -257,7 +259,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void QueueAppearanceSend(UUID agentid) { - // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); +// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); // 10000 ticks per millisecond, 1000 milliseconds per second long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); @@ -393,10 +395,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Dictionary sends = new Dictionary(m_sendqueue); foreach (KeyValuePair kvp in sends) { - if (kvp.Value < now) + // We have to load the key and value into local parameters to avoid a race condition if we loop + // around and load kvp with a different value before FireAndForget has launched its thread. + UUID avatarID = kvp.Key; + long sendTime = kvp.Value; + +// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); + + if (sendTime < now) { - Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); }); - m_sendqueue.Remove(kvp.Key); + Util.FireAndForget(o => SendAppearance(avatarID)); + m_sendqueue.Remove(avatarID); } } } @@ -406,10 +415,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Dictionary saves = new Dictionary(m_savequeue); foreach (KeyValuePair kvp in saves) { - if (kvp.Value < now) + // We have to load the key and value into local parameters to avoid a race condition if we loop + // around and load kvp with a different value before FireAndForget has launched its thread. + UUID avatarID = kvp.Key; + long sendTime = kvp.Value; + + if (sendTime < now) { - Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); }); - m_savequeue.Remove(kvp.Key); + Util.FireAndForget(o => SaveAppearance(avatarID)); + m_savequeue.Remove(avatarID); } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 29966f9722..3e3fb0fa63 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2628,7 +2628,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendAppearanceToAllOtherAgents() { - //m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} ({1})", Name, UUID); +// m_log.DebugFormat("[SCENE PRESENCE] SendAppearanceToAllOtherAgents: {0} {1}", Name, UUID); + // only send update from root agents to other clients; children are only "listening posts" if (IsChildAgent) { @@ -2656,7 +2657,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SendOtherAgentsAppearanceToMe() { - //m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} ({1})", Name, UUID); +// m_log.DebugFormat("[SCENE PRESENCE] SendOtherAgentsAppearanceToMe: {0} {1}", Name, UUID); int count = 0; m_scene.ForEachRootScenePresence(delegate(ScenePresence scenePresence) From 72923134e9ab9ab946253c883d40536af389ab18 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 2 Nov 2011 18:40:49 +0000 Subject: [PATCH 3/4] Get some hopefully more useful exception information when OpenJPEG.EncodeFromImage() fails in VectorRender and DynamicTexture modules --- .../Scripting/DynamicTexture/DynamicTextureModule.cs | 6 ++++-- .../Scripting/VectorRender/VectorRenderModule.cs | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 6075e194b6..f2c8b3dd54 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -395,9 +395,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { result = OpenJPEG.EncodeFromImage(joint, true); } - catch (Exception) + catch (Exception e) { - m_log.Error("[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); + m_log.ErrorFormat( + "[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Exception {0}{1}", + e.Message, e.StackTrace); } return result; diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 7316e5b546..c061868ed6 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -338,10 +338,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); } - catch (Exception) + catch (Exception e) { - m_log.Error( - "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); + m_log.ErrorFormat( + "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}", + e.Message, e.StackTrace); } m_textureManager.ReturnData(id, imageJ2000); From e2c51a977d42822fe78ae0744117afb7bf509d35 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 2 Nov 2011 14:59:00 -0700 Subject: [PATCH 4/4] Changes UpdateFlag in SOP to an enumeration of NONE, TERSE and FULL. UpdateFlag is now referenced/used only within SOP and SOG. Outsiders are using ScheduleFullUpdate, ScheduleTerseUpdate or ClearUpdateSchedule on SOP consistently now. Also started working toward eliminating those calls to ScheduleFullUpdate, ScheduleTerseUpdate or ClearUpdateSchedule from outside SOP in favor of just setting properties on SOP and let SOP decide if an update should be scheduled. This consolidates the update policy within SOP and the client rather than everywhere that makes changes to SOP. Some places forget to call update while others call it multiple times, "just to be sure". UpdateFlag and Schedule*Update will both be made private shortly. UpdateFlag is intended to be transient and internal to SOP so it has been removed from XML serializer for SOPs. --- OpenSim/Data/Tests/RegionTests.cs | 5 - .../ObjectCaps/UploadObjectAssetModule.cs | 7 +- .../EntityTransfer/EntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Framework/Scenes/SceneObjectGroup.cs | 6 +- .../Framework/Scenes/SceneObjectPart.cs | 99 ++++++++++--------- .../Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Serialization/SceneObjectSerializer.cs | 7 -- .../Scenes/Tests/SceneObjectLinkingTests.cs | 16 +-- OpenSim/Region/Framework/Scenes/UndoState.cs | 6 +- .../Shared/Api/Implementation/LSL_Api.cs | 15 ++- 11 files changed, 76 insertions(+), 91 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index cac8cac3ef..1b93176df6 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -297,7 +297,6 @@ namespace OpenSim.Data.Tests pbshap.ProfileEnd = ushort.MaxValue; pbshap.ProfileHollow = ushort.MaxValue; Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); - byte updatef = (byte) random.Next(127); RegionInfo regionInfo = new RegionInfo(); regionInfo.RegionID = region3; @@ -336,7 +335,6 @@ namespace OpenSim.Data.Tests sop.LinkNum = linknum; sop.ClickAction = clickaction; sop.Scale = scale; - sop.UpdateFlag = updatef; //Tests if local part accepted the parameters: Assert.That(regionh,Is.EqualTo(sop.RegionHandle), "Assert.That(regionh,Is.EqualTo(sop.RegionHandle))"); @@ -369,7 +367,6 @@ namespace OpenSim.Data.Tests Assert.That(linknum,Is.EqualTo(sop.LinkNum), "Assert.That(linknum,Is.EqualTo(sop.LinkNum))"); Assert.That(clickaction,Is.EqualTo(sop.ClickAction), "Assert.That(clickaction,Is.EqualTo(sop.ClickAction))"); Assert.That(scale,Is.EqualTo(sop.Scale), "Assert.That(scale,Is.EqualTo(sop.Scale))"); - Assert.That(updatef,Is.EqualTo(sop.UpdateFlag), "Assert.That(updatef,Is.EqualTo(sop.UpdateFlag))"); // This is necessary or object will not be inserted in DB sop.Flags = PrimFlags.None; @@ -469,7 +466,6 @@ namespace OpenSim.Data.Tests PrimitiveBaseShape pbshap = new PrimitiveBaseShape(); pbshap = PrimitiveBaseShape.Default; Vector3 scale = new Vector3(random.Next(),random.Next(),random.Next()); - byte updatef = (byte) random.Next(127); // Updates the region with new values SceneObjectGroup sog2 = FindSOG("Adam West", region3); @@ -499,7 +495,6 @@ namespace OpenSim.Data.Tests sog2.RootPart.LinkNum = linknum; sog2.RootPart.ClickAction = clickaction; sog2.RootPart.Scale = scale; - sog2.RootPart.UpdateFlag = updatef; db.StoreObject(sog2, region3); List sogs = db.LoadObjects(region3); diff --git a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs index c07fc73069..e4bacd4df2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/ObjectCaps/UploadObjectAssetModule.cs @@ -332,7 +332,7 @@ namespace OpenSim.Region.ClientStack.Linden grp.IsAttachment = false; // Required for linking - grp.RootPart.UpdateFlag = 0; + grp.RootPart.ClearUpdateSchedule(); if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) { @@ -345,8 +345,9 @@ namespace OpenSim.Region.ClientStack.Linden for (int j = 1; j < allparts.Length; j++) { - rootGroup.RootPart.UpdateFlag = 0; - allparts[j].RootPart.UpdateFlag = 0; + // Required for linking + rootGroup.RootPart.ClearUpdateSchedule(); + allparts[j].RootPart.ClearUpdateSchedule(); rootGroup.LinkToGroup(allparts[j]); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7324b26afc..7251bd88ba 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1714,7 +1714,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); bool successYN = false; - grp.RootPart.UpdateFlag = 0; + grp.RootPart.ClearUpdateSchedule(); //int primcrossingXMLmethod = 0; if (destination != null) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 1af18e7309..82ded28360 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1799,7 +1799,7 @@ namespace OpenSim.Region.Framework.Scenes newSet.RemoveAt(0); foreach (SceneObjectPart newChild in newSet) - newChild.UpdateFlag = 0; + newChild.ClearUpdateSchedule(); LinkObjects(newRoot, newSet); if (!affectedGroups.Contains(newRoot.ParentGroup)) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 2ea9854ef2..a0a734499e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1157,7 +1157,7 @@ namespace OpenSim.Region.Framework.Scenes if (!silent) { - part.UpdateFlag = 0; + part.ClearUpdateSchedule(); if (part == m_rootPart) { if (!IsAttachment || (AttachedAvatar == avatar.ControllingClient.AgentId) || @@ -1735,13 +1735,13 @@ namespace OpenSim.Region.Framework.Scenes if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) { - m_rootPart.UpdateFlag = 1; + m_rootPart.UpdateFlag = UpdateRequired.TERSE; lastPhysGroupPos = AbsolutePosition; } if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) { - m_rootPart.UpdateFlag = 1; + m_rootPart.UpdateFlag = UpdateRequired.TERSE; lastPhysGroupRot = GroupRotation; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b68cc9fde6..44f822ce39 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -106,6 +106,13 @@ namespace OpenSim.Region.Framework.Scenes SCULPT = 7 } + public enum UpdateRequired : byte + { + NONE = 0, + TERSE = 1, + FULL = 2 + } + #endregion Enumerations public class SceneObjectPart : IScriptHost, ISceneEntity @@ -254,15 +261,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_passTouches; - /// - /// Only used internally to schedule client updates. - /// 0 - no update is scheduled - /// 1 - terse update scheduled - /// 2 - full update scheduled - /// - /// TODO - This should be an enumeration - /// - private byte m_updateFlag; + private UpdateRequired m_updateFlag; private PhysicsActor m_physActor; protected Vector3 m_acceleration; @@ -884,7 +883,15 @@ namespace OpenSim.Region.Framework.Scenes } } - /// + /// Update angular velocity and schedule terse update. + public void UpdateAngularVelocity(Vector3 avel) + { + AngularVelocity = avel; + ScheduleTerseUpdate(); + ParentGroup.HasGroupChanged = true; + } + + /// Get or set angular velocity. Does not schedule update. public Vector3 AngularVelocity { get @@ -1023,8 +1030,8 @@ namespace OpenSim.Region.Framework.Scenes TriggerScriptChangedEvent(Changed.SCALE); } } - - public byte UpdateFlag + + public UpdateRequired UpdateFlag { get { return m_updateFlag; } set { m_updateFlag = value; } @@ -1309,9 +1316,9 @@ namespace OpenSim.Region.Framework.Scenes /// /// Clear all pending updates of parts to clients /// - private void ClearUpdateSchedule() + public void ClearUpdateSchedule() { - m_updateFlag = 0; + UpdateFlag = UpdateRequired.NONE; } /// @@ -2829,7 +2836,7 @@ namespace OpenSim.Region.Framework.Scenes TimeStampFull = (uint)timeNow; } - m_updateFlag = 2; + UpdateFlag = UpdateRequired.FULL; // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling full update for {0}, {1} at {2}", @@ -2845,13 +2852,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup == null) return; - if (m_updateFlag < 1) + if (UpdateFlag == UpdateRequired.NONE) { m_parentGroup.HasGroupChanged = true; m_parentGroup.QueueForUpdateCheck(); TimeStampTerse = (uint) Util.UnixTimeSinceEpoch(); - m_updateFlag = 1; + UpdateFlag = UpdateRequired.TERSE; // m_log.DebugFormat( // "[SCENE OBJECT PART]: Scheduling terse update for {0}, {1} at {2}", @@ -3018,45 +3025,39 @@ namespace OpenSim.Region.Framework.Scenes const float POSITION_TOLERANCE = 0.05f; const int TIME_MS_TOLERANCE = 3000; - if (m_updateFlag == 1) + switch (UpdateFlag) { - // Throw away duplicate or insignificant updates - if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Acceleration.Equals(m_lastAcceleration) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || - !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || - !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || - Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) + case UpdateRequired.TERSE: { - AddTerseUpdateToAllAvatars(); - ClearUpdateSchedule(); + // Throw away duplicate or insignificant updates + if (!RotationOffset.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Acceleration.Equals(m_lastAcceleration) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + Velocity.ApproxEquals(Vector3.Zero, VELOCITY_TOLERANCE) || + !AngularVelocity.ApproxEquals(m_lastAngularVelocity, VELOCITY_TOLERANCE) || + !OffsetPosition.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || + Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) + { + AddTerseUpdateToAllAvatars(); + ClearUpdateSchedule(); - // This causes the Scene to 'poll' physical objects every couple of frames - // bad, so it's been replaced by an event driven method. - //if ((ObjectFlags & (uint)PrimFlags.Physics) != 0) - //{ - // Only send the constant terse updates on physical objects! - //ScheduleTerseUpdate(); - //} - - // Update the "last" values - m_lastPosition = OffsetPosition; - m_lastRotation = RotationOffset; - m_lastVelocity = Velocity; - m_lastAcceleration = Acceleration; - m_lastAngularVelocity = AngularVelocity; - m_lastTerseSent = Environment.TickCount; + // Update the "last" values + m_lastPosition = OffsetPosition; + m_lastRotation = RotationOffset; + m_lastVelocity = Velocity; + m_lastAcceleration = Acceleration; + m_lastAngularVelocity = AngularVelocity; + m_lastTerseSent = Environment.TickCount; + } + break; } - } - else - { - if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes + case UpdateRequired.FULL: { AddFullUpdateToAllAvatars(); - ClearUpdateSchedule(); + break; } } + ClearUpdateSchedule(); } @@ -3436,7 +3437,7 @@ namespace OpenSim.Region.Framework.Scenes _groupID = groupID; if (client != null) SendPropertiesToClient(client); - m_updateFlag = 2; + UpdateFlag = UpdateRequired.FULL; } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 29966f9722..71c39b2941 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3211,7 +3211,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (ISceneObject so in cAgent.AttachmentObjects) { ((SceneObjectGroup)so).LocalId = 0; - ((SceneObjectGroup)so).RootPart.UpdateFlag = 0; + ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); m_scene.IncomingCreateObject(so); } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index e06a222b15..60cc788dc9 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -316,7 +316,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization m_SOPXmlProcessors.Add("ClickAction", ProcessClickAction); m_SOPXmlProcessors.Add("Shape", ProcessShape); m_SOPXmlProcessors.Add("Scale", ProcessScale); - m_SOPXmlProcessors.Add("UpdateFlag", ProcessUpdateFlag); m_SOPXmlProcessors.Add("SitTargetOrientation", ProcessSitTargetOrientation); m_SOPXmlProcessors.Add("SitTargetPosition", ProcessSitTargetPosition); m_SOPXmlProcessors.Add("SitTargetPositionLL", ProcessSitTargetPositionLL); @@ -584,11 +583,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization obj.Scale = Util.ReadVector(reader, "Scale"); } - private static void ProcessUpdateFlag(SceneObjectPart obj, XmlTextReader reader) - { - obj.UpdateFlag = (byte)reader.ReadElementContentAsInt("UpdateFlag", String.Empty); - } - private static void ProcessSitTargetOrientation(SceneObjectPart obj, XmlTextReader reader) { obj.SitTargetOrientation = Util.ReadQuaternion(reader, "SitTargetOrientation"); @@ -1187,7 +1181,6 @@ namespace OpenSim.Region.Framework.Scenes.Serialization WriteShape(writer, sop.Shape, options); WriteVector(writer, "Scale", sop.Scale); - writer.WriteElementString("UpdateFlag", sop.UpdateFlag.ToString()); WriteQuaternion(writer, "SitTargetOrientation", sop.SitTargetOrientation); WriteVector(writer, "SitTargetPosition", sop.SitTargetPosition); WriteVector(writer, "SitTargetPositionLL", sop.SitTargetPositionLL); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs index 90cdd7baf4..a2332bb4ec 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs @@ -70,8 +70,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests grp2.UpdateGroupRotationR(Quaternion.CreateFromEulers(180 * Utils.DEG_TO_RAD, 0, 0)); // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp2.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearUpdateSchedule(); + grp2.RootPart.ClearUpdateSchedule(); // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); @@ -164,10 +164,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests grp4.UpdateGroupRotationR(Quaternion.CreateFromEulers(0, 90 * Utils.DEG_TO_RAD, 0)); // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp2.RootPart.UpdateFlag = 0; - grp3.RootPart.UpdateFlag = 0; - grp4.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearUpdateSchedule(); + grp2.RootPart.ClearUpdateSchedule(); + grp3.RootPart.ClearUpdateSchedule(); + grp4.RootPart.ClearUpdateSchedule(); // Link grp2 to grp1. part2 becomes child prim to grp1. grp2 is eliminated. grp1.LinkToGroup(grp2); @@ -198,8 +198,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests } // Required for linking - grp1.RootPart.UpdateFlag = 0; - grp3.RootPart.UpdateFlag = 0; + grp1.RootPart.ClearUpdateSchedule(); + grp3.RootPart.ClearUpdateSchedule(); // root part should have no offset position or rotation Assert.That(part1.OffsetPosition == Vector3.Zero && part1.RotationOffset == Quaternion.Identity, diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index d34d8e55ae..860172c4f7 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -158,6 +158,7 @@ namespace OpenSim.Region.Framework.Scenes } else { + // Note: Updating these properties on sop automatically schedules an update if needed if (Position != Vector3.Zero) { // m_log.DebugFormat( @@ -181,8 +182,6 @@ namespace OpenSim.Region.Framework.Scenes part.Resize(Scale); } - - part.ScheduleTerseUpdate(); } part.Undoing = false; @@ -212,6 +211,7 @@ namespace OpenSim.Region.Framework.Scenes } else { + // Note: Updating these properties on sop automatically schedules an update if needed if (Position != Vector3.Zero) part.OffsetPosition = Position; @@ -220,8 +220,6 @@ namespace OpenSim.Region.Framework.Scenes if (Scale != Vector3.Zero) part.Resize(Scale); - - part.ScheduleTerseUpdate(); } part.Undoing = false; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 83c3b78d65..b3d0dd5dfc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3330,10 +3330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) { - part.AngularVelocity = new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)); - part.ScheduleTerseUpdate(); - part.SendTerseUpdateToAllClients(); - part.ParentGroup.HasGroupChanged = true; + part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); } public LSL_Integer llGetStartParameter() @@ -3595,11 +3592,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim = targetPart.ParentGroup; childPrim = m_host.ParentGroup; } -// byte uf = childPrim.RootPart.UpdateFlag; - childPrim.RootPart.UpdateFlag = 0; + + // Required for linking + childPrim.RootPart.ClearUpdateSchedule(); parentPrim.LinkToGroup(childPrim); -// if (uf != (Byte)0) -// parent.RootPart.UpdateFlag = uf; } parentPrim.TriggerScriptChangedEvent(Changed.LINK); @@ -3680,7 +3676,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parts.Remove(newRoot); foreach (SceneObjectPart part in parts) { - part.UpdateFlag = 0; + // Required for linking + part.ClearUpdateSchedule(); newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } newRoot.ParentGroup.HasGroupChanged = true;