diff options
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Prioritizer.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 189 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 98 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 205 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 152 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 68 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | 143 |
12 files changed, 600 insertions, 340 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 145f9ed..3a3ec2b 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs | |||
@@ -31,7 +31,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
31 | 31 | ||
32 | public class Prioritizer | 32 | public class Prioritizer |
33 | { | 33 | { |
34 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 34 | // private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
35 | 35 | ||
36 | /// <summary> | 36 | /// <summary> |
37 | /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the | 37 | /// This is added to the priority of all child prims, to make sure that the root prim update is sent to the |
@@ -75,7 +75,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
75 | break; | 75 | break; |
76 | default: | 76 | default: |
77 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | 77 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); |
78 | break; | ||
79 | } | 78 | } |
80 | 79 | ||
81 | // Adjust priority so that root prims are sent to the viewer first. This is especially important for | 80 | // Adjust priority so that root prims are sent to the viewer first. This is especially important for |
@@ -122,9 +121,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
122 | // Use group position for child prims | 121 | // Use group position for child prims |
123 | Vector3 entityPos; | 122 | Vector3 entityPos; |
124 | if (entity is SceneObjectPart) | 123 | if (entity is SceneObjectPart) |
125 | entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | 124 | { |
125 | // Can't use Scene.GetGroupByPrim() here, since the entity may have been delete from the scene | ||
126 | // before its scheduled update was triggered | ||
127 | //entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; | ||
128 | entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition; | ||
129 | } | ||
126 | else | 130 | else |
131 | { | ||
127 | entityPos = entity.AbsolutePosition; | 132 | entityPos = entity.AbsolutePosition; |
133 | } | ||
128 | 134 | ||
129 | return Vector3.DistanceSquared(presencePos, entityPos); | 135 | return Vector3.DistanceSquared(presencePos, entityPos); |
130 | } | 136 | } |
@@ -157,7 +163,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
157 | } | 163 | } |
158 | } | 164 | } |
159 | else | 165 | else |
166 | { | ||
160 | entityPos = entity.AbsolutePosition; | 167 | entityPos = entity.AbsolutePosition; |
168 | } | ||
161 | 169 | ||
162 | if (!presence.IsChildAgent) | 170 | if (!presence.IsChildAgent) |
163 | { | 171 | { |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index ab18c93..8760c84 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -122,7 +122,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
122 | else | 122 | else |
123 | { | 123 | { |
124 | m_log.WarnFormat( | 124 | m_log.WarnFormat( |
125 | "[AGENT INVENTORY]: Agent {1} could not add item {2} {3}", | 125 | "[AGENT INVENTORY]: Agent {0} could not add item {1} {2}", |
126 | AgentID, item.Name, item.ID); | 126 | AgentID, item.Name, item.ID); |
127 | 127 | ||
128 | return; | 128 | return; |
@@ -984,7 +984,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
984 | 984 | ||
985 | private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) | 985 | private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) |
986 | { | 986 | { |
987 | Console.WriteLine("CreateAgentInventoryItemFromTask"); | ||
988 | TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId); | 987 | TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(itemId); |
989 | 988 | ||
990 | if (null == taskItem) | 989 | if (null == taskItem) |
@@ -1055,7 +1054,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1055 | /// <param name="itemID"></param> | 1054 | /// <param name="itemID"></param> |
1056 | public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId) | 1055 | public InventoryItemBase MoveTaskInventoryItem(IClientAPI remoteClient, UUID folderId, SceneObjectPart part, UUID itemId) |
1057 | { | 1056 | { |
1058 | m_log.Info("Adding task inventory"); | 1057 | m_log.DebugFormat( |
1058 | "[PRIM INVENTORY]: Adding item {0} from {1} to folder {2} for {3}", | ||
1059 | itemId, part.Name, folderId, remoteClient.Name); | ||
1060 | |||
1059 | InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId); | 1061 | InventoryItemBase agentItem = CreateAgentInventoryItemFromTask(remoteClient.AgentId, part, itemId); |
1060 | 1062 | ||
1061 | if (agentItem == null) | 1063 | if (agentItem == null) |
@@ -1121,7 +1123,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1121 | /// <see>MoveTaskInventoryItem</see> | 1123 | /// <see>MoveTaskInventoryItem</see> |
1122 | /// </summary> | 1124 | /// </summary> |
1123 | /// <param name="remoteClient"></param> | 1125 | /// <param name="remoteClient"></param> |
1124 | /// <param name="folderID"></param> | 1126 | /// <param name="folderID"> |
1127 | /// The user inventory folder to move (or copy) the item to. If null, then the most | ||
1128 | /// suitable system folder is used (e.g. the Objects folder for objects). If there is no suitable folder, then | ||
1129 | /// the item is placed in the user's root inventory folder | ||
1130 | /// </param> | ||
1125 | /// <param name="part"></param> | 1131 | /// <param name="part"></param> |
1126 | /// <param name="itemID"></param> | 1132 | /// <param name="itemID"></param> |
1127 | public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId) | 1133 | public InventoryItemBase MoveTaskInventoryItem(UUID avatarId, UUID folderId, SceneObjectPart part, UUID itemId) |
@@ -1846,53 +1852,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1846 | } | 1852 | } |
1847 | } | 1853 | } |
1848 | 1854 | ||
1849 | public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) | ||
1850 | { | ||
1851 | SceneObjectGroup objectGroup = grp; | ||
1852 | if (objectGroup != null) | ||
1853 | { | ||
1854 | if (!grp.HasGroupChanged) | ||
1855 | { | ||
1856 | m_log.InfoFormat("[ATTACHMENT]: Save request for {0} which is unchanged", grp.UUID); | ||
1857 | return; | ||
1858 | } | ||
1859 | |||
1860 | m_log.InfoFormat( | ||
1861 | "[ATTACHMENT]: Updating asset for attachment {0}, attachpoint {1}", | ||
1862 | grp.UUID, grp.GetAttachmentPoint()); | ||
1863 | |||
1864 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | ||
1865 | |||
1866 | InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); | ||
1867 | item = InventoryService.GetItem(item); | ||
1868 | |||
1869 | if (item != null) | ||
1870 | { | ||
1871 | AssetBase asset = CreateAsset( | ||
1872 | objectGroup.GetPartName(objectGroup.LocalId), | ||
1873 | objectGroup.GetPartDescription(objectGroup.LocalId), | ||
1874 | (sbyte)AssetType.Object, | ||
1875 | Utils.StringToBytes(sceneObjectXml), | ||
1876 | remoteClient.AgentId); | ||
1877 | AssetService.Store(asset); | ||
1878 | |||
1879 | item.AssetID = asset.FullID; | ||
1880 | item.Description = asset.Description; | ||
1881 | item.Name = asset.Name; | ||
1882 | item.AssetType = asset.Type; | ||
1883 | item.InvType = (int)InventoryType.Object; | ||
1884 | |||
1885 | InventoryService.UpdateItem(item); | ||
1886 | |||
1887 | // this gets called when the agent loggs off! | ||
1888 | if (remoteClient != null) | ||
1889 | { | ||
1890 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
1891 | } | ||
1892 | } | ||
1893 | } | ||
1894 | } | ||
1895 | |||
1896 | public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) | 1855 | public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) |
1897 | { | 1856 | { |
1898 | itemID = UUID.Zero; | 1857 | itemID = UUID.Zero; |
@@ -1998,7 +1957,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1998 | remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | 1957 | remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, |
1999 | RezSelected, RemoveItem, fromTaskID, false); | 1958 | RezSelected, RemoveItem, fromTaskID, false); |
2000 | } | 1959 | } |
2001 | 1960 | ||
2002 | /// <summary> | 1961 | /// <summary> |
2003 | /// Rez an object into the scene from a prim's inventory. | 1962 | /// Rez an object into the scene from a prim's inventory. |
2004 | /// </summary> | 1963 | /// </summary> |
@@ -2013,95 +1972,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
2013 | SceneObjectPart sourcePart, TaskInventoryItem item, | 1972 | SceneObjectPart sourcePart, TaskInventoryItem item, |
2014 | Vector3 pos, Quaternion rot, Vector3 vel, int param) | 1973 | Vector3 pos, Quaternion rot, Vector3 vel, int param) |
2015 | { | 1974 | { |
2016 | // Rez object | 1975 | if (null == item) |
2017 | if (item != null) | 1976 | return null; |
2018 | { | 1977 | |
2019 | UUID ownerID = item.OwnerID; | 1978 | SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); |
2020 | 1979 | ||
2021 | AssetBase rezAsset = AssetService.Get(item.AssetID.ToString()); | 1980 | if (null == group) |
2022 | 1981 | return null; | |
2023 | if (rezAsset != null) | 1982 | |
2024 | { | 1983 | if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) |
2025 | string xmlData = Utils.BytesToString(rezAsset.Data); | 1984 | return null; |
2026 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
2027 | |||
2028 | if (!Permissions.CanRezObject(group.Children.Count, ownerID, pos)) | ||
2029 | { | ||
2030 | return null; | ||
2031 | } | ||
2032 | group.ResetIDs(); | ||
2033 | |||
2034 | AddNewSceneObject(group, true); | ||
2035 | |||
2036 | // we set it's position in world. | ||
2037 | group.AbsolutePosition = pos; | ||
2038 | |||
2039 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); | ||
2040 | |||
2041 | // Since renaming the item in the inventory does not affect the name stored | ||
2042 | // in the serialization, transfer the correct name from the inventory to the | ||
2043 | // object itself before we rez. | ||
2044 | rootPart.Name = item.Name; | ||
2045 | rootPart.Description = item.Description; | ||
2046 | |||
2047 | List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values); | ||
2048 | |||
2049 | group.SetGroup(sourcePart.GroupID, null); | ||
2050 | |||
2051 | if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) | ||
2052 | { | ||
2053 | if (Permissions.PropagatePermissions()) | ||
2054 | { | ||
2055 | foreach (SceneObjectPart part in partList) | ||
2056 | { | ||
2057 | part.EveryoneMask = item.EveryonePermissions; | ||
2058 | part.NextOwnerMask = item.NextPermissions; | ||
2059 | } | ||
2060 | group.ApplyNextOwnerPermissions(); | ||
2061 | } | ||
2062 | } | ||
2063 | |||
2064 | foreach (SceneObjectPart part in partList) | ||
2065 | { | ||
2066 | if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) | ||
2067 | { | ||
2068 | part.LastOwnerID = part.OwnerID; | ||
2069 | part.OwnerID = item.OwnerID; | ||
2070 | part.Inventory.ChangeInventoryOwner(item.OwnerID); | ||
2071 | } | ||
2072 | part.EveryoneMask = item.EveryonePermissions; | ||
2073 | part.NextOwnerMask = item.NextPermissions; | ||
2074 | } | ||
2075 | |||
2076 | rootPart.TrimPermissions(); | ||
2077 | |||
2078 | if (group.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
2079 | { | ||
2080 | group.ClearPartAttachmentData(); | ||
2081 | } | ||
2082 | |||
2083 | group.UpdateGroupRotationR(rot); | ||
2084 | |||
2085 | //group.ApplyPhysics(m_physicalPrim); | ||
2086 | if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) | ||
2087 | { | ||
2088 | group.RootPart.ApplyImpulse((vel * group.GetMass()), false); | ||
2089 | group.Velocity = vel; | ||
2090 | rootPart.ScheduleFullUpdate(); | ||
2091 | } | ||
2092 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); | ||
2093 | rootPart.ScheduleFullUpdate(); | ||
2094 | 1985 | ||
2095 | if (!Permissions.BypassPermissions()) | 1986 | if (!Permissions.BypassPermissions()) |
2096 | { | 1987 | { |
2097 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 1988 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) |
2098 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); | 1989 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); |
2099 | } | ||
2100 | return rootPart.ParentGroup; | ||
2101 | } | ||
2102 | } | 1990 | } |
2103 | 1991 | ||
2104 | return null; | 1992 | AddNewSceneObject(group, true, pos, rot, vel); |
1993 | |||
1994 | // We can only call this after adding the scene object, since the scene object references the scene | ||
1995 | // to find out if scripts should be activated at all. | ||
1996 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); | ||
1997 | |||
1998 | group.ScheduleGroupForFullUpdate(); | ||
1999 | |||
2000 | return group; | ||
2105 | } | 2001 | } |
2106 | 2002 | ||
2107 | public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) | 2003 | public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) |
@@ -2161,7 +2057,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2161 | sog.SetGroup(groupID, remoteClient); | 2057 | sog.SetGroup(groupID, remoteClient); |
2162 | sog.ScheduleGroupForFullUpdate(); | 2058 | sog.ScheduleGroupForFullUpdate(); |
2163 | 2059 | ||
2164 | foreach (SceneObjectPart child in sog.Children.Values) | 2060 | List<SceneObjectPart> partList = null; |
2061 | lock (sog.Children) | ||
2062 | partList = new List<SceneObjectPart>(sog.Children.Values); | ||
2063 | |||
2064 | foreach (SceneObjectPart child in partList) | ||
2165 | child.Inventory.ChangeInventoryOwner(ownerID); | 2065 | child.Inventory.ChangeInventoryOwner(ownerID); |
2166 | } | 2066 | } |
2167 | else | 2067 | else |
@@ -2171,8 +2071,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2171 | 2071 | ||
2172 | if (sog.GroupID != groupID) | 2072 | if (sog.GroupID != groupID) |
2173 | continue; | 2073 | continue; |
2074 | |||
2075 | List<SceneObjectPart> partList = null; | ||
2076 | lock (sog.Children) | ||
2077 | partList = new List<SceneObjectPart>(sog.Children.Values); | ||
2174 | 2078 | ||
2175 | foreach (SceneObjectPart child in sog.Children.Values) | 2079 | foreach (SceneObjectPart child in partList) |
2176 | { | 2080 | { |
2177 | child.LastOwnerID = child.OwnerID; | 2081 | child.LastOwnerID = child.OwnerID; |
2178 | child.Inventory.ChangeInventoryOwner(groupID); | 2082 | child.Inventory.ChangeInventoryOwner(groupID); |
@@ -2180,8 +2084,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2180 | 2084 | ||
2181 | sog.SetOwnerId(groupID); | 2085 | sog.SetOwnerId(groupID); |
2182 | sog.ApplyNextOwnerPermissions(); | 2086 | sog.ApplyNextOwnerPermissions(); |
2183 | } | 2087 | } |
2184 | |||
2185 | } | 2088 | } |
2186 | 2089 | ||
2187 | foreach (uint localID in localIDs) | 2090 | foreach (uint localID in localIDs) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index e25b1f1..c511774 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -156,21 +156,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
156 | } | 156 | } |
157 | break; | 157 | break; |
158 | } | 158 | } |
159 | else | 159 | else |
160 | { | 160 | { |
161 | // We also need to check the children of this prim as they | 161 | // We also need to check the children of this prim as they |
162 | // can be selected as well and send property information | 162 | // can be selected as well and send property information |
163 | bool foundPrim = false; | 163 | bool foundPrim = false; |
164 | foreach (KeyValuePair<UUID, SceneObjectPart> child in ((SceneObjectGroup) ent).Children) | 164 | |
165 | { | 165 | SceneObjectGroup sog = ent as SceneObjectGroup; |
166 | if (child.Value.LocalId == primLocalID) | 166 | |
167 | { | 167 | List<SceneObjectPart> partList = null; |
168 | child.Value.GetProperties(remoteClient); | 168 | lock (sog.Children) |
169 | foundPrim = true; | 169 | partList = new List<SceneObjectPart>(sog.Children.Values); |
170 | break; | 170 | |
171 | } | 171 | foreach (SceneObjectPart part in partList) |
172 | } | 172 | { |
173 | if (foundPrim) break; | 173 | if (part.LocalId == primLocalID) |
174 | { | ||
175 | part.GetProperties(remoteClient); | ||
176 | foundPrim = true; | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | |||
181 | if (foundPrim) | ||
182 | break; | ||
174 | } | 183 | } |
175 | } | 184 | } |
176 | } | 185 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 736b696..9fea2a0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -42,7 +42,6 @@ using OpenMetaverse.Imaging; | |||
42 | using OpenSim.Framework; | 42 | using OpenSim.Framework; |
43 | using OpenSim.Services.Interfaces; | 43 | using OpenSim.Services.Interfaces; |
44 | using OpenSim.Framework.Communications; | 44 | using OpenSim.Framework.Communications; |
45 | |||
46 | using OpenSim.Framework.Console; | 45 | using OpenSim.Framework.Console; |
47 | using OpenSim.Region.Framework.Interfaces; | 46 | using OpenSim.Region.Framework.Interfaces; |
48 | using OpenSim.Region.Framework.Scenes.Scripting; | 47 | using OpenSim.Region.Framework.Scenes.Scripting; |
@@ -399,6 +398,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
399 | private bool m_firstHeartbeat = true; | 398 | private bool m_firstHeartbeat = true; |
400 | 399 | ||
401 | private object m_deleting_scene_object = new object(); | 400 | private object m_deleting_scene_object = new object(); |
401 | private object m_cleaningAttachments = new object(); | ||
402 | 402 | ||
403 | // the minimum time that must elapse before a changed object will be considered for persisted | 403 | // the minimum time that must elapse before a changed object will be considered for persisted |
404 | public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; | 404 | public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; |
@@ -1790,8 +1790,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1790 | 1790 | ||
1791 | if (group.RootPart == null) | 1791 | if (group.RootPart == null) |
1792 | { | 1792 | { |
1793 | m_log.ErrorFormat("[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", | 1793 | m_log.ErrorFormat( |
1794 | group.Children == null ? 0 : group.Children.Count); | 1794 | "[SCENE]: Found a SceneObjectGroup with m_rootPart == null and {0} children", |
1795 | group.Children == null ? 0 : group.PrimCount); | ||
1795 | } | 1796 | } |
1796 | 1797 | ||
1797 | AddRestoredSceneObject(group, true, true); | 1798 | AddRestoredSceneObject(group, true, true); |
@@ -2050,7 +2051,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2050 | public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) | 2051 | public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) |
2051 | { | 2052 | { |
2052 | return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 2053 | return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
2053 | } | 2054 | } |
2055 | |||
2056 | /// <summary> | ||
2057 | /// Add a newly created object to the scene. | ||
2058 | /// </summary> | ||
2059 | /// | ||
2060 | /// This method does not send updates to the client - callers need to handle this themselves. | ||
2061 | /// <param name="sceneObject"></param> | ||
2062 | /// <param name="attachToBackup"></param> | ||
2063 | /// <param name="pos">Position of the object</param> | ||
2064 | /// <param name="rot">Rotation of the object</param> | ||
2065 | /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> | ||
2066 | /// <returns></returns> | ||
2067 | public bool AddNewSceneObject( | ||
2068 | SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) | ||
2069 | { | ||
2070 | return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, pos, rot, vel); | ||
2071 | } | ||
2054 | 2072 | ||
2055 | /// <summary> | 2073 | /// <summary> |
2056 | /// Delete every object from the scene. This does not include attachments worn by avatars. | 2074 | /// Delete every object from the scene. This does not include attachments worn by avatars. |
@@ -2113,7 +2131,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
2113 | group.RemoveScriptInstances(true); | 2131 | group.RemoveScriptInstances(true); |
2114 | } | 2132 | } |
2115 | 2133 | ||
2116 | foreach (SceneObjectPart part in group.Children.Values) | 2134 | List<SceneObjectPart> partList = null; |
2135 | lock (group.Children) | ||
2136 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
2137 | |||
2138 | foreach (SceneObjectPart part in partList) | ||
2117 | { | 2139 | { |
2118 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) | 2140 | if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) |
2119 | { | 2141 | { |
@@ -2125,6 +2147,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2125 | part.PhysActor = null; | 2147 | part.PhysActor = null; |
2126 | } | 2148 | } |
2127 | } | 2149 | } |
2150 | |||
2128 | // if (rootPart.PhysActor != null) | 2151 | // if (rootPart.PhysActor != null) |
2129 | // { | 2152 | // { |
2130 | // PhysicsScene.RemovePrim(rootPart.PhysActor); | 2153 | // PhysicsScene.RemovePrim(rootPart.PhysActor); |
@@ -2481,14 +2504,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2481 | 2504 | ||
2482 | // Force allocation of new LocalId | 2505 | // Force allocation of new LocalId |
2483 | // | 2506 | // |
2484 | foreach (SceneObjectPart p in sceneObject.Children.Values) | 2507 | lock (sceneObject.Children) |
2485 | p.LocalId = 0; | 2508 | { |
2509 | foreach (SceneObjectPart p in sceneObject.Children.Values) | ||
2510 | p.LocalId = 0; | ||
2511 | } | ||
2486 | 2512 | ||
2487 | if (sceneObject.IsAttachmentCheckFull()) // Attachment | 2513 | if (sceneObject.IsAttachmentCheckFull()) // Attachment |
2488 | { | 2514 | { |
2489 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); | 2515 | sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez); |
2490 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); | 2516 | sceneObject.RootPart.AddFlag(PrimFlags.Phantom); |
2491 | |||
2492 | 2517 | ||
2493 | // Don't sent a full update here because this will cause full updates to be sent twice for | 2518 | // Don't sent a full update here because this will cause full updates to be sent twice for |
2494 | // attachments on region crossings, resulting in viewer glitches. | 2519 | // attachments on region crossings, resulting in viewer glitches. |
@@ -2502,7 +2527,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2502 | 2527 | ||
2503 | if (sp != null) | 2528 | if (sp != null) |
2504 | { | 2529 | { |
2505 | |||
2506 | SceneObjectGroup grp = sceneObject; | 2530 | SceneObjectGroup grp = sceneObject; |
2507 | 2531 | ||
2508 | m_log.DebugFormat( | 2532 | m_log.DebugFormat( |
@@ -3210,6 +3234,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3210 | m_log.Debug("[Scene] Beginning OnRemovePresence"); | 3234 | m_log.Debug("[Scene] Beginning OnRemovePresence"); |
3211 | m_eventManager.TriggerOnRemovePresence(agentID); | 3235 | m_eventManager.TriggerOnRemovePresence(agentID); |
3212 | m_log.Debug("[Scene] Finished OnRemovePresence"); | 3236 | m_log.Debug("[Scene] Finished OnRemovePresence"); |
3237 | |||
3213 | ForEachClient( | 3238 | ForEachClient( |
3214 | delegate(IClientAPI client) | 3239 | delegate(IClientAPI client) |
3215 | { | 3240 | { |
@@ -3245,6 +3270,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3245 | } | 3270 | } |
3246 | m_log.Debug("[Scene] Done. Firing RemoveCircuit"); | 3271 | m_log.Debug("[Scene] Done. Firing RemoveCircuit"); |
3247 | m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); | 3272 | m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); |
3273 | CleanDroppedAttachments(); | ||
3248 | m_log.Debug("[Scene] The avatar has left the building"); | 3274 | m_log.Debug("[Scene] The avatar has left the building"); |
3249 | //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); | 3275 | //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); |
3250 | //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); | 3276 | //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); |
@@ -3443,6 +3469,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3443 | 3469 | ||
3444 | if (vialogin) | 3470 | if (vialogin) |
3445 | { | 3471 | { |
3472 | CleanDroppedAttachments(); | ||
3473 | |||
3446 | if (TestBorderCross(agent.startpos, Cardinals.E)) | 3474 | if (TestBorderCross(agent.startpos, Cardinals.E)) |
3447 | { | 3475 | { |
3448 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); | 3476 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); |
@@ -3694,18 +3722,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3694 | return true; | 3722 | return true; |
3695 | } | 3723 | } |
3696 | 3724 | ||
3697 | private ILandObject GetParcelAtPoint(float x, float y) | ||
3698 | { | ||
3699 | foreach (var parcel in AllParcels()) | ||
3700 | { | ||
3701 | if (parcel.ContainsPoint((int)x,(int)y)) | ||
3702 | { | ||
3703 | return parcel; | ||
3704 | } | ||
3705 | } | ||
3706 | return null; | ||
3707 | } | ||
3708 | |||
3709 | /// <summary> | 3725 | /// <summary> |
3710 | /// Update an AgentCircuitData object with new information | 3726 | /// Update an AgentCircuitData object with new information |
3711 | /// </summary> | 3727 | /// </summary> |
@@ -5041,5 +5057,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
5041 | throw new Exception(error); | 5057 | throw new Exception(error); |
5042 | } | 5058 | } |
5043 | } | 5059 | } |
5060 | |||
5061 | public void CleanDroppedAttachments() | ||
5062 | { | ||
5063 | List<SceneObjectGroup> objectsToDelete = | ||
5064 | new List<SceneObjectGroup>(); | ||
5065 | |||
5066 | lock (m_cleaningAttachments) | ||
5067 | { | ||
5068 | ForEachSOG(delegate (SceneObjectGroup grp) | ||
5069 | { | ||
5070 | if (grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) | ||
5071 | { | ||
5072 | UUID agentID = grp.OwnerID; | ||
5073 | if (agentID == UUID.Zero) | ||
5074 | { | ||
5075 | objectsToDelete.Add(grp); | ||
5076 | return; | ||
5077 | } | ||
5078 | |||
5079 | ScenePresence sp = GetScenePresence(agentID); | ||
5080 | if (sp == null) | ||
5081 | { | ||
5082 | objectsToDelete.Add(grp); | ||
5083 | return; | ||
5084 | } | ||
5085 | } | ||
5086 | }); | ||
5087 | } | ||
5088 | |||
5089 | if (objectsToDelete.Count > 0) | ||
5090 | { | ||
5091 | m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count); | ||
5092 | foreach (SceneObjectGroup grp in objectsToDelete) | ||
5093 | { | ||
5094 | m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); | ||
5095 | DeleteSceneObject(grp, true); | ||
5096 | } | ||
5097 | m_log.Debug("[SCENE]: Finished dropped attachment deletion"); | ||
5098 | } | ||
5099 | } | ||
5044 | } | 5100 | } |
5045 | } | 5101 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 59e4037..1293d5d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | |||
@@ -70,7 +70,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
70 | /// <summary> | 70 | /// <summary> |
71 | /// A user will arrive shortly, set up appropriate credentials so it can connect | 71 | /// A user will arrive shortly, set up appropriate credentials so it can connect |
72 | /// </summary> | 72 | /// </summary> |
73 | public event ExpectUserDelegate OnExpectUser; | 73 | // public event ExpectUserDelegate OnExpectUser; |
74 | 74 | ||
75 | /// <summary> | 75 | /// <summary> |
76 | /// A Prim will arrive shortly | 76 | /// A Prim will arrive shortly |
@@ -80,7 +80,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
80 | /// <summary> | 80 | /// <summary> |
81 | /// A new prim has arrived | 81 | /// A new prim has arrived |
82 | /// </summary> | 82 | /// </summary> |
83 | public event PrimCrossing OnPrimCrossingIntoRegion; | 83 | // public event PrimCrossing OnPrimCrossingIntoRegion; |
84 | 84 | ||
85 | ///// <summary> | 85 | ///// <summary> |
86 | ///// A New Region is up and available | 86 | ///// A New Region is up and available |
@@ -90,7 +90,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
90 | /// <summary> | 90 | /// <summary> |
91 | /// We have a child agent for this avatar and we're getting a status update about it | 91 | /// We have a child agent for this avatar and we're getting a status update about it |
92 | /// </summary> | 92 | /// </summary> |
93 | public event ChildAgentUpdate OnChildAgentUpdate; | 93 | // public event ChildAgentUpdate OnChildAgentUpdate; |
94 | //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; | 94 | //public event RemoveKnownRegionsFromAvatarList OnRemoveKnownRegionFromAvatar; |
95 | 95 | ||
96 | /// <summary> | 96 | /// <summary> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 94ec534..b86a564 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
104 | 104 | ||
105 | protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); | 105 | protected internal Dictionary<uint, SceneObjectGroup> SceneObjectGroupsByLocalID = new Dictionary<uint, SceneObjectGroup>(); |
106 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); | 106 | protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); |
107 | private readonly Object m_dictionary_lock = new Object(); | ||
108 | 107 | ||
109 | private Object m_updateLock = new Object(); | 108 | private Object m_updateLock = new Object(); |
110 | 109 | ||
@@ -150,11 +149,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
150 | m_scenePresencesLock.ExitWriteLock(); | 149 | m_scenePresencesLock.ExitWriteLock(); |
151 | } | 150 | } |
152 | 151 | ||
153 | lock (m_dictionary_lock) | 152 | lock (SceneObjectGroupsByFullID) |
154 | { | ||
155 | SceneObjectGroupsByFullID.Clear(); | 153 | SceneObjectGroupsByFullID.Clear(); |
154 | lock (SceneObjectGroupsByLocalID) | ||
156 | SceneObjectGroupsByLocalID.Clear(); | 155 | SceneObjectGroupsByLocalID.Clear(); |
157 | } | ||
158 | 156 | ||
159 | Entities.Clear(); | 157 | Entities.Clear(); |
160 | } | 158 | } |
@@ -314,6 +312,42 @@ namespace OpenSim.Region.Framework.Scenes | |||
314 | 312 | ||
315 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); | 313 | return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); |
316 | } | 314 | } |
315 | |||
316 | /// <summary> | ||
317 | /// Add a newly created object to the scene. | ||
318 | /// </summary> | ||
319 | /// | ||
320 | /// This method does not send updates to the client - callers need to handle this themselves. | ||
321 | /// <param name="sceneObject"></param> | ||
322 | /// <param name="attachToBackup"></param> | ||
323 | /// <param name="pos">Position of the object</param> | ||
324 | /// <param name="rot">Rotation of the object</param> | ||
325 | /// <param name="vel">Velocity of the object. This parameter only has an effect if the object is physical</param> | ||
326 | /// <returns></returns> | ||
327 | public bool AddNewSceneObject( | ||
328 | SceneObjectGroup sceneObject, bool attachToBackup, Vector3 pos, Quaternion rot, Vector3 vel) | ||
329 | { | ||
330 | AddNewSceneObject(sceneObject, true, false); | ||
331 | |||
332 | // we set it's position in world. | ||
333 | sceneObject.AbsolutePosition = pos; | ||
334 | |||
335 | if (sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) | ||
336 | { | ||
337 | sceneObject.ClearPartAttachmentData(); | ||
338 | } | ||
339 | |||
340 | sceneObject.UpdateGroupRotationR(rot); | ||
341 | |||
342 | //group.ApplyPhysics(m_physicalPrim); | ||
343 | if (sceneObject.RootPart.PhysActor != null && sceneObject.RootPart.PhysActor.IsPhysical && vel != Vector3.Zero) | ||
344 | { | ||
345 | sceneObject.RootPart.ApplyImpulse((vel * sceneObject.GetMass()), false); | ||
346 | sceneObject.Velocity = vel; | ||
347 | } | ||
348 | |||
349 | return true; | ||
350 | } | ||
317 | 351 | ||
318 | /// <summary> | 352 | /// <summary> |
319 | /// Add an object to the scene. This will both update the scene, and send information about the | 353 | /// Add an object to the scene. This will both update the scene, and send information about the |
@@ -350,50 +384,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", | 384 | // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", |
351 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); | 385 | // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); |
352 | 386 | ||
353 | if (m_parentScene.m_clampPrimSize) | 387 | lock (sceneObject.Children) |
354 | { | 388 | { |
355 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 389 | if (m_parentScene.m_clampPrimSize) |
356 | { | 390 | { |
357 | Vector3 scale = part.Shape.Scale; | 391 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
358 | 392 | { | |
359 | if (scale.X > m_parentScene.m_maxNonphys) | 393 | Vector3 scale = part.Shape.Scale; |
360 | scale.X = m_parentScene.m_maxNonphys; | 394 | |
361 | if (scale.Y > m_parentScene.m_maxNonphys) | 395 | if (scale.X > m_parentScene.m_maxNonphys) |
362 | scale.Y = m_parentScene.m_maxNonphys; | 396 | scale.X = m_parentScene.m_maxNonphys; |
363 | if (scale.Z > m_parentScene.m_maxNonphys) | 397 | if (scale.Y > m_parentScene.m_maxNonphys) |
364 | scale.Z = m_parentScene.m_maxNonphys; | 398 | scale.Y = m_parentScene.m_maxNonphys; |
365 | 399 | if (scale.Z > m_parentScene.m_maxNonphys) | |
366 | part.Shape.Scale = scale; | 400 | scale.Z = m_parentScene.m_maxNonphys; |
401 | |||
402 | part.Shape.Scale = scale; | ||
403 | } | ||
367 | } | 404 | } |
405 | |||
406 | m_numPrim += sceneObject.Children.Count; | ||
368 | } | 407 | } |
369 | 408 | ||
370 | sceneObject.AttachToScene(m_parentScene); | 409 | sceneObject.AttachToScene(m_parentScene); |
371 | 410 | ||
372 | if (sendClientUpdates) | 411 | if (sendClientUpdates) |
373 | sceneObject.ScheduleGroupForFullUpdate(); | 412 | sceneObject.ScheduleGroupForFullUpdate(); |
374 | 413 | ||
375 | Entities.Add(sceneObject); | 414 | Entities.Add(sceneObject); |
376 | m_numPrim += sceneObject.Children.Count; | ||
377 | 415 | ||
378 | if (attachToBackup) | 416 | if (attachToBackup) |
379 | { | ||
380 | sceneObject.AttachToBackup(); | 417 | sceneObject.AttachToBackup(); |
381 | } | ||
382 | 418 | ||
383 | if (OnObjectCreate != null) | 419 | if (OnObjectCreate != null) |
384 | { | ||
385 | OnObjectCreate(sceneObject); | 420 | OnObjectCreate(sceneObject); |
386 | } | ||
387 | 421 | ||
388 | lock (m_dictionary_lock) | 422 | lock (SceneObjectGroupsByFullID) |
389 | { | 423 | { |
390 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; | 424 | SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; |
391 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
392 | foreach (SceneObjectPart part in sceneObject.Children.Values) | 425 | foreach (SceneObjectPart part in sceneObject.Children.Values) |
393 | { | ||
394 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; | 426 | SceneObjectGroupsByFullID[part.UUID] = sceneObject; |
427 | } | ||
428 | |||
429 | lock (SceneObjectGroupsByLocalID) | ||
430 | { | ||
431 | SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; | ||
432 | foreach (SceneObjectPart part in sceneObject.Children.Values) | ||
395 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; | 433 | SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; |
396 | } | ||
397 | } | 434 | } |
398 | } | 435 | } |
399 | 436 | ||
@@ -408,24 +445,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
408 | { | 445 | { |
409 | if (Entities.ContainsKey(uuid)) | 446 | if (Entities.ContainsKey(uuid)) |
410 | { | 447 | { |
448 | SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; | ||
449 | |||
411 | if (!resultOfObjectLinked) | 450 | if (!resultOfObjectLinked) |
412 | { | 451 | { |
413 | m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; | 452 | m_numPrim -= grp.PrimCount; |
414 | 453 | ||
415 | if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 454 | if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) |
416 | { | 455 | RemovePhysicalPrim(grp.PrimCount); |
417 | RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); | ||
418 | } | ||
419 | } | 456 | } |
420 | 457 | ||
421 | if (OnObjectRemove != null) | 458 | if (OnObjectRemove != null) |
422 | OnObjectRemove(Entities[uuid]); | 459 | OnObjectRemove(Entities[uuid]); |
423 | 460 | ||
424 | lock (m_dictionary_lock) | 461 | lock (SceneObjectGroupsByFullID) |
425 | { | 462 | { |
426 | SceneObjectGroupsByFullID.Remove(uuid); | 463 | foreach (SceneObjectPart part in grp.Children.Values) |
427 | SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); | 464 | SceneObjectGroupsByFullID.Remove(part.UUID); |
465 | SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); | ||
428 | } | 466 | } |
467 | lock (SceneObjectGroupsByLocalID) | ||
468 | { | ||
469 | foreach (SceneObjectPart part in grp.Children.Values) | ||
470 | SceneObjectGroupsByLocalID.Remove(part.LocalId); | ||
471 | SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); | ||
472 | } | ||
473 | |||
429 | Entities.Remove(uuid); | 474 | Entities.Remove(uuid); |
430 | //SceneObjectGroup part; | 475 | //SceneObjectGroup part; |
431 | //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) | 476 | //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) |
@@ -884,7 +929,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
884 | { | 929 | { |
885 | if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) | 930 | if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) |
886 | { | 931 | { |
887 | return sog; | 932 | if (sog.HasChildPrim(localID)) |
933 | return sog; | ||
934 | SceneObjectGroupsByLocalID.Remove(localID); | ||
888 | } | 935 | } |
889 | } | 936 | } |
890 | 937 | ||
@@ -920,7 +967,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | { | 967 | { |
921 | if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) | 968 | if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) |
922 | { | 969 | { |
923 | return sog; | 970 | lock (sog.Children) |
971 | { | ||
972 | if (sog.Children.ContainsKey(fullID)) | ||
973 | return sog; | ||
974 | } | ||
975 | |||
976 | SceneObjectGroupsByFullID.Remove(fullID); | ||
924 | } | 977 | } |
925 | } | 978 | } |
926 | 979 | ||
@@ -1087,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1087 | /// <param name="action"></param> | 1140 | /// <param name="action"></param> |
1088 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1141 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1089 | { | 1142 | { |
1090 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1143 | List<EntityBase> objlist = Entities.GetAllByType<SceneObjectGroup>(); |
1091 | foreach (SceneObjectGroup obj in objlist) | 1144 | foreach (EntityBase ent in objlist) |
1092 | { | 1145 | { |
1146 | SceneObjectGroup obj = (SceneObjectGroup)ent; | ||
1147 | |||
1093 | try | 1148 | try |
1094 | { | 1149 | { |
1095 | action(obj); | 1150 | action(obj); |
@@ -1293,37 +1348,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1293 | /// <param name="localID"></param> | 1348 | /// <param name="localID"></param> |
1294 | /// <param name="pos"></param> | 1349 | /// <param name="pos"></param> |
1295 | /// <param name="remoteClient"></param> | 1350 | /// <param name="remoteClient"></param> |
1296 | protected internal void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) | 1351 | public void UpdatePrimPosition(uint localID, Vector3 pos, IClientAPI remoteClient) |
1297 | { | 1352 | { |
1298 | SceneObjectGroup group = GetGroupByPrim(localID); | 1353 | SceneObjectGroup group = GetGroupByPrim(localID); |
1354 | |||
1299 | if (group != null) | 1355 | if (group != null) |
1300 | { | 1356 | { |
1301 | |||
1302 | // Vector3 oldPos = group.AbsolutePosition; | ||
1303 | if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) | 1357 | if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) |
1304 | { | 1358 | { |
1305 | 1359 | if (m_parentScene.AttachmentsModule != null) | |
1306 | // If this is an attachment, then we need to save the modified | 1360 | m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos); |
1307 | // object back into the avatar's inventory. First we save the | ||
1308 | // attachment point information, then we update the relative | ||
1309 | // positioning (which caused this method to get driven in the | ||
1310 | // first place. Then we have to mark the object as NOT an | ||
1311 | // attachment. This is necessary in order to correctly save | ||
1312 | // and retrieve GroupPosition information for the attachment. | ||
1313 | // Then we save the asset back into the appropriate inventory | ||
1314 | // entry. Finally, we restore the object's attachment status. | ||
1315 | |||
1316 | byte attachmentPoint = group.GetAttachmentPoint(); | ||
1317 | group.UpdateGroupPosition(pos); | ||
1318 | group.RootPart.IsAttachment = false; | ||
1319 | group.AbsolutePosition = group.RootPart.AttachedPos; | ||
1320 | m_parentScene.UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); | ||
1321 | group.SetAttachmentPoint(attachmentPoint); | ||
1322 | |||
1323 | } | 1361 | } |
1324 | else | 1362 | else |
1325 | { | 1363 | { |
1326 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) | 1364 | if (m_parentScene.Permissions.CanMoveObject(group.UUID, remoteClient.AgentId) |
1365 | && m_parentScene.Permissions.CanObjectEntry(group.UUID, false, pos)) | ||
1327 | { | 1366 | { |
1328 | group.UpdateGroupPosition(pos); | 1367 | group.UpdateGroupPosition(pos); |
1329 | } | 1368 | } |
@@ -1332,14 +1371,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1332 | } | 1371 | } |
1333 | 1372 | ||
1334 | /// <summary> | 1373 | /// <summary> |
1335 | /// | 1374 | /// Update the texture entry of the given prim. |
1336 | /// </summary> | 1375 | /// </summary> |
1376 | /// | ||
1377 | /// A texture entry is an object that contains details of all the textures of the prim's face. In this case, | ||
1378 | /// the texture is given in its byte serialized form. | ||
1379 | /// | ||
1337 | /// <param name="localID"></param> | 1380 | /// <param name="localID"></param> |
1338 | /// <param name="texture"></param> | 1381 | /// <param name="texture"></param> |
1339 | /// <param name="remoteClient"></param> | 1382 | /// <param name="remoteClient"></param> |
1340 | protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) | 1383 | protected internal void UpdatePrimTexture(uint localID, byte[] texture, IClientAPI remoteClient) |
1341 | { | 1384 | { |
1342 | SceneObjectGroup group = GetGroupByPrim(localID); | 1385 | SceneObjectGroup group = GetGroupByPrim(localID); |
1386 | |||
1343 | if (group != null) | 1387 | if (group != null) |
1344 | { | 1388 | { |
1345 | if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) | 1389 | if (m_parentScene.Permissions.CanEditObject(group.UUID,remoteClient.AgentId)) |
@@ -1630,7 +1674,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1630 | { | 1674 | { |
1631 | if (part != null) | 1675 | if (part != null) |
1632 | { | 1676 | { |
1633 | if (part.ParentGroup.Children.Count != 1) // Skip single | 1677 | if (part.ParentGroup.PrimCount != 1) // Skip single |
1634 | { | 1678 | { |
1635 | if (part.LinkNum < 2) // Root | 1679 | if (part.LinkNum < 2) // Root |
1636 | rootParts.Add(part); | 1680 | rootParts.Add(part); |
@@ -1669,8 +1713,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1669 | // However, editing linked parts and unlinking may be different | 1713 | // However, editing linked parts and unlinking may be different |
1670 | // | 1714 | // |
1671 | SceneObjectGroup group = root.ParentGroup; | 1715 | SceneObjectGroup group = root.ParentGroup; |
1672 | List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values); | 1716 | |
1673 | int numChildren = group.Children.Count; | 1717 | List<SceneObjectPart> newSet = null; |
1718 | int numChildren = -1; | ||
1719 | |||
1720 | lock (group.Children) | ||
1721 | { | ||
1722 | newSet = new List<SceneObjectPart>(group.Children.Values); | ||
1723 | numChildren = group.PrimCount; | ||
1724 | } | ||
1674 | 1725 | ||
1675 | // If there are prims left in a link set, but the root is | 1726 | // If there are prims left in a link set, but the root is |
1676 | // slated for unlink, we need to do this | 1727 | // slated for unlink, we need to do this |
@@ -1722,8 +1773,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1722 | SceneObjectPart newRoot = newSet[0]; | 1773 | SceneObjectPart newRoot = newSet[0]; |
1723 | newSet.RemoveAt(0); | 1774 | newSet.RemoveAt(0); |
1724 | 1775 | ||
1725 | List<uint> linkIDs = new List<uint>(); | ||
1726 | |||
1727 | foreach (SceneObjectPart newChild in newSet) | 1776 | foreach (SceneObjectPart newChild in newSet) |
1728 | newChild.UpdateFlag = 0; | 1777 | newChild.UpdateFlag = 0; |
1729 | 1778 | ||
@@ -1760,12 +1809,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
1760 | { | 1809 | { |
1761 | if (ent is SceneObjectGroup) | 1810 | if (ent is SceneObjectGroup) |
1762 | { | 1811 | { |
1763 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in ((SceneObjectGroup)ent).Children) | 1812 | SceneObjectGroup sog = ent as SceneObjectGroup; |
1813 | |||
1814 | lock (sog.Children) | ||
1764 | { | 1815 | { |
1765 | if (subent.Value.LocalId == localID) | 1816 | foreach (KeyValuePair<UUID, SceneObjectPart> subent in sog.Children) |
1766 | { | 1817 | { |
1767 | objid = subent.Key; | 1818 | if (subent.Value.LocalId == localID) |
1768 | obj = subent.Value; | 1819 | { |
1820 | objid = subent.Key; | ||
1821 | obj = subent.Value; | ||
1822 | } | ||
1769 | } | 1823 | } |
1770 | } | 1824 | } |
1771 | } | 1825 | } |
@@ -1830,7 +1884,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1830 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); | 1884 | SceneObjectGroup original = GetGroupByPrim(originalPrimID); |
1831 | if (original != null) | 1885 | if (original != null) |
1832 | { | 1886 | { |
1833 | if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) | 1887 | if (m_parentScene.Permissions.CanDuplicateObject( |
1888 | original.PrimCount, original.UUID, AgentID, original.AbsolutePosition)) | ||
1834 | { | 1889 | { |
1835 | SceneObjectGroup copy = original.Copy(true); | 1890 | SceneObjectGroup copy = original.Copy(true); |
1836 | copy.AbsolutePosition = copy.AbsolutePosition + offset; | 1891 | copy.AbsolutePosition = copy.AbsolutePosition + offset; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9b66fad..5a586d4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -360,7 +360,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
360 | /// </summary> | 360 | /// </summary> |
361 | public int PrimCount | 361 | public int PrimCount |
362 | { | 362 | { |
363 | get { return m_parts.Count; } | 363 | get { lock (m_parts) { return m_parts.Count; } } |
364 | } | 364 | } |
365 | 365 | ||
366 | protected Quaternion m_rotation = Quaternion.Identity; | 366 | protected Quaternion m_rotation = Quaternion.Identity; |
@@ -398,6 +398,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
398 | 398 | ||
399 | /// <value> | 399 | /// <value> |
400 | /// The parts of this scene object group. You must lock this property before using it. | 400 | /// The parts of this scene object group. You must lock this property before using it. |
401 | /// If you're doing anything other than reading values, please take a copy of the values rather than locking | ||
402 | /// the dictionary for the entirety of the operation. This increases liveness and reduces the danger of deadlock | ||
403 | /// If you want to know the number of children, consider using the PrimCount property instead | ||
401 | /// </value> | 404 | /// </value> |
402 | public Dictionary<UUID, SceneObjectPart> Children | 405 | public Dictionary<UUID, SceneObjectPart> Children |
403 | { | 406 | { |
@@ -521,7 +524,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
521 | public override UUID UUID | 524 | public override UUID UUID |
522 | { | 525 | { |
523 | get { return m_rootPart.UUID; } | 526 | get { return m_rootPart.UUID; } |
524 | set { m_rootPart.UUID = value; } | 527 | set |
528 | { | ||
529 | m_rootPart.UUID = value; | ||
530 | |||
531 | lock (m_parts) | ||
532 | { | ||
533 | m_parts.Remove(m_rootPart.UUID); | ||
534 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
535 | } | ||
536 | } | ||
525 | } | 537 | } |
526 | 538 | ||
527 | public UUID OwnerID | 539 | public UUID OwnerID |
@@ -742,21 +754,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
742 | if (m_rootPart.LocalId == 0) | 754 | if (m_rootPart.LocalId == 0) |
743 | m_rootPart.LocalId = m_scene.AllocateLocalId(); | 755 | m_rootPart.LocalId = m_scene.AllocateLocalId(); |
744 | 756 | ||
745 | // No need to lock here since the object isn't yet in a scene | 757 | lock (m_parts) |
746 | foreach (SceneObjectPart part in m_parts.Values) | ||
747 | { | 758 | { |
748 | if (Object.ReferenceEquals(part, m_rootPart)) | 759 | foreach (SceneObjectPart part in m_parts.Values) |
749 | { | ||
750 | continue; | ||
751 | } | ||
752 | |||
753 | if (part.LocalId == 0) | ||
754 | { | 760 | { |
755 | part.LocalId = m_scene.AllocateLocalId(); | 761 | if (Object.ReferenceEquals(part, m_rootPart)) |
762 | { | ||
763 | continue; | ||
764 | } | ||
765 | |||
766 | if (part.LocalId == 0) | ||
767 | { | ||
768 | part.LocalId = m_scene.AllocateLocalId(); | ||
769 | } | ||
770 | |||
771 | part.ParentID = m_rootPart.LocalId; | ||
772 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
756 | } | 773 | } |
757 | |||
758 | part.ParentID = m_rootPart.LocalId; | ||
759 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | ||
760 | } | 774 | } |
761 | 775 | ||
762 | ApplyPhysics(m_scene.m_physicalPrim); | 776 | ApplyPhysics(m_scene.m_physicalPrim); |
@@ -1238,9 +1252,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1238 | m_rootPart.AttachedAvatar = agentID; | 1252 | m_rootPart.AttachedAvatar = agentID; |
1239 | 1253 | ||
1240 | //Anakin Lohner bug #3839 | 1254 | //Anakin Lohner bug #3839 |
1241 | foreach (SceneObjectPart p in m_parts.Values) | 1255 | lock (m_parts) |
1242 | { | 1256 | { |
1243 | p.AttachedAvatar = agentID; | 1257 | foreach (SceneObjectPart p in m_parts.Values) |
1258 | { | ||
1259 | p.AttachedAvatar = agentID; | ||
1260 | } | ||
1244 | } | 1261 | } |
1245 | 1262 | ||
1246 | if (m_rootPart.PhysActor != null) | 1263 | if (m_rootPart.PhysActor != null) |
@@ -1308,10 +1325,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1308 | 1325 | ||
1309 | AbsolutePosition = detachedpos; | 1326 | AbsolutePosition = detachedpos; |
1310 | m_rootPart.AttachedAvatar = UUID.Zero; | 1327 | m_rootPart.AttachedAvatar = UUID.Zero; |
1311 | //Anakin Lohner bug #3839 | 1328 | |
1312 | foreach (SceneObjectPart p in m_parts.Values) | 1329 | //Anakin Lohner bug #3839 |
1330 | lock (m_parts) | ||
1313 | { | 1331 | { |
1314 | p.AttachedAvatar = UUID.Zero; | 1332 | foreach (SceneObjectPart p in m_parts.Values) |
1333 | { | ||
1334 | p.AttachedAvatar = UUID.Zero; | ||
1335 | } | ||
1315 | } | 1336 | } |
1316 | 1337 | ||
1317 | m_rootPart.SetParentLocalId(0); | 1338 | m_rootPart.SetParentLocalId(0); |
@@ -1337,10 +1358,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1337 | } | 1358 | } |
1338 | 1359 | ||
1339 | m_rootPart.AttachedAvatar = UUID.Zero; | 1360 | m_rootPart.AttachedAvatar = UUID.Zero; |
1361 | |||
1340 | //Anakin Lohner bug #3839 | 1362 | //Anakin Lohner bug #3839 |
1341 | foreach (SceneObjectPart p in m_parts.Values) | 1363 | lock (m_parts) |
1342 | { | 1364 | { |
1343 | p.AttachedAvatar = UUID.Zero; | 1365 | foreach (SceneObjectPart p in m_parts.Values) |
1366 | { | ||
1367 | p.AttachedAvatar = UUID.Zero; | ||
1368 | } | ||
1344 | } | 1369 | } |
1345 | 1370 | ||
1346 | m_rootPart.SetParentLocalId(0); | 1371 | m_rootPart.SetParentLocalId(0); |
@@ -1406,9 +1431,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1406 | part.ParentID = 0; | 1431 | part.ParentID = 0; |
1407 | part.LinkNum = 0; | 1432 | part.LinkNum = 0; |
1408 | 1433 | ||
1409 | // No locking required since the SOG should not be in the scene yet - one can't change root parts after | 1434 | lock (m_parts) |
1410 | // the scene object has been attached to the scene | 1435 | m_parts.Add(m_rootPart.UUID, m_rootPart); |
1411 | m_parts.Add(m_rootPart.UUID, m_rootPart); | ||
1412 | } | 1436 | } |
1413 | 1437 | ||
1414 | /// <summary> | 1438 | /// <summary> |
@@ -1928,14 +1952,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1928 | } | 1952 | } |
1929 | 1953 | ||
1930 | /// <summary> | 1954 | /// <summary> |
1931 | /// | 1955 | /// Copy the given part as the root part of this scene object. |
1932 | /// </summary> | 1956 | /// </summary> |
1933 | /// <param name="part"></param> | 1957 | /// <param name="part"></param> |
1934 | /// <param name="cAgentID"></param> | 1958 | /// <param name="cAgentID"></param> |
1935 | /// <param name="cGroupID"></param> | 1959 | /// <param name="cGroupID"></param> |
1936 | public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) | 1960 | public void CopyRootPart(SceneObjectPart part, UUID cAgentID, UUID cGroupID, bool userExposed) |
1937 | { | 1961 | { |
1938 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); | 1962 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); |
1939 | } | 1963 | } |
1940 | 1964 | ||
1941 | public void ScriptSetPhysicsStatus(bool UsePhysics) | 1965 | public void ScriptSetPhysicsStatus(bool UsePhysics) |
@@ -2234,14 +2258,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2234 | /// </summary> | 2258 | /// </summary> |
2235 | public void ResetIDs() | 2259 | public void ResetIDs() |
2236 | { | 2260 | { |
2237 | // As this is only ever called for prims which are not currently part of the scene (and hence | 2261 | lock (m_parts) |
2238 | // not accessible by clients), there should be no need to lock | ||
2239 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); | ||
2240 | m_parts.Clear(); | ||
2241 | foreach (SceneObjectPart part in partsList) | ||
2242 | { | 2262 | { |
2243 | part.ResetIDs(part.LinkNum); // Don't change link nums | 2263 | List<SceneObjectPart> partsList = new List<SceneObjectPart>(m_parts.Values); |
2244 | m_parts.Add(part.UUID, part); | 2264 | m_parts.Clear(); |
2265 | foreach (SceneObjectPart part in partsList) | ||
2266 | { | ||
2267 | part.ResetIDs(part.LinkNum); // Don't change link nums | ||
2268 | m_parts.Add(part.UUID, part); | ||
2269 | } | ||
2245 | } | 2270 | } |
2246 | } | 2271 | } |
2247 | 2272 | ||
@@ -2283,29 +2308,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
2283 | // return; | 2308 | // return; |
2284 | 2309 | ||
2285 | lockPartsForRead(true); | 2310 | lockPartsForRead(true); |
2286 | { | ||
2287 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | ||
2288 | 2311 | ||
2289 | if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) | 2312 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); |
2290 | { | ||
2291 | m_rootPart.UpdateFlag = 1; | ||
2292 | lastPhysGroupPos = AbsolutePosition; | ||
2293 | } | ||
2294 | 2313 | ||
2295 | if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) | 2314 | if (UsePhysics && !AbsolutePosition.ApproxEquals(lastPhysGroupPos, 0.02f)) |
2296 | { | 2315 | { |
2297 | m_rootPart.UpdateFlag = 1; | 2316 | m_rootPart.UpdateFlag = 1; |
2298 | lastPhysGroupRot = GroupRotation; | 2317 | lastPhysGroupPos = AbsolutePosition; |
2299 | } | 2318 | } |
2300 | 2319 | ||
2301 | foreach (SceneObjectPart part in m_parts.Values) | 2320 | if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) |
2302 | { | 2321 | { |
2303 | if (!IsSelected) | 2322 | m_rootPart.UpdateFlag = 1; |
2304 | part.UpdateLookAt(); | 2323 | lastPhysGroupRot = GroupRotation; |
2324 | } | ||
2305 | 2325 | ||
2306 | part.SendScheduledUpdates(); | 2326 | List<SceneObjectPart> partList = null; |
2307 | 2327 | partList = new List<SceneObjectPart>(m_parts.Values); | |
2308 | } | 2328 | |
2329 | foreach (SceneObjectPart part in partList) | ||
2330 | { | ||
2331 | if (!IsSelected) | ||
2332 | part.UpdateLookAt(); | ||
2333 | part.SendScheduledUpdates(); | ||
2309 | } | 2334 | } |
2310 | lockPartsForRead(false); | 2335 | lockPartsForRead(false); |
2311 | } | 2336 | } |
@@ -2479,10 +2504,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2479 | public SceneObjectPart GetChildPart(UUID primID) | 2504 | public SceneObjectPart GetChildPart(UUID primID) |
2480 | { | 2505 | { |
2481 | SceneObjectPart childPart = null; | 2506 | SceneObjectPart childPart = null; |
2482 | if (m_parts.ContainsKey(primID)) | 2507 | |
2508 | lock (m_parts) | ||
2483 | { | 2509 | { |
2484 | childPart = m_parts[primID]; | 2510 | if (m_parts.ContainsKey(primID)) |
2511 | { | ||
2512 | childPart = m_parts[primID]; | ||
2513 | } | ||
2485 | } | 2514 | } |
2515 | |||
2486 | return childPart; | 2516 | return childPart; |
2487 | } | 2517 | } |
2488 | 2518 | ||
@@ -2519,9 +2549,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2519 | /// <returns></returns> | 2549 | /// <returns></returns> |
2520 | public bool HasChildPrim(UUID primID) | 2550 | public bool HasChildPrim(UUID primID) |
2521 | { | 2551 | { |
2522 | if (m_parts.ContainsKey(primID)) | 2552 | lock (m_parts) |
2523 | { | 2553 | { |
2524 | return true; | 2554 | if (m_parts.ContainsKey(primID)) |
2555 | return true; | ||
2525 | } | 2556 | } |
2526 | 2557 | ||
2527 | return false; | 2558 | return false; |
@@ -3132,9 +3163,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3132 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, | 3163 | public void UpdatePermissions(UUID AgentID, byte field, uint localID, |
3133 | uint mask, byte addRemTF) | 3164 | uint mask, byte addRemTF) |
3134 | { | 3165 | { |
3135 | foreach (SceneObjectPart part in m_parts.Values) | 3166 | List<SceneObjectPart> partList = null; |
3136 | part.UpdatePermissions(AgentID, field, localID, mask, | 3167 | lock (m_parts) |
3137 | addRemTF); | 3168 | partList = new List<SceneObjectPart>(m_parts.Values); |
3169 | |||
3170 | foreach (SceneObjectPart part in partList) | ||
3171 | part.UpdatePermissions(AgentID, field, localID, mask, addRemTF); | ||
3138 | 3172 | ||
3139 | HasGroupChanged = true; | 3173 | HasGroupChanged = true; |
3140 | } | 3174 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9e52b00..eefe8bb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -4756,20 +4756,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
4756 | if (ParentGroup == null || ParentGroup.IsDeleted) | 4756 | if (ParentGroup == null || ParentGroup.IsDeleted) |
4757 | return; | 4757 | return; |
4758 | 4758 | ||
4759 | Vector3 lPos = OffsetPosition; | 4759 | if (IsAttachment && ParentGroup.RootPart != this) |
4760 | 4760 | return; | |
4761 | if (IsAttachment) | ||
4762 | { | ||
4763 | if (ParentGroup.RootPart != this) | ||
4764 | return; | ||
4765 | |||
4766 | lPos = ParentGroup.RootPart.AttachedPos; | ||
4767 | } | ||
4768 | else | ||
4769 | { | ||
4770 | if (ParentGroup.RootPart == this) | ||
4771 | lPos = AbsolutePosition; | ||
4772 | } | ||
4773 | 4761 | ||
4774 | // Causes this thread to dig into the Client Thread Data. | 4762 | // Causes this thread to dig into the Client Thread Data. |
4775 | // Remember your locking here! | 4763 | // Remember your locking here! |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8b4f0ed..c5994b2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -37,6 +37,7 @@ using log4net; | |||
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Region.Framework.Interfaces; | 38 | using OpenSim.Region.Framework.Interfaces; |
39 | using OpenSim.Region.Framework.Scenes.Scripting; | 39 | using OpenSim.Region.Framework.Scenes.Scripting; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | ||
40 | 41 | ||
41 | namespace OpenSim.Region.Framework.Scenes | 42 | namespace OpenSim.Region.Framework.Scenes |
42 | { | 43 | { |
@@ -722,6 +723,70 @@ namespace OpenSim.Region.Framework.Scenes | |||
722 | return items; | 723 | return items; |
723 | } | 724 | } |
724 | 725 | ||
726 | public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) | ||
727 | { | ||
728 | AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | ||
729 | |||
730 | if (null == rezAsset) | ||
731 | { | ||
732 | m_log.WarnFormat( | ||
733 | "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", | ||
734 | item.AssetID, item.Name, m_part.Name); | ||
735 | return null; | ||
736 | } | ||
737 | |||
738 | string xmlData = Utils.BytesToString(rezAsset.Data); | ||
739 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
740 | |||
741 | group.ResetIDs(); | ||
742 | |||
743 | SceneObjectPart rootPart = group.GetChildPart(group.UUID); | ||
744 | |||
745 | // Since renaming the item in the inventory does not affect the name stored | ||
746 | // in the serialization, transfer the correct name from the inventory to the | ||
747 | // object itself before we rez. | ||
748 | rootPart.Name = item.Name; | ||
749 | rootPart.Description = item.Description; | ||
750 | |||
751 | List<SceneObjectPart> partList = null; | ||
752 | |||
753 | lock (group.Children) | ||
754 | partList = new List<SceneObjectPart>(group.Children.Values); | ||
755 | |||
756 | group.SetGroup(m_part.GroupID, null); | ||
757 | |||
758 | if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) | ||
759 | { | ||
760 | if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) | ||
761 | { | ||
762 | foreach (SceneObjectPart part in partList) | ||
763 | { | ||
764 | part.EveryoneMask = item.EveryonePermissions; | ||
765 | part.NextOwnerMask = item.NextPermissions; | ||
766 | } | ||
767 | |||
768 | group.ApplyNextOwnerPermissions(); | ||
769 | } | ||
770 | } | ||
771 | |||
772 | foreach (SceneObjectPart part in partList) | ||
773 | { | ||
774 | if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) | ||
775 | { | ||
776 | part.LastOwnerID = part.OwnerID; | ||
777 | part.OwnerID = item.OwnerID; | ||
778 | part.Inventory.ChangeInventoryOwner(item.OwnerID); | ||
779 | } | ||
780 | |||
781 | part.EveryoneMask = item.EveryonePermissions; | ||
782 | part.NextOwnerMask = item.NextPermissions; | ||
783 | } | ||
784 | |||
785 | rootPart.TrimPermissions(); | ||
786 | |||
787 | return group; | ||
788 | } | ||
789 | |||
725 | /// <summary> | 790 | /// <summary> |
726 | /// Update an existing inventory item. | 791 | /// Update an existing inventory item. |
727 | /// </summary> | 792 | /// </summary> |
@@ -1197,6 +1262,5 @@ namespace OpenSim.Region.Framework.Scenes | |||
1197 | 1262 | ||
1198 | Items.LockItemsForRead(false); | 1263 | Items.LockItemsForRead(false); |
1199 | } | 1264 | } |
1200 | |||
1201 | } | 1265 | } |
1202 | } | 1266 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 02e60f8..cd80eb0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2668,15 +2668,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2668 | { | 2668 | { |
2669 | m_perfMonMS = Util.EnvironmentTickCount(); | 2669 | m_perfMonMS = Util.EnvironmentTickCount(); |
2670 | 2670 | ||
2671 | PhysicsActor actor = m_physicsActor; | ||
2672 | Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; | ||
2673 | |||
2674 | Vector3 pos = m_pos; | 2671 | Vector3 pos = m_pos; |
2675 | pos.Z += m_appearance.HipOffset; | 2672 | pos.Z += m_appearance.HipOffset; |
2676 | 2673 | ||
2677 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); | 2674 | //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); |
2678 | 2675 | ||
2679 | remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | 2676 | remoteClient.SendPrimUpdate( |
2677 | this, | ||
2678 | PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | ||
2679 | | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); | ||
2680 | 2680 | ||
2681 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); | 2681 | m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); |
2682 | m_scene.StatsReporter.AddAgentUpdates(1); | 2682 | m_scene.StatsReporter.AddAgentUpdates(1); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs index fc66c85..3e2a2af 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs | |||
@@ -134,7 +134,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
134 | sop.Text = RandomName(); | 134 | sop.Text = RandomName(); |
135 | sop.SitName = RandomName(); | 135 | sop.SitName = RandomName(); |
136 | sop.TouchName = RandomName(); | 136 | sop.TouchName = RandomName(); |
137 | sop.ObjectFlags |= (uint)PrimFlags.Phantom; | 137 | sop.Flags |= PrimFlags.Phantom; |
138 | 138 | ||
139 | SceneObjectGroup sog = new SceneObjectGroup(sop); | 139 | SceneObjectGroup sog = new SceneObjectGroup(sop); |
140 | scene.AddNewSceneObject(sog, false); | 140 | scene.AddNewSceneObject(sog, false); |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs new file mode 100644 index 0000000..da8199d --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/TaskInventoryTests.cs | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Reflection; | ||
31 | using System.Text; | ||
32 | using System.Threading; | ||
33 | using System.Timers; | ||
34 | using Timer=System.Timers.Timer; | ||
35 | using Nini.Config; | ||
36 | using NUnit.Framework; | ||
37 | using NUnit.Framework.SyntaxHelpers; | ||
38 | using OpenMetaverse; | ||
39 | using OpenMetaverse.Assets; | ||
40 | using OpenSim.Framework; | ||
41 | using OpenSim.Framework.Communications; | ||
42 | using OpenSim.Region.Framework.Scenes; | ||
43 | using OpenSim.Region.Framework.Interfaces; | ||
44 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | ||
45 | using OpenSim.Region.CoreModules.World.Serialiser; | ||
46 | using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; | ||
47 | using OpenSim.Services.Interfaces; | ||
48 | using OpenSim.Tests.Common; | ||
49 | using OpenSim.Tests.Common.Mock; | ||
50 | using OpenSim.Tests.Common.Setup; | ||
51 | |||
52 | namespace OpenSim.Region.Framework.Tests | ||
53 | { | ||
54 | [TestFixture] | ||
55 | public class TaskInventoryTests | ||
56 | { | ||
57 | protected UserAccount CreateUser(Scene scene) | ||
58 | { | ||
59 | string userFirstName = "Jock"; | ||
60 | string userLastName = "Stirrup"; | ||
61 | string userPassword = "troll"; | ||
62 | UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); | ||
63 | return UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); | ||
64 | } | ||
65 | |||
66 | protected SceneObjectGroup CreateSO1(Scene scene, UUID ownerId) | ||
67 | { | ||
68 | string part1Name = "part1"; | ||
69 | UUID part1Id = UUID.Parse("10000000-0000-0000-0000-000000000000"); | ||
70 | SceneObjectPart part1 | ||
71 | = new SceneObjectPart(ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) | ||
72 | { Name = part1Name, UUID = part1Id }; | ||
73 | return new SceneObjectGroup(part1); | ||
74 | } | ||
75 | |||
76 | protected TaskInventoryItem CreateSOItem1(Scene scene, SceneObjectPart part) | ||
77 | { | ||
78 | AssetNotecard nc = new AssetNotecard("Hello World!"); | ||
79 | UUID ncAssetUuid = new UUID("00000000-0000-0000-1000-000000000000"); | ||
80 | UUID ncItemUuid = new UUID("00000000-0000-0000-1100-000000000000"); | ||
81 | AssetBase ncAsset | ||
82 | = AssetHelpers.CreateAsset(ncAssetUuid, AssetType.Notecard, nc.AssetData, UUID.Zero); | ||
83 | scene.AssetService.Store(ncAsset); | ||
84 | TaskInventoryItem ncItem | ||
85 | = new TaskInventoryItem | ||
86 | { Name = "ncItem", AssetID = ncAssetUuid, ItemID = ncItemUuid, | ||
87 | Type = (int)AssetType.Notecard, InvType = (int)InventoryType.Notecard }; | ||
88 | part.Inventory.AddInventoryItem(ncItem, true); | ||
89 | |||
90 | return ncItem; | ||
91 | } | ||
92 | |||
93 | /// <summary> | ||
94 | /// Test MoveTaskInventoryItem where the item has no parent folder assigned. | ||
95 | /// </summary> | ||
96 | /// This should place it in the most suitable user folder. | ||
97 | [Test] | ||
98 | public void TestMoveTaskInventoryItem() | ||
99 | { | ||
100 | TestHelper.InMethod(); | ||
101 | // log4net.Config.XmlConfigurator.Configure(); | ||
102 | |||
103 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | ||
104 | UserAccount user1 = CreateUser(scene); | ||
105 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); | ||
106 | SceneObjectPart sop1 = sog1.RootPart; | ||
107 | TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1); | ||
108 | InventoryFolderBase folder | ||
109 | = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, user1.PrincipalID, "Objects")[0]; | ||
110 | |||
111 | // Perform test | ||
112 | scene.MoveTaskInventoryItem(user1.PrincipalID, folder.ID, sop1, sopItem1.ItemID); | ||
113 | |||
114 | InventoryItemBase ncUserItem | ||
115 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Objects/ncItem"); | ||
116 | Assert.That(ncUserItem, Is.Not.Null, "Objects/ncItem was not found"); | ||
117 | } | ||
118 | |||
119 | /// <summary> | ||
120 | /// Test MoveTaskInventoryItem where the item has no parent folder assigned. | ||
121 | /// </summary> | ||
122 | /// This should place it in the most suitable user folder. | ||
123 | [Test] | ||
124 | public void TestMoveTaskInventoryItemNoParent() | ||
125 | { | ||
126 | TestHelper.InMethod(); | ||
127 | // log4net.Config.XmlConfigurator.Configure(); | ||
128 | |||
129 | Scene scene = SceneSetupHelpers.SetupScene("inventory"); | ||
130 | UserAccount user1 = CreateUser(scene); | ||
131 | SceneObjectGroup sog1 = CreateSO1(scene, user1.PrincipalID); | ||
132 | SceneObjectPart sop1 = sog1.RootPart; | ||
133 | TaskInventoryItem sopItem1 = CreateSOItem1(scene, sop1); | ||
134 | |||
135 | // Perform test | ||
136 | scene.MoveTaskInventoryItem(user1.PrincipalID, UUID.Zero, sop1, sopItem1.ItemID); | ||
137 | |||
138 | InventoryItemBase ncUserItem | ||
139 | = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, user1.PrincipalID, "Notecards/ncItem"); | ||
140 | Assert.That(ncUserItem, Is.Not.Null, "Notecards/ncItem was not found"); | ||
141 | } | ||
142 | } | ||
143 | } \ No newline at end of file | ||