From f8cc409034528f645628bd022aba9657545637f8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 5 Dec 2009 23:25:30 +0000 Subject: [PATCH 1/8] Cause better packing of ObjectProperties --- .../ClientStack/LindenUDP/LLClientView.cs | 104 +++++++++++++----- 1 file changed, 78 insertions(+), 26 deletions(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index ffe6fe934f..fba5090a14 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -352,6 +352,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP private IHyperAssetService m_hyperAssets; private const bool m_checkPackets = true; + private Timer m_propertiesPacketTimer; + private List m_propertiesBlocks = new List(); + #endregion Class Members #region Properties @@ -433,6 +436,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.OnQueueEmpty += HandleQueueEmpty; m_udpClient.OnPacketStats += PopulateStats; + m_propertiesPacketTimer = new Timer(100); + m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; + RegisterLocalPacketHandlers(); } @@ -3579,42 +3585,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) { - ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); // TODO: don't create new blocks if recycling an old packet - proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; - proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); - proper.ObjectData[0].ItemID = ItemID; - proper.ObjectData[0].CreationDate = CreationDate; - proper.ObjectData[0].CreatorID = CreatorUUID; - proper.ObjectData[0].FolderID = FolderUUID; - proper.ObjectData[0].FromTaskID = FromTaskUUID; - proper.ObjectData[0].GroupID = GroupUUID; - proper.ObjectData[0].InventorySerial = InventorySerial; + ObjectPropertiesPacket.ObjectDataBlock block = + new ObjectPropertiesPacket.ObjectDataBlock(); - proper.ObjectData[0].LastOwnerID = LastOwnerUUID; + block.ItemID = ItemID; + block.CreationDate = CreationDate; + block.CreatorID = CreatorUUID; + block.FolderID = FolderUUID; + block.FromTaskID = FromTaskUUID; + block.GroupID = GroupUUID; + block.InventorySerial = InventorySerial; + + block.LastOwnerID = LastOwnerUUID; // proper.ObjectData[0].LastOwnerID = UUID.Zero; - proper.ObjectData[0].ObjectID = ObjectUUID; + block.ObjectID = ObjectUUID; if (OwnerUUID == GroupUUID) - proper.ObjectData[0].OwnerID = UUID.Zero; + block.OwnerID = UUID.Zero; else - proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); - proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); - proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); - proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); - proper.ObjectData[0].OwnerMask = OwnerMask; - proper.ObjectData[0].NextOwnerMask = NextOwnerMask; - proper.ObjectData[0].GroupMask = GroupMask; - proper.ObjectData[0].EveryoneMask = EveryoneMask; - proper.ObjectData[0].BaseMask = BaseMask; + block.OwnerID = OwnerUUID; + block.TouchName = Util.StringToBytes256(TouchTitle); + block.TextureID = TextureID; + block.SitName = Util.StringToBytes256(SitTitle); + block.Name = Util.StringToBytes256(ItemName); + block.Description = Util.StringToBytes256(ItemDescription); + block.OwnerMask = OwnerMask; + block.NextOwnerMask = NextOwnerMask; + block.GroupMask = GroupMask; + block.EveryoneMask = EveryoneMask; + block.BaseMask = BaseMask; // proper.ObjectData[0].AggregatePerms = 53; // proper.ObjectData[0].AggregatePermTextures = 0; // proper.ObjectData[0].AggregatePermTexturesOwner = 0; - proper.ObjectData[0].SaleType = saleType; - proper.ObjectData[0].SalePrice = salePrice; + block.SaleType = saleType; + block.SalePrice = salePrice; + + lock (m_propertiesPacketTimer) + { + m_propertiesBlocks.Add(block); + + int length = 0; + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + length += b.Length; + } + if (length > 1100) // FIXME: use real MTU + { + ProcessObjectPropertiesPacket(null, null); + m_propertiesPacketTimer.Stop(); + return; + } + + m_propertiesPacketTimer.Stop(); + m_propertiesPacketTimer.Start(); + } + + //proper.Header.Zerocoded = true; + //OutPacket(proper, ThrottleOutPacketType.Task); + } + + private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) + { + ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + + lock (m_propertiesPacketTimer) + { + m_propertiesPacketTimer.Stop(); + + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; + + int index = 0; + + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + proper.ObjectData[index++] = b; + } + + m_propertiesBlocks.Clear(); + } + proper.Header.Zerocoded = true; OutPacket(proper, ThrottleOutPacketType.Task); } From e3a22ff37da47405d2ad2a656970f501e1a7673c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:02:24 +0000 Subject: [PATCH 2/8] Eliminate multiple updates on link/unlink --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 ++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 ++++---- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2fdb48dd89..d87e81441b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1593,6 +1593,8 @@ namespace OpenSim.Region.Framework.Scenes // occur on link to invoke this elsewhere (such as object selection) parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); if (client != null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6badaf5d0d..6170caa3c5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2207,8 +2207,8 @@ namespace OpenSim.Region.Framework.Scenes // unmoved prims! ResetChildPrimPhysicsPositions(); - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// @@ -2299,8 +2299,8 @@ namespace OpenSim.Region.Framework.Scenes linkPart.Rezzed = RootPart.Rezzed; - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d235bacb23..9a905f1825 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3523,6 +3523,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { parentPrim.DelinkFromGroup(part.LocalId, true); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) @@ -3534,6 +3536,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateFlag = 0; newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } + newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } else @@ -3542,6 +3546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; parentPrim.DelinkFromGroup(childPrim.LocalId, true); + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } } @@ -3561,6 +3567,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); } public LSL_String llGetLinkKey(int linknum) From 46d5add175b2c4281780c839283616fbe5394b67 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:25:04 +0000 Subject: [PATCH 3/8] Lock updates out while linking and unlinking --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 279 +++++++++--------- 1 file changed, 146 insertions(+), 133 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d87e81441b..5efe188544 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -26,6 +26,7 @@ */ using System; +using System.Threading; using System.Collections.Generic; using System.Reflection; using OpenMetaverse; @@ -96,6 +97,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); private readonly Object m_dictionary_lock = new Object(); + private Object m_updateLock = new Object(); + #endregion protected internal SceneGraph(Scene parent, RegionInfo regInfo) @@ -369,6 +372,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdateObjectGroups() { + if (!Monitor.TryEnter(m_updateLock)) + return; + List updates; // Some updates add more updates to the updateList. @@ -395,6 +401,7 @@ namespace OpenSim.Region.Framework.Scenes "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); } } + Monitor.Exit(m_updateLock); } protected internal void AddPhysicalPrim(int number) @@ -1555,56 +1562,59 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) { - SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); - - List childGroups = new List(); - if (parentGroup != null) + lock (m_updateLock) { - // We do this in reverse to get the link order of the prims correct - for (int i = childPrimIds.Count - 1; i >= 0; i--) + SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); + + List childGroups = new List(); + if (parentGroup != null) { - SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); - if (child != null) + // We do this in reverse to get the link order of the prims correct + for (int i = childPrimIds.Count - 1; i >= 0; i--) { - // Make sure no child prim is set for sale - // So that, on delink, no prims are unwittingly - // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; - childGroups.Add(child); + SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); + if (child != null) + { + // Make sure no child prim is set for sale + // So that, on delink, no prims are unwittingly + // left for sale and sold off + child.RootPart.ObjectSaleType = 0; + child.RootPart.SalePrice = 10; + childGroups.Add(child); + } } } - } - else - { - return; // parent is null so not in this region - } - - foreach (SceneObjectGroup child in childGroups) - { - parentGroup.LinkToGroup(child); - - // this is here so physics gets updated! - // Don't remove! Bad juju! Stay away! or fix physics! - child.AbsolutePosition = child.AbsolutePosition; - } - - // We need to explicitly resend the newly link prim's object properties since no other actions - // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); - parentGroup.TriggerScriptChangedEvent(Changed.LINK); - parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); - - if (client != null) - { - parentGroup.GetProperties(client); - } - else - { - foreach (ScenePresence p in GetScenePresences()) + else { - parentGroup.GetProperties(p.ControllingClient); + return; // parent is null so not in this region + } + + foreach (SceneObjectGroup child in childGroups) + { + parentGroup.LinkToGroup(child); + + // this is here so physics gets updated! + // Don't remove! Bad juju! Stay away! or fix physics! + child.AbsolutePosition = child.AbsolutePosition; + } + + // We need to explicitly resend the newly link prim's object properties since no other actions + // occur on link to invoke this elsewhere (such as object selection) + parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); + parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); + + if (client != null) + { + parentGroup.GetProperties(client); + } + else + { + foreach (ScenePresence p in GetScenePresences()) + { + parentGroup.GetProperties(p.ControllingClient); + } } } } @@ -1620,109 +1630,112 @@ namespace OpenSim.Region.Framework.Scenes protected internal void DelinkObjects(List primIds, bool sendEvents) { - List childParts = new List(); - List rootParts = new List(); - List affectedGroups = new List(); - // Look them all up in one go, since that is comparatively expensive - // - foreach (uint primID in primIds) + lock (m_updateLock) { - SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); - if (part != null) - { - if (part.LinkNum < 2) // Root or single - rootParts.Add(part); - else - childParts.Add(part); - - SceneObjectGroup group = part.ParentGroup; - if (!affectedGroups.Contains(group)) - affectedGroups.Add(group); - } - else - { - m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); - } - } - - foreach (SceneObjectPart child in childParts) - { - // Unlink all child parts from their groups + List childParts = new List(); + List rootParts = new List(); + List affectedGroups = new List(); + // Look them all up in one go, since that is comparatively expensive // - child.ParentGroup.DelinkFromGroup(child, sendEvents); - } - - foreach (SceneObjectPart root in rootParts) - { - // In most cases, this will run only one time, and the prim - // will be a solo prim - // However, editing linked parts and unlinking may be different - // - SceneObjectGroup group = root.ParentGroup; - List newSet = new List(group.Children.Values); - int numChildren = group.Children.Count; - - // If there are prims left in a link set, but the root is - // slated for unlink, we need to do this - // - if (numChildren != 1) + foreach (uint primID in primIds) { - // Unlink the remaining set - // - bool sendEventsToRemainder = true; - if (numChildren > 1) - sendEventsToRemainder = false; - - foreach (SceneObjectPart p in newSet) + SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); + if (part != null) { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); + if (part.LinkNum < 2) // Root or single + rootParts.Add(part); + else + childParts.Add(part); + + SceneObjectGroup group = part.ParentGroup; + if (!affectedGroups.Contains(group)) + affectedGroups.Add(group); } - - // If there is more than one prim remaining, we - // need to re-link - // - if (numChildren > 2) + else { - // Remove old root - // - if (newSet.Contains(root)) - newSet.Remove(root); + m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); + } + } - // Preserve link ordering + foreach (SceneObjectPart child in childParts) + { + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, sendEvents); + } + + foreach (SceneObjectPart root in rootParts) + { + // In most cases, this will run only one time, and the prim + // will be a solo prim + // However, editing linked parts and unlinking may be different + // + SceneObjectGroup group = root.ParentGroup; + List newSet = new List(group.Children.Values); + int numChildren = group.Children.Count; + + // If there are prims left in a link set, but the root is + // slated for unlink, we need to do this + // + if (numChildren != 1) + { + // Unlink the remaining set // - newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + bool sendEventsToRemainder = true; + if (numChildren > 1) + sendEventsToRemainder = false; + + foreach (SceneObjectPart p in newSet) { - return a.LinkNum.CompareTo(b.LinkNum); - }); - - // Determine new root - // - SceneObjectPart newRoot = newSet[0]; - newSet.RemoveAt(0); - - List linkIDs = new List(); - - foreach (SceneObjectPart newChild in newSet) - { - newChild.UpdateFlag = 0; - linkIDs.Add(newChild.LocalId); + if (p != group.RootPart) + group.DelinkFromGroup(p, sendEventsToRemainder); } - LinkObjects(null, newRoot.LocalId, linkIDs); - if (!affectedGroups.Contains(newRoot.ParentGroup)) - affectedGroups.Add(newRoot.ParentGroup); + // If there is more than one prim remaining, we + // need to re-link + // + if (numChildren > 2) + { + // Remove old root + // + if (newSet.Contains(root)) + newSet.Remove(root); + + // Preserve link ordering + // + newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + { + return a.LinkNum.CompareTo(b.LinkNum); + }); + + // Determine new root + // + SceneObjectPart newRoot = newSet[0]; + newSet.RemoveAt(0); + + List linkIDs = new List(); + + foreach (SceneObjectPart newChild in newSet) + { + newChild.UpdateFlag = 0; + linkIDs.Add(newChild.LocalId); + } + + LinkObjects(null, newRoot.LocalId, linkIDs); + if (!affectedGroups.Contains(newRoot.ParentGroup)) + affectedGroups.Add(newRoot.ParentGroup); + } } } - } - // Finally, trigger events in the roots - // - foreach (SceneObjectGroup g in affectedGroups) - { - g.TriggerScriptChangedEvent(Changed.LINK); - g.HasGroupChanged = true; // Persist - g.ScheduleGroupForFullUpdate(); + // Finally, trigger events in the roots + // + foreach (SceneObjectGroup g in affectedGroups) + { + g.TriggerScriptChangedEvent(Changed.LINK); + g.HasGroupChanged = true; // Persist + g.ScheduleGroupForFullUpdate(); + } } } From 5259a32319fd2b27faa3dcd070dece7b428dfd80 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:50:28 +0000 Subject: [PATCH 4/8] Remove extra forced updates. They're not needed for each prim. Really. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6170caa3c5..cb87212672 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2114,14 +2114,14 @@ namespace OpenSim.Region.Framework.Scenes public void LinkToGroup(SceneObjectGroup objectGroup) { // Make sure we have sent any pending unlinks or stuff. - if (objectGroup.RootPart.UpdateFlag > 0) - { - m_log.WarnFormat( - "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", - objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); + //if (objectGroup.RootPart.UpdateFlag > 0) + //{ + // m_log.WarnFormat( + // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", + // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); - objectGroup.RootPart.SendScheduledUpdates(); - } + // objectGroup.RootPart.SendScheduledUpdates(); + //} // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", From f71025aeedf63d5b0ddfe2e18b7d541879db8248 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 01:20:39 +0000 Subject: [PATCH 5/8] Change locking to not mix explicit Monitor.* calls with lock() --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5efe188544..4bdc52cee9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1562,7 +1562,8 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) { - lock (m_updateLock) + Monitor.Enter(m_updateLock); + try { SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); @@ -1617,6 +1618,10 @@ namespace OpenSim.Region.Framework.Scenes } } } + finally + { + Monitor.Exit(m_updateLock); + } } /// @@ -1630,7 +1635,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal void DelinkObjects(List primIds, bool sendEvents) { - lock (m_updateLock) + Monitor.Enter(m_updateLock); + try { List childParts = new List(); List rootParts = new List(); @@ -1737,6 +1743,10 @@ namespace OpenSim.Region.Framework.Scenes g.ScheduleGroupForFullUpdate(); } } + finally + { + Monitor.Exit(m_updateLock); + } } protected internal void MakeObjectSearchable(IClientAPI remoteClient, bool IncludeInSearch, uint localID) From 1a695875a72379f8a8a15ef6818167c443b60494 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 02:00:32 +0000 Subject: [PATCH 6/8] Skip single prims in unlink selections --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4bdc52cee9..18e7b79c0f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1648,14 +1648,17 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); if (part != null) { - if (part.LinkNum < 2) // Root or single - rootParts.Add(part); - else - childParts.Add(part); + if (part.ParentGroup.Children.Count != 1) // Skip single + { + if (part.LinkNum < 2) // Root + rootParts.Add(part); + else + childParts.Add(part); - SceneObjectGroup group = part.ParentGroup; - if (!affectedGroups.Contains(group)) - affectedGroups.Add(group); + SceneObjectGroup group = part.ParentGroup; + if (!affectedGroups.Contains(group)) + affectedGroups.Add(group); + } } else { From 9453c426316e8af97b1280c8e6415d2c051d7284 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 02:15:52 +0000 Subject: [PATCH 7/8] Experimental: Remove explicit property sends --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 18e7b79c0f..f74fd5d93f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1606,17 +1606,17 @@ namespace OpenSim.Region.Framework.Scenes parentGroup.HasGroupChanged = true; parentGroup.ScheduleGroupForFullUpdate(); - if (client != null) - { - parentGroup.GetProperties(client); - } - else - { - foreach (ScenePresence p in GetScenePresences()) - { - parentGroup.GetProperties(p.ControllingClient); - } - } +// if (client != null) +// { +// parentGroup.GetProperties(client); +// } +// else +// { +// foreach (ScenePresence p in GetScenePresences()) +// { +// parentGroup.GetProperties(p.ControllingClient); +// } +// } } finally { From 8d196dbd148f759f9fce1a2f456abfc084fd8f97 Mon Sep 17 00:00:00 2001 From: "Teravus Ovares (Dan Olivares)" Date: Sat, 5 Dec 2009 22:18:00 -0500 Subject: [PATCH 8/8] * Adds Normal to the fields returned by the Physics Raycaster * Fixes recognizing when a sit target is and isn't set. * * 1. Vector3.Zero. * * 2. Orientation: x:0, y:0, z:0, w:1 - ZERO_ROTATION * * (or) Orientation: x:0, y:0, z:0, w:0 - Invalid Quaternion * * (or) Orientation: x:0, y:0, z:1, w:0 - Invalid mapping, some older objects still exist with it --- .../Region/Framework/Scenes/ScenePresence.cs | 24 +++++++++++++++---- .../Region/Physics/Manager/PhysicsScene.cs | 4 ++-- .../OdePlugin/ODERayCastRequestManager.cs | 10 ++++++-- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a3ceecbbe6..24840d4128 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1105,7 +1105,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) { const float POSITION_TOLERANCE = 0.02f; const float VELOCITY_TOLERANCE = 0.02f; @@ -1686,8 +1686,13 @@ namespace OpenSim.Region.Framework.Scenes bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); bool SitTargetisSet = - (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && - avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); + (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && + ( + avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 1f // Valid Zero Rotation quaternion + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point + || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion + ) + )); if (SitTargetisSet && SitTargetUnOccupied) { @@ -1750,7 +1755,7 @@ namespace OpenSim.Region.Framework.Scenes StandUp(); } m_nextSitAnimation = "SIT"; - + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); @@ -1762,12 +1767,23 @@ namespace OpenSim.Region.Framework.Scenes } m_requestedSitTargetID = part.LocalId; //m_requestedSitOffset = offset; + //offset.X += part.Scale.X;// *offset.X; + //offset.Y += part.Scale.Y;// * offset.Y; + //offset.Z += part.Scale.Z;// * offset.Z; + //m_requestedSitOffset = offset; + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); } else { m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); } + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); + } + SendSitResponse(remoteClient, targetID, offset); } diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs index 6d515e9eca..217d307443 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.Physics.Manager { public delegate void physicsCrash(); - public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance); + public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); public abstract class PhysicsScene { @@ -204,7 +204,7 @@ namespace OpenSim.Region.Physics.Manager public virtual void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) { if (retMethod != null) - retMethod(false, Vector3.Zero, 0, 999999999999f); + retMethod(false, Vector3.Zero, 0, 999999999999f, Vector3.Zero); } private class NullPhysicsScene : PhysicsScene diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs index c8ae229187..732e835789 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs @@ -145,6 +145,7 @@ namespace OpenSim.Region.Physics.OdePlugin uint hitConsumerID = 0; float distance = 999999999999f; Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); + Vector3 snormal = Vector3.Zero; // Find closest contact and object. lock (m_contactResults) @@ -157,6 +158,7 @@ namespace OpenSim.Region.Physics.OdePlugin hitConsumerID = cResult.ConsumerID; distance = cResult.Depth; hitYN = true; + snormal = cResult.Normal; } } @@ -165,7 +167,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Return results if (req.callbackMethod != null) - req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance); + req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); } // This is the standard Near. Uses space AABBs to speed up detection. @@ -310,7 +312,8 @@ namespace OpenSim.Region.Physics.OdePlugin collisionresult.ConsumerID = ((OdePrim)p1).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; - + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); } @@ -325,6 +328,8 @@ namespace OpenSim.Region.Physics.OdePlugin collisionresult.ConsumerID = ((OdePrim)p2).m_localID; collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); collisionresult.Depth = contacts[i].depth; + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); lock (m_contactResults) m_contactResults.Add(collisionresult); @@ -358,5 +363,6 @@ namespace OpenSim.Region.Physics.OdePlugin public Vector3 Pos; public float Depth; public uint ConsumerID; + public Vector3 Normal; } }