aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rwxr-xr-xOpenSim/Region/Framework/Scenes/SceneGraph.cs126
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 @@
28using System; 28using System;
29using System.Threading; 29using System.Threading;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Collections.Concurrent;
31using System.Reflection; 32using System.Reflection;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenMetaverse.Packets; 34using 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 {