diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rwxr-xr-x | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 126 |
1 files changed, 59 insertions, 67 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 61a243d..68864cc 100755 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Threading; | 29 | using System.Threading; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Collections.Concurrent; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using OpenMetaverse; | 33 | using OpenMetaverse; |
33 | using OpenMetaverse.Packets; | 34 | using OpenMetaverse.Packets; |
@@ -68,8 +69,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
68 | 69 | ||
69 | #region Fields | 70 | #region Fields |
70 | 71 | ||
71 | protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); | 72 | protected System.Threading.ReaderWriterLockSlim m_scenePresencesLock = new System.Threading.ReaderWriterLockSlim(); |
72 | protected Dictionary<UUID, ScenePresence> m_scenePresenceMap = new Dictionary<UUID, ScenePresence>(); | 73 | |
74 | protected ConcurrentDictionary<UUID, ScenePresence> m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); | ||
75 | protected ConcurrentDictionary<uint, ScenePresence> m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); | ||
73 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); | 76 | protected List<ScenePresence> m_scenePresenceArray = new List<ScenePresence>(); |
74 | 77 | ||
75 | protected internal EntityManager Entities = new EntityManager(); | 78 | protected internal EntityManager Entities = new EntityManager(); |
@@ -147,10 +150,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
147 | m_scenePresencesLock.EnterWriteLock(); | 150 | m_scenePresencesLock.EnterWriteLock(); |
148 | try | 151 | try |
149 | { | 152 | { |
150 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(); | 153 | m_scenePresenceMap = new ConcurrentDictionary<UUID, ScenePresence>(); |
151 | List<ScenePresence> newlist = new List<ScenePresence>(); | 154 | m_scenePresenceLocalIDMap = new ConcurrentDictionary<uint, ScenePresence>(); |
152 | m_scenePresenceMap = newmap; | 155 | m_scenePresenceArray = new List<ScenePresence>(); |
153 | m_scenePresenceArray = newlist; | ||
154 | } | 156 | } |
155 | finally | 157 | finally |
156 | { | 158 | { |
@@ -165,22 +167,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
165 | SceneObjectGroupsByLocalPartID.Clear(); | 167 | SceneObjectGroupsByLocalPartID.Clear(); |
166 | 168 | ||
167 | Entities.Clear(); | 169 | Entities.Clear(); |
170 | m_scenePresencesLock.Dispose(); | ||
168 | } | 171 | } |
169 | 172 | ||
170 | #region Update Methods | 173 | #region Update Methods |
171 | 174 | ||
172 | protected internal void UpdatePreparePhysics() | 175 | protected internal void UpdatePreparePhysics() |
173 | { | 176 | { |
174 | // If we are using a threaded physics engine | ||
175 | // grab the latest scene from the engine before | ||
176 | // trying to process it. | ||
177 | |||
178 | // PhysX does this (runs in the background). | ||
179 | |||
180 | if (PhysicsScene.IsThreaded) | ||
181 | { | ||
182 | PhysicsScene.GetResults(); | ||
183 | } | ||
184 | } | 177 | } |
185 | 178 | ||
186 | /// <summary> | 179 | /// <summary> |
@@ -197,6 +190,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
197 | }); | 190 | }); |
198 | } | 191 | } |
199 | 192 | ||
193 | protected internal void UpdateScenePresenceMovement() | ||
194 | { | ||
195 | ForEachScenePresence(delegate (ScenePresence presence) | ||
196 | { | ||
197 | presence.UpdateMovement(); | ||
198 | }); | ||
199 | } | ||
200 | |||
200 | /// <summary> | 201 | /// <summary> |
201 | /// Perform a physics frame update. | 202 | /// Perform a physics frame update. |
202 | /// </summary> | 203 | /// </summary> |
@@ -204,23 +205,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
204 | /// <returns></returns> | 205 | /// <returns></returns> |
205 | protected internal float UpdatePhysics(double elapsed) | 206 | protected internal float UpdatePhysics(double elapsed) |
206 | { | 207 | { |
207 | // Here is where the Scene calls the PhysicsScene. This is a one-way | 208 | if (PhysicsScene != null) |
208 | // interaction; the PhysicsScene cannot access the calling Scene directly. | 209 | return PhysicsScene.Simulate((float)elapsed); |
209 | // But with joints, we want a PhysicsActor to be able to influence a | 210 | return 0; |
210 | // non-physics SceneObjectPart. In particular, a PhysicsActor that is connected | ||
211 | // with a joint should be able to move the SceneObjectPart which is the visual | ||
212 | // representation of that joint (for editing and serialization purposes). | ||
213 | // However the PhysicsActor normally cannot directly influence anything outside | ||
214 | // of the PhysicsScene, and the non-physical SceneObjectPart which represents | ||
215 | // the joint in the Scene does not exist in the PhysicsScene. | ||
216 | // | ||
217 | // To solve this, we have an event in the PhysicsScene that is fired when a joint | ||
218 | // has changed position (because one of its associated PhysicsActors has changed | ||
219 | // position). | ||
220 | // | ||
221 | // Therefore, JointMoved and JointDeactivated events will be fired as a result of the following Simulate(). | ||
222 | |||
223 | return PhysicsScene.Simulate((float)elapsed); | ||
224 | } | 211 | } |
225 | 212 | ||
226 | protected internal void ProcessPhysicsPreSimulation() | 213 | protected internal void ProcessPhysicsPreSimulation() |
@@ -229,14 +216,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
229 | PhysicsScene.ProcessPreSimulation(); | 216 | PhysicsScene.ProcessPreSimulation(); |
230 | } | 217 | } |
231 | 218 | ||
232 | protected internal void UpdateScenePresenceMovement() | ||
233 | { | ||
234 | ForEachScenePresence(delegate(ScenePresence presence) | ||
235 | { | ||
236 | presence.UpdateMovement(); | ||
237 | }); | ||
238 | } | ||
239 | |||
240 | public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations) | 219 | public void GetCoarseLocations(out List<Vector3> coarseLocations, out List<UUID> avatarUUIDs, uint maxLocations) |
241 | { | 220 | { |
242 | coarseLocations = new List<Vector3>(); | 221 | coarseLocations = new List<Vector3>(); |
@@ -640,7 +619,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
640 | lock (m_updateList) | 619 | lock (m_updateList) |
641 | { | 620 | { |
642 | updates = new List<SceneObjectGroup>(m_updateList.Values); | 621 | updates = new List<SceneObjectGroup>(m_updateList.Values); |
643 | m_updateList.Clear(); | 622 | m_updateList = new Dictionary<UUID, SceneObjectGroup>(); |
644 | } | 623 | } |
645 | 624 | ||
646 | // Go through all updates | 625 | // Go through all updates |
@@ -720,26 +699,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | { | 699 | { |
721 | m_numChildAgents++; | 700 | m_numChildAgents++; |
722 | 701 | ||
723 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | ||
724 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | 702 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); |
725 | 703 | ||
726 | if (!newmap.ContainsKey(presence.UUID)) | 704 | if (!m_scenePresenceMap.ContainsKey(presence.UUID)) |
727 | { | 705 | { |
728 | newmap.Add(presence.UUID, presence); | 706 | m_scenePresenceMap[presence.UUID] = presence; |
707 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
729 | newlist.Add(presence); | 708 | newlist.Add(presence); |
730 | } | 709 | } |
731 | else | 710 | else |
732 | { | 711 | { |
733 | // Remember the old presence reference from the dictionary | 712 | // Remember the old presence reference from the dictionary |
734 | ScenePresence oldref = newmap[presence.UUID]; | 713 | ScenePresence oldref = m_scenePresenceMap[presence.UUID]; |
714 | uint oldLocalID = oldref.LocalId; | ||
735 | // Replace the presence reference in the dictionary with the new value | 715 | // Replace the presence reference in the dictionary with the new value |
736 | newmap[presence.UUID] = presence; | 716 | m_scenePresenceMap[presence.UUID] = presence; |
737 | // Find the index in the list where the old ref was stored and update the reference | ||
738 | newlist[newlist.IndexOf(oldref)] = presence; | 717 | newlist[newlist.IndexOf(oldref)] = presence; |
718 | |||
719 | if(presence.LocalId != oldLocalID) | ||
720 | { | ||
721 | m_scenePresenceLocalIDMap.TryRemove(oldLocalID, out oldref); | ||
722 | m_scenePresenceLocalIDMap[presence.LocalId] = presence; | ||
723 | } | ||
724 | // Find the index in the list where the old ref was stored and update the reference | ||
739 | } | 725 | } |
740 | 726 | ||
741 | // Swap out the dictionary and list with new references | 727 | // Swap out the dictionary and list with new references |
742 | m_scenePresenceMap = newmap; | ||
743 | m_scenePresenceArray = newlist; | 728 | m_scenePresenceArray = newlist; |
744 | } | 729 | } |
745 | finally | 730 | finally |
@@ -765,20 +750,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
765 | m_scenePresencesLock.EnterWriteLock(); | 750 | m_scenePresencesLock.EnterWriteLock(); |
766 | try | 751 | try |
767 | { | 752 | { |
768 | Dictionary<UUID, ScenePresence> newmap = new Dictionary<UUID, ScenePresence>(m_scenePresenceMap); | ||
769 | List<ScenePresence> newlist = new List<ScenePresence>(m_scenePresenceArray); | ||
770 | |||
771 | // Remove the presence reference from the dictionary | 753 | // Remove the presence reference from the dictionary |
772 | if (newmap.ContainsKey(agentID)) | 754 | ScenePresence oldref; |
755 | if(m_scenePresenceMap.TryRemove(agentID, out oldref)) | ||
773 | { | 756 | { |
774 | ScenePresence oldref = newmap[agentID]; | ||
775 | newmap.Remove(agentID); | ||
776 | |||
777 | // Find the index in the list where the old ref was stored and remove the reference | 757 | // Find the index in the list where the old ref was stored and remove the reference |
778 | newlist.RemoveAt(newlist.IndexOf(oldref)); | 758 | List<ScenePresence> newsps = new List<ScenePresence>(m_scenePresenceArray); |
779 | // Swap out the dictionary and list with new references | 759 | newsps.RemoveAt(newsps.IndexOf(oldref)); |
780 | m_scenePresenceMap = newmap; | 760 | m_scenePresenceArray = newsps; |
781 | m_scenePresenceArray = newlist; | 761 | m_scenePresenceLocalIDMap.TryRemove(oldref.LocalId, out oldref); |
782 | } | 762 | } |
783 | else | 763 | else |
784 | { | 764 | { |
@@ -914,7 +894,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
914 | /// <returns></returns> | 894 | /// <returns></returns> |
915 | protected internal List<ScenePresence> GetScenePresences() | 895 | protected internal List<ScenePresence> GetScenePresences() |
916 | { | 896 | { |
917 | return m_scenePresenceArray; | 897 | |
898 | m_scenePresencesLock.EnterReadLock(); | ||
899 | try | ||
900 | { | ||
901 | return m_scenePresenceArray; | ||
902 | } | ||
903 | finally | ||
904 | { | ||
905 | m_scenePresencesLock.ExitReadLock(); | ||
906 | } | ||
918 | } | 907 | } |
919 | 908 | ||
920 | /// <summary> | 909 | /// <summary> |
@@ -924,9 +913,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
924 | /// <returns>null if the presence was not found</returns> | 913 | /// <returns>null if the presence was not found</returns> |
925 | protected internal ScenePresence GetScenePresence(UUID agentID) | 914 | protected internal ScenePresence GetScenePresence(UUID agentID) |
926 | { | 915 | { |
927 | Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap; | ||
928 | ScenePresence presence; | 916 | ScenePresence presence; |
929 | presences.TryGetValue(agentID, out presence); | 917 | m_scenePresenceMap.TryGetValue(agentID, out presence); |
930 | return presence; | 918 | return presence; |
931 | } | 919 | } |
932 | 920 | ||
@@ -955,24 +943,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
955 | /// <returns>null if the presence was not found</returns> | 943 | /// <returns>null if the presence was not found</returns> |
956 | protected internal ScenePresence GetScenePresence(uint localID) | 944 | protected internal ScenePresence GetScenePresence(uint localID) |
957 | { | 945 | { |
946 | ScenePresence sp = null; | ||
947 | if(m_scenePresenceLocalIDMap.TryGetValue(localID, out sp)) | ||
948 | return sp; | ||
949 | /* | ||
958 | List<ScenePresence> presences = GetScenePresences(); | 950 | List<ScenePresence> presences = GetScenePresences(); |
959 | foreach (ScenePresence presence in presences) | 951 | foreach (ScenePresence presence in presences) |
960 | if (presence.LocalId == localID) | 952 | if (presence.LocalId == localID) |
961 | return presence; | 953 | return presence; |
954 | */ | ||
962 | return null; | 955 | return null; |
963 | } | 956 | } |
964 | 957 | ||
965 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) | 958 | protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) |
966 | { | 959 | { |
967 | Dictionary<UUID, ScenePresence> presences = m_scenePresenceMap; | 960 | return m_scenePresenceMap.TryGetValue(agentID, out avatar); |
968 | presences.TryGetValue(agentID, out avatar); | ||
969 | return (avatar != null); | ||
970 | } | 961 | } |
971 | 962 | ||
972 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) | 963 | protected internal bool TryGetAvatarByName(string name, out ScenePresence avatar) |
973 | { | 964 | { |
974 | avatar = null; | 965 | avatar = null; |
975 | foreach (ScenePresence presence in GetScenePresences()) | 966 | List<ScenePresence> presences = GetScenePresences(); |
967 | foreach (ScenePresence presence in presences) | ||
976 | { | 968 | { |
977 | if (String.Compare(name, presence.ControllingClient.Name, true) == 0) | 969 | if (String.Compare(name, presence.ControllingClient.Name, true) == 0) |
978 | { | 970 | { |