aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs2
-rw-r--r--OpenSim/Region/Framework/Interfaces/ITerrainModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/EntityManager.cs79
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs21
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs94
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs264
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs543
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs32
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs66
-rw-r--r--OpenSim/Region/Framework/Scenes/SimStatsReporter.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs11
13 files changed, 736 insertions, 411 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
index 78bd622..7312799 100644
--- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
+++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs
@@ -103,6 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces
103 103
104 void StoreRegionSettings(RegionSettings rs); 104 void StoreRegionSettings(RegionSettings rs);
105 RegionSettings LoadRegionSettings(UUID regionUUID); 105 RegionSettings LoadRegionSettings(UUID regionUUID);
106 RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID);
107 void StoreRegionWindlightSettings(RegionMeta7WindlightData wl);
106 108
107 void Shutdown(); 109 void Shutdown();
108 } 110 }
diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
index 2dcba0c..7caac55 100644
--- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.Framework.Interfaces
51 /// </param> 51 /// </param>
52 /// <param name="stream"></param> 52 /// <param name="stream"></param>
53 void LoadFromStream(string filename, Stream stream); 53 void LoadFromStream(string filename, Stream stream);
54 54 void LoadFromStream(string filename, System.Uri pathToTerrainHeightmap);
55 /// <summary> 55 /// <summary>
56 /// Save a terrain to a stream. 56 /// Save a terrain to a stream.
57 /// </summary> 57 /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index b031f61..50624a1 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -448,5 +448,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation
448 448
449 SendAnimPack(animIDs, sequenceNums, objectIDs); 449 SendAnimPack(animIDs, sequenceNums, objectIDs);
450 } 450 }
451
452 public void Close()
453 {
454 m_animations = null;
455 m_scenePresence = null;
456 }
451 } 457 }
452} 458}
diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs
index 099fcce..c246e32 100644
--- a/OpenSim/Region/Framework/Scenes/EntityManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs
@@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes
40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>(); 40 private readonly Dictionary<UUID,EntityBase> m_eb_uuid = new Dictionary<UUID, EntityBase>();
41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>(); 41 private readonly Dictionary<uint, EntityBase> m_eb_localID = new Dictionary<uint, EntityBase>();
42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>(); 42 //private readonly Dictionary<UUID, ScenePresence> m_pres_uuid = new Dictionary<UUID, ScenePresence>();
43 private readonly Object m_lock = new Object(); 43 private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim();
44 44
45 [Obsolete("Use Add() instead.")] 45 [Obsolete("Use Add() instead.")]
46 public void Add(UUID id, EntityBase eb) 46 public void Add(UUID id, EntityBase eb)
@@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes
50 50
51 public void Add(EntityBase entity) 51 public void Add(EntityBase entity)
52 { 52 {
53 lock (m_lock) 53 m_lock.EnterWriteLock();
54 try
54 { 55 {
55 try 56 try
56 { 57 {
@@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes
62 m_log.ErrorFormat("Add Entity failed: {0}", e.Message); 63 m_log.ErrorFormat("Add Entity failed: {0}", e.Message);
63 } 64 }
64 } 65 }
66 finally
67 {
68 m_lock.ExitWriteLock();
69 }
65 } 70 }
66 71
67 public void InsertOrReplace(EntityBase entity) 72 public void InsertOrReplace(EntityBase entity)
68 { 73 {
69 lock (m_lock) 74 m_lock.EnterWriteLock();
75 try
70 { 76 {
71 try 77 try
72 { 78 {
@@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes
78 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); 84 m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message);
79 } 85 }
80 } 86 }
87 finally
88 {
89 m_lock.ExitWriteLock();
90 }
81 } 91 }
82 92
83 public void Clear() 93 public void Clear()
84 { 94 {
85 lock (m_lock) 95 m_lock.EnterWriteLock();
96 try
86 { 97 {
87 m_eb_uuid.Clear(); 98 m_eb_uuid.Clear();
88 m_eb_localID.Clear(); 99 m_eb_localID.Clear();
89 } 100 }
101 finally
102 {
103 m_lock.ExitWriteLock();
104 }
90 } 105 }
91 106
92 public int Count 107 public int Count
@@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes
123 138
124 public bool Remove(uint localID) 139 public bool Remove(uint localID)
125 { 140 {
126 lock (m_lock) 141 m_lock.EnterWriteLock();
142 try
127 { 143 {
128 try 144 try
129 { 145 {
@@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes
141 return false; 157 return false;
142 } 158 }
143 } 159 }
160 finally
161 {
162 m_lock.ExitWriteLock();
163 }
144 } 164 }
145 165
146 public bool Remove(UUID id) 166 public bool Remove(UUID id)
147 { 167 {
148 lock (m_lock) 168 m_lock.EnterWriteLock();
169 try
149 { 170 {
150 try 171 try
151 { 172 {
@@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes
163 return false; 184 return false;
164 } 185 }
165 } 186 }
187 finally
188 {
189 m_lock.ExitWriteLock();
190 }
166 } 191 }
167 192
168 public List<EntityBase> GetAllByType<T>() 193 public List<EntityBase> GetAllByType<T>()
169 { 194 {
170 List<EntityBase> tmp = new List<EntityBase>(); 195 List<EntityBase> tmp = new List<EntityBase>();
171 196
172 lock (m_lock) 197 m_lock.EnterReadLock();
198 try
173 { 199 {
174 try 200 try
175 { 201 {
@@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes
187 tmp = null; 213 tmp = null;
188 } 214 }
189 } 215 }
216 finally
217 {
218 m_lock.ExitReadLock();
219 }
190 220
191 return tmp; 221 return tmp;
192 } 222 }
193 223
194 public List<EntityBase> GetEntities() 224 public List<EntityBase> GetEntities()
195 { 225 {
196 lock (m_lock) 226 m_lock.EnterReadLock();
227 try
197 { 228 {
198 return new List<EntityBase>(m_eb_uuid.Values); 229 return new List<EntityBase>(m_eb_uuid.Values);
199 } 230 }
231 finally
232 {
233 m_lock.ExitReadLock();
234 }
200 } 235 }
201 236
202 public EntityBase this[UUID id] 237 public EntityBase this[UUID id]
203 { 238 {
204 get 239 get
205 { 240 {
206 lock (m_lock) 241 m_lock.EnterReadLock();
242 try
207 { 243 {
208 EntityBase entity; 244 EntityBase entity;
209 if (m_eb_uuid.TryGetValue(id, out entity)) 245 if (m_eb_uuid.TryGetValue(id, out entity))
@@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes
211 else 247 else
212 return null; 248 return null;
213 } 249 }
250 finally
251 {
252 m_lock.ExitReadLock();
253 }
214 } 254 }
215 set 255 set
216 { 256 {
@@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes
222 { 262 {
223 get 263 get
224 { 264 {
225 lock (m_lock) 265 m_lock.EnterReadLock();
266 try
226 { 267 {
227 EntityBase entity; 268 EntityBase entity;
228 if (m_eb_localID.TryGetValue(localID, out entity)) 269 if (m_eb_localID.TryGetValue(localID, out entity))
@@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes
230 else 271 else
231 return null; 272 return null;
232 } 273 }
274 finally
275 {
276 m_lock.ExitReadLock();
277 }
233 } 278 }
234 set 279 set
235 { 280 {
@@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes
239 284
240 public bool TryGetValue(UUID key, out EntityBase obj) 285 public bool TryGetValue(UUID key, out EntityBase obj)
241 { 286 {
242 lock (m_lock) 287 m_lock.EnterReadLock();
288 try
243 { 289 {
244 return m_eb_uuid.TryGetValue(key, out obj); 290 return m_eb_uuid.TryGetValue(key, out obj);
245 } 291 }
292 finally
293 {
294 m_lock.ExitReadLock();
295 }
246 } 296 }
247 297
248 public bool TryGetValue(uint key, out EntityBase obj) 298 public bool TryGetValue(uint key, out EntityBase obj)
249 { 299 {
250 lock (m_lock) 300 m_lock.EnterReadLock();
301 try
251 { 302 {
252 return m_eb_localID.TryGetValue(key, out obj); 303 return m_eb_localID.TryGetValue(key, out obj);
253 } 304 }
305 finally
306 {
307 m_lock.ExitReadLock();
308 }
254 } 309 }
255 310
256 /// <summary> 311 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 753344d..a86e263 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -193,7 +193,9 @@ namespace OpenSim.Region.Framework.Scenes
193 public event OnMakeChildAgentDelegate OnMakeChildAgent; 193 public event OnMakeChildAgentDelegate OnMakeChildAgent;
194 194
195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence); 195 public delegate void OnMakeRootAgentDelegate(ScenePresence presence);
196 public delegate void OnSaveNewWindlightProfileDelegate();
196 public event OnMakeRootAgentDelegate OnMakeRootAgent; 197 public event OnMakeRootAgentDelegate OnMakeRootAgent;
198 public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile;
197 199
198 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); 200 public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel);
199 201
@@ -411,6 +413,7 @@ namespace OpenSim.Region.Framework.Scenes
411 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; 413 private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage;
412 private ClientClosed handlerClientClosed = null; //OnClientClosed; 414 private ClientClosed handlerClientClosed = null; //OnClientClosed;
413 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; 415 private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent;
416 private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile;
414 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; 417 private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent;
415 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; 418 private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick;
416 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; 419 private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps;
@@ -772,6 +775,15 @@ namespace OpenSim.Region.Framework.Scenes
772 } 775 }
773 } 776 }
774 777
778 public void TriggerOnSaveNewWindlightProfile()
779 {
780 handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile;
781 if (handlerSaveNewWindlightProfile != null)
782 {
783 handlerSaveNewWindlightProfile();
784 }
785 }
786
775 public void TriggerOnMakeRootAgent(ScenePresence presence) 787 public void TriggerOnMakeRootAgent(ScenePresence presence)
776 { 788 {
777 handlerMakeRootAgent = OnMakeRootAgent; 789 handlerMakeRootAgent = OnMakeRootAgent;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 83208e9..7ca779a 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -1726,10 +1726,19 @@ namespace OpenSim.Region.Framework.Scenes
1726 1726
1727 if (folderID == UUID.Zero && folder == null) 1727 if (folderID == UUID.Zero && folder == null)
1728 { 1728 {
1729 // Catch all. Use lost & found 1729 if (action == DeRezAction.Delete)
1730 // 1730 {
1731 // Deletes go to trash by default
1732 //
1733 folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
1734 }
1735 else
1736 {
1737 // Catch all. Use lost & found
1738 //
1731 1739
1732 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); 1740 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
1741 }
1733 } 1742 }
1734 1743
1735 if (folder == null) // None of the above 1744 if (folder == null) // None of the above
@@ -2388,6 +2397,12 @@ namespace OpenSim.Region.Framework.Scenes
2388 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); 2397 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
2389 item = InventoryService.GetItem(item); 2398 item = InventoryService.GetItem(item);
2390 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); 2399 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
2400
2401 if (m_AvatarFactory != null)
2402 {
2403 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
2404 }
2405
2391 } 2406 }
2392 } 2407 }
2393 2408
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 3034f9a..1b275b0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -310,7 +310,7 @@ namespace OpenSim.Region.Framework.Scenes
310 private Thread HeartbeatThread; 310 private Thread HeartbeatThread;
311 private volatile bool shuttingdown; 311 private volatile bool shuttingdown;
312 312
313 private int m_lastUpdate = Environment.TickCount; 313 private int m_lastUpdate;
314 private bool m_firstHeartbeat = true; 314 private bool m_firstHeartbeat = true;
315 315
316 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; 316 private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time;
@@ -526,6 +526,7 @@ namespace OpenSim.Region.Framework.Scenes
526 m_regionHandle = m_regInfo.RegionHandle; 526 m_regionHandle = m_regInfo.RegionHandle;
527 m_regionName = m_regInfo.RegionName; 527 m_regionName = m_regInfo.RegionName;
528 m_datastore = m_regInfo.DataStore; 528 m_datastore = m_regInfo.DataStore;
529 m_lastUpdate = Util.EnvironmentTickCount();
529 530
530 m_physicalPrim = physicalPrim; 531 m_physicalPrim = physicalPrim;
531 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor; 532 m_seeIntoRegionFromNeighbor = SeeIntoRegionFromNeighbor;
@@ -538,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes
538 539
539 // Load region settings 540 // Load region settings
540 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); 541 m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID);
542 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID);
543
541 if (m_storageManager.EstateDataStore != null) 544 if (m_storageManager.EstateDataStore != null)
542 { 545 {
543 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); 546 m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID);
@@ -735,6 +738,8 @@ namespace OpenSim.Region.Framework.Scenes
735 738
736 m_regInfo = regInfo; 739 m_regInfo = regInfo;
737 m_eventManager = new EventManager(); 740 m_eventManager = new EventManager();
741
742 m_lastUpdate = Util.EnvironmentTickCount();
738 } 743 }
739 744
740 #endregion 745 #endregion
@@ -1101,7 +1106,7 @@ namespace OpenSim.Region.Framework.Scenes
1101 HeartbeatThread.Abort(); 1106 HeartbeatThread.Abort();
1102 HeartbeatThread = null; 1107 HeartbeatThread = null;
1103 } 1108 }
1104 m_lastUpdate = Environment.TickCount; 1109 m_lastUpdate = Util.EnvironmentTickCount();
1105 1110
1106 HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false); 1111 HeartbeatThread = Watchdog.StartThread(Heartbeat, "Heartbeat for region " + RegionInfo.RegionName, ThreadPriority.Normal, false);
1107 } 1112 }
@@ -1142,7 +1147,7 @@ namespace OpenSim.Region.Framework.Scenes
1142 { 1147 {
1143 Update(); 1148 Update();
1144 1149
1145 m_lastUpdate = Environment.TickCount; 1150 m_lastUpdate = Util.EnvironmentTickCount();
1146 m_firstHeartbeat = false; 1151 m_firstHeartbeat = false;
1147 } 1152 }
1148 catch (ThreadAbortException) 1153 catch (ThreadAbortException)
@@ -1170,8 +1175,9 @@ namespace OpenSim.Region.Framework.Scenes
1170 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; 1175 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1171 physicsFPS = 0f; 1176 physicsFPS = 0f;
1172 1177
1173 maintc = otherMS = Environment.TickCount; 1178 maintc = Util.EnvironmentTickCount();
1174 int tmpFrameMS = maintc; 1179 int tmpFrameMS = maintc;
1180 tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1175 1181
1176 // Increment the frame counter 1182 // Increment the frame counter
1177 ++m_frame; 1183 ++m_frame;
@@ -1191,16 +1197,15 @@ namespace OpenSim.Region.Framework.Scenes
1191 if (m_frame % m_update_objects == 0) 1197 if (m_frame % m_update_objects == 0)
1192 m_sceneGraph.UpdateObjectGroups(); 1198 m_sceneGraph.UpdateObjectGroups();
1193 1199
1194 int TempPhysicsMS2 = Environment.TickCount; 1200 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1195 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1201 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1196 m_sceneGraph.UpdatePreparePhysics(); 1202 m_sceneGraph.UpdatePreparePhysics();
1197 TempPhysicsMS2 = Environment.TickCount - TempPhysicsMS2; 1203 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1198 physicsMS2 = TempPhysicsMS2;
1199 1204
1200 if (m_frame % m_update_entitymovement == 0) 1205 if (m_frame % m_update_entitymovement == 0)
1201 m_sceneGraph.UpdateScenePresenceMovement(); 1206 m_sceneGraph.UpdateScenePresenceMovement();
1202 1207
1203 int TempPhysicsMS = Environment.TickCount; 1208 int tmpPhysicsMS = Util.EnvironmentTickCount();
1204 if (m_frame % m_update_physics == 0) 1209 if (m_frame % m_update_physics == 0)
1205 { 1210 {
1206 if (m_physics_enabled) 1211 if (m_physics_enabled)
@@ -1208,57 +1213,49 @@ namespace OpenSim.Region.Framework.Scenes
1208 if (SynchronizeScene != null) 1213 if (SynchronizeScene != null)
1209 SynchronizeScene(this); 1214 SynchronizeScene(this);
1210 } 1215 }
1211 TempPhysicsMS = Environment.TickCount - TempPhysicsMS; 1216 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1212 physicsMS = TempPhysicsMS;
1213 1217
1214 // Delete temp-on-rez stuff 1218 // Delete temp-on-rez stuff
1215 if (m_frame % m_update_backup == 0) 1219 if (m_frame % m_update_backup == 0)
1216 { 1220 {
1217 int tozMS = Environment.TickCount; 1221 int tmpTempOnRezMS = Util.EnvironmentTickCount();
1218 CleanTempObjects(); 1222 CleanTempObjects();
1219 tozMS -= Environment.TickCount; 1223 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1220 tempOnRezMS = tozMS;
1221 } 1224 }
1222 1225
1223 if (RegionStatus != RegionStatus.SlaveScene) 1226 if (RegionStatus != RegionStatus.SlaveScene)
1224 { 1227 {
1225 if (m_frame % m_update_events == 0) 1228 if (m_frame % m_update_events == 0)
1226 { 1229 {
1227 int evMS = Environment.TickCount; 1230 int evMS = Util.EnvironmentTickCount();
1228 UpdateEvents(); 1231 UpdateEvents();
1229 evMS -= Environment.TickCount; 1232 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1230 eventMS = evMS;
1231 } 1233 }
1232 1234
1233 if (m_frame % m_update_backup == 0) 1235 if (m_frame % m_update_backup == 0)
1234 { 1236 {
1235 int backMS = Environment.TickCount; 1237 int backMS = Util.EnvironmentTickCount();
1236 UpdateStorageBackup(); 1238 UpdateStorageBackup();
1237 backMS -= Environment.TickCount; 1239 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1238 backupMS = backMS;
1239 } 1240 }
1240 1241
1241 if (m_frame % m_update_terrain == 0) 1242 if (m_frame % m_update_terrain == 0)
1242 { 1243 {
1243 int terMS = Environment.TickCount; 1244 int terMS = Util.EnvironmentTickCount();
1244 UpdateTerrain(); 1245 UpdateTerrain();
1245 terMS -= Environment.TickCount; 1246 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1246 terrainMS = terMS;
1247 } 1247 }
1248 1248
1249 if (m_frame % m_update_land == 0) 1249 if (m_frame % m_update_land == 0)
1250 { 1250 {
1251 int ldMS = Environment.TickCount; 1251 int ldMS = Util.EnvironmentTickCount();
1252 UpdateLand(); 1252 UpdateLand();
1253 ldMS -= Environment.TickCount; 1253 landMS = Util.EnvironmentTickCountSubtract(ldMS);
1254 landMS = ldMS;
1255 } 1254 }
1256 1255
1257 int tickCount = Environment.TickCount; 1256 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1258 otherMS = tickCount - otherMS; 1257 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1259 tmpFrameMS -= tickCount; 1258 lastCompletedFrame = Util.EnvironmentTickCount();
1260 frameMS = tmpFrameMS;
1261 lastCompletedFrame = tickCount;
1262 1259
1263 // if (m_frame%m_update_avatars == 0) 1260 // if (m_frame%m_update_avatars == 0)
1264 // UpdateInWorldTime(); 1261 // UpdateInWorldTime();
@@ -1311,8 +1308,8 @@ namespace OpenSim.Region.Framework.Scenes
1311 { 1308 {
1312 m_lastupdate = DateTime.UtcNow; 1309 m_lastupdate = DateTime.UtcNow;
1313 } 1310 }
1314 1311
1315 maintc = Environment.TickCount - maintc; 1312 maintc = Util.EnvironmentTickCountSubtract(maintc);
1316 maintc = (int)(m_timespan * 1000) - maintc; 1313 maintc = (int)(m_timespan * 1000) - maintc;
1317 1314
1318 if ((maintc < (m_timespan * 1000)) && maintc > 0) 1315 if ((maintc < (m_timespan * 1000)) && maintc > 0)
@@ -1323,6 +1320,7 @@ namespace OpenSim.Region.Framework.Scenes
1323 } 1320 }
1324 } 1321 }
1325 1322
1323
1326 1324
1327 public void AddGroupTarget(SceneObjectGroup grp) 1325 public void AddGroupTarget(SceneObjectGroup grp)
1328 { 1326 {
@@ -1506,6 +1504,19 @@ namespace OpenSim.Region.Framework.Scenes
1506 { 1504 {
1507 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); 1505 m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID);
1508 } 1506 }
1507
1508 public void StoreWindlightProfile(RegionMeta7WindlightData wl)
1509 {
1510 m_regInfo.WindlightSettings = wl;
1511 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1512 m_eventManager.TriggerOnSaveNewWindlightProfile();
1513 }
1514
1515 public void LoadWindlightProfile()
1516 {
1517 m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID);
1518 m_eventManager.TriggerOnSaveNewWindlightProfile();
1519 }
1509 1520
1510 /// <summary> 1521 /// <summary>
1511 /// Loads the World heightmap 1522 /// Loads the World heightmap
@@ -2599,7 +2610,7 @@ namespace OpenSim.Region.Framework.Scenes
2599 } 2610 }
2600 } 2611 }
2601 2612
2602 m_LastLogin = Environment.TickCount; 2613 m_LastLogin = Util.EnvironmentTickCount();
2603 EventManager.TriggerOnNewClient(client); 2614 EventManager.TriggerOnNewClient(client);
2604 } 2615 }
2605 2616
@@ -3050,6 +3061,7 @@ namespace OpenSim.Region.Framework.Scenes
3050 // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around. 3061 // TODO: The next line can be removed, as soon as only homeRegionID based UserServers are around.
3051 // TODO: The HomeRegion property can be removed then, too 3062 // TODO: The HomeRegion property can be removed then, too
3052 UserProfile.HomeRegion = RegionInfo.RegionHandle; 3063 UserProfile.HomeRegion = RegionInfo.RegionHandle;
3064
3053 UserProfile.HomeLocation = position; 3065 UserProfile.HomeLocation = position;
3054 UserProfile.HomeLookAt = lookAt; 3066 UserProfile.HomeLookAt = lookAt;
3055 CommsManager.UserService.UpdateUserProfile(UserProfile); 3067 CommsManager.UserService.UpdateUserProfile(UserProfile);
@@ -4410,16 +4422,6 @@ namespace OpenSim.Region.Framework.Scenes
4410 4422
4411 #endregion 4423 #endregion
4412 4424
4413 #region Avatar Appearance Default
4414
4415 public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams)
4416 {
4417 visualParams = AvatarAppearance.GetDefaultVisualParams();
4418 wearables = AvatarWearable.DefaultWearables;
4419 }
4420
4421 #endregion
4422
4423 public void RegionHandleRequest(IClientAPI client, UUID regionID) 4425 public void RegionHandleRequest(IClientAPI client, UUID regionID)
4424 { 4426 {
4425 ulong handle = 0; 4427 ulong handle = 0;
@@ -4678,14 +4680,14 @@ namespace OpenSim.Region.Framework.Scenes
4678 // 4680 //
4679 int health=1; // Start at 1, means we're up 4681 int health=1; // Start at 1, means we're up
4680 4682
4681 if ((Environment.TickCount - m_lastUpdate) < 1000) 4683 if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000)
4682 health+=1; 4684 health+=1;
4683 else 4685 else
4684 return health; 4686 return health;
4685 4687
4686 // A login in the last 4 mins? We can't be doing too badly 4688 // A login in the last 4 mins? We can't be doing too badly
4687 // 4689 //
4688 if ((Environment.TickCount - m_LastLogin) < 240000) 4690 if ((Util.EnvironmentTickCountSubtract(m_LastLogin)) < 240000)
4689 health++; 4691 health++;
4690 else 4692 else
4691 return health; 4693 return health;
@@ -4883,7 +4885,7 @@ namespace OpenSim.Region.Framework.Scenes
4883 if (m_firstHeartbeat) 4885 if (m_firstHeartbeat)
4884 return; 4886 return;
4885 4887
4886 if (System.Environment.TickCount - m_lastUpdate > 2000) 4888 if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000)
4887 StartTimer(); 4889 StartTimer();
4888 } 4890 }
4889 } 4891 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 2fdb48d..f74fd5d 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using System.Reflection; 31using System.Reflection;
31using OpenMetaverse; 32using OpenMetaverse;
@@ -96,6 +97,8 @@ namespace OpenSim.Region.Framework.Scenes
96 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>(); 97 protected internal Dictionary<UUID, SceneObjectGroup> SceneObjectGroupsByFullID = new Dictionary<UUID, SceneObjectGroup>();
97 private readonly Object m_dictionary_lock = new Object(); 98 private readonly Object m_dictionary_lock = new Object();
98 99
100 private Object m_updateLock = new Object();
101
99 #endregion 102 #endregion
100 103
101 protected internal SceneGraph(Scene parent, RegionInfo regInfo) 104 protected internal SceneGraph(Scene parent, RegionInfo regInfo)
@@ -369,6 +372,9 @@ namespace OpenSim.Region.Framework.Scenes
369 /// </summary> 372 /// </summary>
370 protected internal void UpdateObjectGroups() 373 protected internal void UpdateObjectGroups()
371 { 374 {
375 if (!Monitor.TryEnter(m_updateLock))
376 return;
377
372 List<SceneObjectGroup> updates; 378 List<SceneObjectGroup> updates;
373 379
374 // Some updates add more updates to the updateList. 380 // Some updates add more updates to the updateList.
@@ -395,6 +401,7 @@ namespace OpenSim.Region.Framework.Scenes
395 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 401 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
396 } 402 }
397 } 403 }
404 Monitor.Exit(m_updateLock);
398 } 405 }
399 406
400 protected internal void AddPhysicalPrim(int number) 407 protected internal void AddPhysicalPrim(int number)
@@ -1555,55 +1562,65 @@ namespace OpenSim.Region.Framework.Scenes
1555 /// <param name="childPrims"></param> 1562 /// <param name="childPrims"></param>
1556 protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds) 1563 protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds)
1557 { 1564 {
1558 SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); 1565 Monitor.Enter(m_updateLock);
1559 1566 try
1560 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1561 if (parentGroup != null)
1562 { 1567 {
1563 // We do this in reverse to get the link order of the prims correct 1568 SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId);
1564 for (int i = childPrimIds.Count - 1; i >= 0; i--) 1569
1570 List<SceneObjectGroup> childGroups = new List<SceneObjectGroup>();
1571 if (parentGroup != null)
1565 { 1572 {
1566 SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); 1573 // We do this in reverse to get the link order of the prims correct
1567 if (child != null) 1574 for (int i = childPrimIds.Count - 1; i >= 0; i--)
1568 { 1575 {
1569 // Make sure no child prim is set for sale 1576 SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]);
1570 // So that, on delink, no prims are unwittingly 1577 if (child != null)
1571 // left for sale and sold off 1578 {
1572 child.RootPart.ObjectSaleType = 0; 1579 // Make sure no child prim is set for sale
1573 child.RootPart.SalePrice = 10; 1580 // So that, on delink, no prims are unwittingly
1574 childGroups.Add(child); 1581 // left for sale and sold off
1582 child.RootPart.ObjectSaleType = 0;
1583 child.RootPart.SalePrice = 10;
1584 childGroups.Add(child);
1585 }
1575 } 1586 }
1576 } 1587 }
1577 } 1588 else
1578 else 1589 {
1579 { 1590 return; // parent is null so not in this region
1580 return; // parent is null so not in this region 1591 }
1581 }
1582 1592
1583 foreach (SceneObjectGroup child in childGroups) 1593 foreach (SceneObjectGroup child in childGroups)
1584 { 1594 {
1585 parentGroup.LinkToGroup(child); 1595 parentGroup.LinkToGroup(child);
1586 1596
1587 // this is here so physics gets updated! 1597 // this is here so physics gets updated!
1588 // Don't remove! Bad juju! Stay away! or fix physics! 1598 // Don't remove! Bad juju! Stay away! or fix physics!
1589 child.AbsolutePosition = child.AbsolutePosition; 1599 child.AbsolutePosition = child.AbsolutePosition;
1590 } 1600 }
1591 1601
1592 // We need to explicitly resend the newly link prim's object properties since no other actions 1602 // We need to explicitly resend the newly link prim's object properties since no other actions
1593 // occur on link to invoke this elsewhere (such as object selection) 1603 // occur on link to invoke this elsewhere (such as object selection)
1594 parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); 1604 parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected);
1595 parentGroup.TriggerScriptChangedEvent(Changed.LINK); 1605 parentGroup.TriggerScriptChangedEvent(Changed.LINK);
1596 1606 parentGroup.HasGroupChanged = true;
1597 if (client != null) 1607 parentGroup.ScheduleGroupForFullUpdate();
1598 { 1608
1599 parentGroup.GetProperties(client); 1609// if (client != null)
1610// {
1611// parentGroup.GetProperties(client);
1612// }
1613// else
1614// {
1615// foreach (ScenePresence p in GetScenePresences())
1616// {
1617// parentGroup.GetProperties(p.ControllingClient);
1618// }
1619// }
1600 } 1620 }
1601 else 1621 finally
1602 { 1622 {
1603 foreach (ScenePresence p in GetScenePresences()) 1623 Monitor.Exit(m_updateLock);
1604 {
1605 parentGroup.GetProperties(p.ControllingClient);
1606 }
1607 } 1624 }
1608 } 1625 }
1609 1626
@@ -1618,109 +1635,120 @@ namespace OpenSim.Region.Framework.Scenes
1618 1635
1619 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents) 1636 protected internal void DelinkObjects(List<uint> primIds, bool sendEvents)
1620 { 1637 {
1621 List<SceneObjectPart> childParts = new List<SceneObjectPart>(); 1638 Monitor.Enter(m_updateLock);
1622 List<SceneObjectPart> rootParts = new List<SceneObjectPart>(); 1639 try
1623 List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
1624 // Look them all up in one go, since that is comparatively expensive
1625 //
1626 foreach (uint primID in primIds)
1627 { 1640 {
1628 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); 1641 List<SceneObjectPart> childParts = new List<SceneObjectPart>();
1629 if (part != null) 1642 List<SceneObjectPart> rootParts = new List<SceneObjectPart>();
1643 List<SceneObjectGroup> affectedGroups = new List<SceneObjectGroup>();
1644 // Look them all up in one go, since that is comparatively expensive
1645 //
1646 foreach (uint primID in primIds)
1630 { 1647 {
1631 if (part.LinkNum < 2) // Root or single 1648 SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID);
1632 rootParts.Add(part); 1649 if (part != null)
1650 {
1651 if (part.ParentGroup.Children.Count != 1) // Skip single
1652 {
1653 if (part.LinkNum < 2) // Root
1654 rootParts.Add(part);
1655 else
1656 childParts.Add(part);
1657
1658 SceneObjectGroup group = part.ParentGroup;
1659 if (!affectedGroups.Contains(group))
1660 affectedGroups.Add(group);
1661 }
1662 }
1633 else 1663 else
1634 childParts.Add(part); 1664 {
1635 1665 m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID);
1636 SceneObjectGroup group = part.ParentGroup; 1666 }
1637 if (!affectedGroups.Contains(group))
1638 affectedGroups.Add(group);
1639 } 1667 }
1640 else 1668
1669 foreach (SceneObjectPart child in childParts)
1641 { 1670 {
1642 m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); 1671 // Unlink all child parts from their groups
1672 //
1673 child.ParentGroup.DelinkFromGroup(child, sendEvents);
1643 } 1674 }
1644 }
1645
1646 foreach (SceneObjectPart child in childParts)
1647 {
1648 // Unlink all child parts from their groups
1649 //
1650 child.ParentGroup.DelinkFromGroup(child, sendEvents);
1651 }
1652
1653 foreach (SceneObjectPart root in rootParts)
1654 {
1655 // In most cases, this will run only one time, and the prim
1656 // will be a solo prim
1657 // However, editing linked parts and unlinking may be different
1658 //
1659 SceneObjectGroup group = root.ParentGroup;
1660 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
1661 int numChildren = group.Children.Count;
1662 1675
1663 // If there are prims left in a link set, but the root is 1676 foreach (SceneObjectPart root in rootParts)
1664 // slated for unlink, we need to do this
1665 //
1666 if (numChildren != 1)
1667 { 1677 {
1668 // Unlink the remaining set 1678 // In most cases, this will run only one time, and the prim
1679 // will be a solo prim
1680 // However, editing linked parts and unlinking may be different
1669 // 1681 //
1670 bool sendEventsToRemainder = true; 1682 SceneObjectGroup group = root.ParentGroup;
1671 if (numChildren > 1) 1683 List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Children.Values);
1672 sendEventsToRemainder = false; 1684 int numChildren = group.Children.Count;
1673
1674 foreach (SceneObjectPart p in newSet)
1675 {
1676 if (p != group.RootPart)
1677 group.DelinkFromGroup(p, sendEventsToRemainder);
1678 }
1679 1685
1680 // If there is more than one prim remaining, we 1686 // If there are prims left in a link set, but the root is
1681 // need to re-link 1687 // slated for unlink, we need to do this
1682 // 1688 //
1683 if (numChildren > 2) 1689 if (numChildren != 1)
1684 { 1690 {
1685 // Remove old root 1691 // Unlink the remaining set
1686 // 1692 //
1687 if (newSet.Contains(root)) 1693 bool sendEventsToRemainder = true;
1688 newSet.Remove(root); 1694 if (numChildren > 1)
1695 sendEventsToRemainder = false;
1689 1696
1690 // Preserve link ordering 1697 foreach (SceneObjectPart p in newSet)
1691 //
1692 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1693 { 1698 {
1694 return a.LinkNum.CompareTo(b.LinkNum); 1699 if (p != group.RootPart)
1695 }); 1700 group.DelinkFromGroup(p, sendEventsToRemainder);
1701 }
1696 1702
1697 // Determine new root 1703 // If there is more than one prim remaining, we
1704 // need to re-link
1698 // 1705 //
1699 SceneObjectPart newRoot = newSet[0]; 1706 if (numChildren > 2)
1700 newSet.RemoveAt(0); 1707 {
1708 // Remove old root
1709 //
1710 if (newSet.Contains(root))
1711 newSet.Remove(root);
1712
1713 // Preserve link ordering
1714 //
1715 newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
1716 {
1717 return a.LinkNum.CompareTo(b.LinkNum);
1718 });
1701 1719
1702 List<uint> linkIDs = new List<uint>(); 1720 // Determine new root
1721 //
1722 SceneObjectPart newRoot = newSet[0];
1723 newSet.RemoveAt(0);
1703 1724
1704 foreach (SceneObjectPart newChild in newSet) 1725 List<uint> linkIDs = new List<uint>();
1705 { 1726
1706 newChild.UpdateFlag = 0; 1727 foreach (SceneObjectPart newChild in newSet)
1707 linkIDs.Add(newChild.LocalId); 1728 {
1708 } 1729 newChild.UpdateFlag = 0;
1730 linkIDs.Add(newChild.LocalId);
1731 }
1709 1732
1710 LinkObjects(null, newRoot.LocalId, linkIDs); 1733 LinkObjects(null, newRoot.LocalId, linkIDs);
1711 if (!affectedGroups.Contains(newRoot.ParentGroup)) 1734 if (!affectedGroups.Contains(newRoot.ParentGroup))
1712 affectedGroups.Add(newRoot.ParentGroup); 1735 affectedGroups.Add(newRoot.ParentGroup);
1736 }
1713 } 1737 }
1714 } 1738 }
1715 }
1716 1739
1717 // Finally, trigger events in the roots 1740 // Finally, trigger events in the roots
1718 // 1741 //
1719 foreach (SceneObjectGroup g in affectedGroups) 1742 foreach (SceneObjectGroup g in affectedGroups)
1743 {
1744 g.TriggerScriptChangedEvent(Changed.LINK);
1745 g.HasGroupChanged = true; // Persist
1746 g.ScheduleGroupForFullUpdate();
1747 }
1748 }
1749 finally
1720 { 1750 {
1721 g.TriggerScriptChangedEvent(Changed.LINK); 1751 Monitor.Exit(m_updateLock);
1722 g.HasGroupChanged = true; // Persist
1723 g.ScheduleGroupForFullUpdate();
1724 } 1752 }
1725 } 1753 }
1726 1754
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index f36ff1d..eacd219 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -98,6 +98,72 @@ namespace OpenSim.Region.Framework.Scenes
98 private bool m_hasGroupChanged = false; 98 private bool m_hasGroupChanged = false;
99 private long timeFirstChanged; 99 private long timeFirstChanged;
100 private long timeLastChanged; 100 private long timeLastChanged;
101 private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim();
102
103 public void lockPartsForRead(bool locked)
104 {
105 if (locked)
106 {
107 if (m_partsLock.RecursiveReadCount > 0)
108 {
109 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
110 m_partsLock.ExitReadLock();
111 }
112 if (m_partsLock.RecursiveWriteCount > 0)
113 {
114 m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed.");
115 m_partsLock.ExitWriteLock();
116 }
117
118 while (!m_partsLock.TryEnterReadLock(60000))
119 {
120 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
121 if (m_partsLock.IsWriteLockHeld)
122 {
123 m_partsLock = new System.Threading.ReaderWriterLockSlim();
124 }
125 }
126 }
127 else
128 {
129 if (m_partsLock.RecursiveReadCount > 0)
130 {
131 m_partsLock.ExitReadLock();
132 }
133 }
134 }
135 public void lockPartsForWrite(bool locked)
136 {
137 if (locked)
138 {
139 if (m_partsLock.RecursiveReadCount > 0)
140 {
141 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
142 m_partsLock.ExitReadLock();
143 }
144 if (m_partsLock.RecursiveWriteCount > 0)
145 {
146 m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
147 m_partsLock.ExitWriteLock();
148 }
149
150 while (!m_partsLock.TryEnterWriteLock(60000))
151 {
152 m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
153 if (m_partsLock.IsWriteLockHeld)
154 {
155 m_partsLock = new System.Threading.ReaderWriterLockSlim();
156 }
157 }
158 }
159 else
160 {
161 if (m_partsLock.RecursiveWriteCount > 0)
162 {
163 m_partsLock.ExitWriteLock();
164 }
165 }
166 }
101 167
102 public bool HasGroupChanged 168 public bool HasGroupChanged
103 { 169 {
@@ -243,13 +309,16 @@ namespace OpenSim.Region.Framework.Scenes
243 set 309 set
244 { 310 {
245 m_regionHandle = value; 311 m_regionHandle = value;
246 lock (m_parts) 312 lockPartsForRead(true);
247 { 313 {
248 foreach (SceneObjectPart part in m_parts.Values) 314 foreach (SceneObjectPart part in m_parts.Values)
249 { 315 {
316
250 part.RegionHandle = m_regionHandle; 317 part.RegionHandle = m_regionHandle;
318
251 } 319 }
252 } 320 }
321 lockPartsForRead(false);
253 } 322 }
254 } 323 }
255 324
@@ -275,13 +344,16 @@ namespace OpenSim.Region.Framework.Scenes
275 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 344 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
276 } 345 }
277 346
278 lock (m_parts) 347 lockPartsForRead(true);
279 { 348 {
280 foreach (SceneObjectPart part in m_parts.Values) 349 foreach (SceneObjectPart part in m_parts.Values)
281 { 350 {
351
282 part.GroupPosition = val; 352 part.GroupPosition = val;
353
283 } 354 }
284 } 355 }
356 lockPartsForRead(false);
285 357
286 //if (m_rootPart.PhysActor != null) 358 //if (m_rootPart.PhysActor != null)
287 //{ 359 //{
@@ -432,13 +504,16 @@ namespace OpenSim.Region.Framework.Scenes
432 504
433 public void SetFromItemID(UUID AssetId) 505 public void SetFromItemID(UUID AssetId)
434 { 506 {
435 lock (m_parts) 507 lockPartsForRead(true);
436 { 508 {
437 foreach (SceneObjectPart part in m_parts.Values) 509 foreach (SceneObjectPart part in m_parts.Values)
438 { 510 {
511
439 part.FromItemID = AssetId; 512 part.FromItemID = AssetId;
513
440 } 514 }
441 } 515 }
516 lockPartsForRead(false);
442 } 517 }
443 518
444 public UUID GetFromItemID() 519 public UUID GetFromItemID()
@@ -505,10 +580,11 @@ namespace OpenSim.Region.Framework.Scenes
505 Vector3 maxScale = Vector3.Zero; 580 Vector3 maxScale = Vector3.Zero;
506 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); 581 Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f);
507 582
508 lock (m_parts) 583 lockPartsForRead(true);
509 { 584 {
510 foreach (SceneObjectPart part in m_parts.Values) 585 foreach (SceneObjectPart part in m_parts.Values)
511 { 586 {
587
512 Vector3 partscale = part.Scale; 588 Vector3 partscale = part.Scale;
513 Vector3 partoffset = part.OffsetPosition; 589 Vector3 partoffset = part.OffsetPosition;
514 590
@@ -519,8 +595,11 @@ namespace OpenSim.Region.Framework.Scenes
519 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; 595 maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X;
520 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; 596 maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y;
521 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; 597 maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z;
598
522 } 599 }
523 } 600 }
601 lockPartsForRead(false);
602
524 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; 603 finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X;
525 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; 604 finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y;
526 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; 605 finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z;
@@ -536,10 +615,11 @@ namespace OpenSim.Region.Framework.Scenes
536 615
537 EntityIntersection result = new EntityIntersection(); 616 EntityIntersection result = new EntityIntersection();
538 617
539 lock (m_parts) 618 lockPartsForRead(true);
540 { 619 {
541 foreach (SceneObjectPart part in m_parts.Values) 620 foreach (SceneObjectPart part in m_parts.Values)
542 { 621 {
622
543 // Temporary commented to stop compiler warning 623 // Temporary commented to stop compiler warning
544 //Vector3 partPosition = 624 //Vector3 partPosition =
545 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); 625 // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z);
@@ -567,8 +647,10 @@ namespace OpenSim.Region.Framework.Scenes
567 result.distance = inter.distance; 647 result.distance = inter.distance;
568 } 648 }
569 } 649 }
650
570 } 651 }
571 } 652 }
653 lockPartsForRead(false);
572 return result; 654 return result;
573 } 655 }
574 656
@@ -581,10 +663,11 @@ namespace OpenSim.Region.Framework.Scenes
581 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) 663 public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight)
582 { 664 {
583 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; 665 float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f;
584 lock (m_parts) 666 lockPartsForRead(true);
585 { 667 {
586 foreach (SceneObjectPart part in m_parts.Values) 668 foreach (SceneObjectPart part in m_parts.Values)
587 { 669 {
670
588 Vector3 worldPos = part.GetWorldPosition(); 671 Vector3 worldPos = part.GetWorldPosition();
589 Vector3 offset = worldPos - AbsolutePosition; 672 Vector3 offset = worldPos - AbsolutePosition;
590 Quaternion worldRot; 673 Quaternion worldRot;
@@ -643,6 +726,8 @@ namespace OpenSim.Region.Framework.Scenes
643 backBottomRight.Y = orig.Y + (part.Scale.Y / 2); 726 backBottomRight.Y = orig.Y + (part.Scale.Y / 2);
644 backBottomRight.Z = orig.Z - (part.Scale.Z / 2); 727 backBottomRight.Z = orig.Z - (part.Scale.Z / 2);
645 728
729
730
646 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); 731 //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z);
647 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); 732 //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z);
648 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); 733 //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z);
@@ -814,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
814 minZ = backBottomLeft.Z; 899 minZ = backBottomLeft.Z;
815 } 900 }
816 } 901 }
902 lockPartsForRead(false);
817 903
818 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); 904 Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ);
819 905
@@ -842,17 +928,20 @@ namespace OpenSim.Region.Framework.Scenes
842 Dictionary<UUID,string> states = new Dictionary<UUID,string>(); 928 Dictionary<UUID,string> states = new Dictionary<UUID,string>();
843 929
844 // Capture script state while holding the lock 930 // Capture script state while holding the lock
845 lock (m_parts) 931 lockPartsForRead(true);
846 { 932 {
847 foreach (SceneObjectPart part in m_parts.Values) 933 foreach (SceneObjectPart part in m_parts.Values)
848 { 934 {
935
849 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates(); 936 Dictionary<UUID,string> pstates = part.Inventory.GetScriptStates();
850 foreach (UUID itemid in pstates.Keys) 937 foreach (UUID itemid in pstates.Keys)
851 { 938 {
852 states.Add(itemid, pstates[itemid]); 939 states.Add(itemid, pstates[itemid]);
853 } 940 }
941
854 } 942 }
855 } 943 }
944 lockPartsForRead(false);
856 945
857 if (states.Count > 0) 946 if (states.Count > 0)
858 { 947 {
@@ -1014,13 +1103,16 @@ namespace OpenSim.Region.Framework.Scenes
1014 1103
1015 public override void UpdateMovement() 1104 public override void UpdateMovement()
1016 { 1105 {
1017 lock (m_parts) 1106 lockPartsForRead(true);
1018 { 1107 {
1019 foreach (SceneObjectPart part in m_parts.Values) 1108 foreach (SceneObjectPart part in m_parts.Values)
1020 { 1109 {
1110
1021 part.UpdateMovement(); 1111 part.UpdateMovement();
1112
1022 } 1113 }
1023 } 1114 }
1115 lockPartsForRead(false);
1024 } 1116 }
1025 1117
1026 public ushort GetTimeDilation() 1118 public ushort GetTimeDilation()
@@ -1064,7 +1156,7 @@ namespace OpenSim.Region.Framework.Scenes
1064 /// <param name="part"></param> 1156 /// <param name="part"></param>
1065 public void AddPart(SceneObjectPart part) 1157 public void AddPart(SceneObjectPart part)
1066 { 1158 {
1067 lock (m_parts) 1159 lockPartsForWrite(true);
1068 { 1160 {
1069 part.SetParent(this); 1161 part.SetParent(this);
1070 m_parts.Add(part.UUID, part); 1162 m_parts.Add(part.UUID, part);
@@ -1074,6 +1166,7 @@ namespace OpenSim.Region.Framework.Scenes
1074 if (part.LinkNum == 2 && RootPart != null) 1166 if (part.LinkNum == 2 && RootPart != null)
1075 RootPart.LinkNum = 1; 1167 RootPart.LinkNum = 1;
1076 } 1168 }
1169 lockPartsForWrite(false);
1077 } 1170 }
1078 1171
1079 /// <summary> 1172 /// <summary>
@@ -1081,28 +1174,33 @@ namespace OpenSim.Region.Framework.Scenes
1081 /// </summary> 1174 /// </summary>
1082 private void UpdateParentIDs() 1175 private void UpdateParentIDs()
1083 { 1176 {
1084 lock (m_parts) 1177 lockPartsForRead(true);
1085 { 1178 {
1086 foreach (SceneObjectPart part in m_parts.Values) 1179 foreach (SceneObjectPart part in m_parts.Values)
1087 { 1180 {
1181
1088 if (part.UUID != m_rootPart.UUID) 1182 if (part.UUID != m_rootPart.UUID)
1089 { 1183 {
1090 part.ParentID = m_rootPart.LocalId; 1184 part.ParentID = m_rootPart.LocalId;
1091 } 1185 }
1186
1092 } 1187 }
1093 } 1188 }
1189 lockPartsForRead(false);
1094 } 1190 }
1095 1191
1096 public void RegenerateFullIDs() 1192 public void RegenerateFullIDs()
1097 { 1193 {
1098 lock (m_parts) 1194 lockPartsForRead(true);
1099 { 1195 {
1100 foreach (SceneObjectPart part in m_parts.Values) 1196 foreach (SceneObjectPart part in m_parts.Values)
1101 { 1197 {
1198
1102 part.UUID = UUID.Random(); 1199 part.UUID = UUID.Random();
1103 1200
1104 } 1201 }
1105 } 1202 }
1203 lockPartsForRead(false);
1106 } 1204 }
1107 1205
1108 // helper provided for parts. 1206 // helper provided for parts.
@@ -1183,28 +1281,33 @@ namespace OpenSim.Region.Framework.Scenes
1183 1281
1184 DetachFromBackup(); 1282 DetachFromBackup();
1185 1283
1186 lock (m_parts) 1284 lockPartsForRead(true);
1285 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1286 lockPartsForRead(false);
1287
1288 foreach (SceneObjectPart part in values)
1187 { 1289 {
1188 foreach (SceneObjectPart part in m_parts.Values)
1189 {
1190// part.Inventory.RemoveScriptInstances(); 1290// part.Inventory.RemoveScriptInstances();
1191 1291
1192 ScenePresence[] avatars = Scene.GetScenePresences(); 1292 ScenePresence[] avatars = Scene.GetScenePresences();
1193 for (int i = 0; i < avatars.Length; i++) 1293 for (int i = 0; i < avatars.Length; i++)
1294 {
1295 if (avatars[i].ParentID == LocalId)
1194 { 1296 {
1195 if (avatars[i].ParentID == LocalId) 1297 avatars[i].StandUp();
1196 { 1298 }
1197 avatars[i].StandUp();
1198 }
1199 1299
1200 if (!silent) 1300 if (!silent)
1201 { 1301 {
1202 if (part == m_rootPart) 1302 part.UpdateFlag = 0;
1203 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); 1303 if (part == m_rootPart)
1204 } 1304 avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId);
1205 } 1305 }
1206 } 1306 }
1307
1207 } 1308 }
1309
1310
1208 } 1311 }
1209 1312
1210 public void AddScriptLPS(int count) 1313 public void AddScriptLPS(int count)
@@ -1229,17 +1332,20 @@ namespace OpenSim.Region.Framework.Scenes
1229 1332
1230 scriptEvents aggregateScriptEvents=0; 1333 scriptEvents aggregateScriptEvents=0;
1231 1334
1232 lock (m_parts) 1335 lockPartsForRead(true);
1233 { 1336 {
1234 foreach (SceneObjectPart part in m_parts.Values) 1337 foreach (SceneObjectPart part in m_parts.Values)
1235 { 1338 {
1339
1236 if (part == null) 1340 if (part == null)
1237 continue; 1341 continue;
1238 if (part != RootPart) 1342 if (part != RootPart)
1239 part.ObjectFlags = objectflagupdate; 1343 part.ObjectFlags = objectflagupdate;
1240 aggregateScriptEvents |= part.AggregateScriptEvents; 1344 aggregateScriptEvents |= part.AggregateScriptEvents;
1345
1241 } 1346 }
1242 } 1347 }
1348 lockPartsForRead(false);
1243 1349
1244 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); 1350 m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0);
1245 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); 1351 m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0);
@@ -1272,42 +1378,52 @@ namespace OpenSim.Region.Framework.Scenes
1272 /// <param name="m_physicalPrim"></param> 1378 /// <param name="m_physicalPrim"></param>
1273 public void ApplyPhysics(bool m_physicalPrim) 1379 public void ApplyPhysics(bool m_physicalPrim)
1274 { 1380 {
1275 lock (m_parts) 1381 lockPartsForRead(true);
1382
1383 if (m_parts.Count > 1)
1276 { 1384 {
1277 if (m_parts.Count > 1) 1385 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1386 lockPartsForRead(false);
1387 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1388 foreach (SceneObjectPart part in values)
1278 { 1389 {
1279 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); 1390
1280 foreach (SceneObjectPart part in m_parts.Values) 1391 if (part.LocalId != m_rootPart.LocalId)
1281 { 1392 {
1282 if (part.LocalId != m_rootPart.LocalId) 1393 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1283 {
1284 part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim);
1285 }
1286 } 1394 }
1287 1395
1288 // Hack to get the physics scene geometries in the right spot
1289 ResetChildPrimPhysicsPositions();
1290 }
1291 else
1292 {
1293 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1294 } 1396 }
1397 // Hack to get the physics scene geometries in the right spot
1398 ResetChildPrimPhysicsPositions();
1399 }
1400 else
1401 {
1402 lockPartsForRead(false);
1403 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim);
1295 } 1404 }
1296 } 1405 }
1297 1406
1298 public void SetOwnerId(UUID userId) 1407 public void SetOwnerId(UUID userId)
1299 { 1408 {
1300 ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); 1409 ForEachPart(delegate(SceneObjectPart part)
1410 {
1411
1412 part.OwnerID = userId;
1413
1414 });
1301 } 1415 }
1302 1416
1303 public void ForEachPart(Action<SceneObjectPart> whatToDo) 1417 public void ForEachPart(Action<SceneObjectPart> whatToDo)
1304 { 1418 {
1305 lock (m_parts) 1419 lockPartsForRead(true);
1420 List<SceneObjectPart> values = new List<SceneObjectPart>(m_parts.Values);
1421 lockPartsForRead(false);
1422 foreach (SceneObjectPart part in values)
1306 { 1423 {
1307 foreach (SceneObjectPart part in m_parts.Values) 1424
1308 { 1425 whatToDo(part);
1309 whatToDo(part); 1426
1310 }
1311 } 1427 }
1312 } 1428 }
1313 1429
@@ -1406,14 +1522,17 @@ namespace OpenSim.Region.Framework.Scenes
1406 { 1522 {
1407 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); 1523 SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID));
1408 1524
1409 lock (m_parts) 1525 lockPartsForRead(true);
1410 { 1526 {
1411 foreach (SceneObjectPart part in m_parts.Values) 1527 foreach (SceneObjectPart part in m_parts.Values)
1412 { 1528 {
1529
1413 if (part != RootPart) 1530 if (part != RootPart)
1414 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); 1531 SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID));
1532
1415 } 1533 }
1416 } 1534 }
1535 lockPartsForRead(false);
1417 } 1536 }
1418 1537
1419 /// <summary> 1538 /// <summary>
@@ -1508,10 +1627,11 @@ namespace OpenSim.Region.Framework.Scenes
1508 1627
1509 List<SceneObjectPart> partList; 1628 List<SceneObjectPart> partList;
1510 1629
1511 lock (m_parts) 1630 lockPartsForRead(true);
1512 { 1631
1513 partList = new List<SceneObjectPart>(m_parts.Values); 1632 partList = new List<SceneObjectPart>(m_parts.Values);
1514 } 1633
1634 lockPartsForRead(false);
1515 1635
1516 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) 1636 partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2)
1517 { 1637 {
@@ -1834,10 +1954,11 @@ namespace OpenSim.Region.Framework.Scenes
1834 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); 1954 SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed);
1835 newPart.SetParent(this); 1955 newPart.SetParent(this);
1836 1956
1837 lock (m_parts) 1957 lockPartsForWrite(true);
1838 { 1958 {
1839 m_parts.Add(newPart.UUID, newPart); 1959 m_parts.Add(newPart.UUID, newPart);
1840 } 1960 }
1961 lockPartsForWrite(false);
1841 1962
1842 SetPartAsNonRoot(newPart); 1963 SetPartAsNonRoot(newPart);
1843 1964
@@ -1900,7 +2021,7 @@ namespace OpenSim.Region.Framework.Scenes
1900 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) 2021 //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0)
1901 // return; 2022 // return;
1902 2023
1903 lock (m_parts) 2024 lockPartsForRead(true);
1904 { 2025 {
1905 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); 2026 bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0);
1906 2027
@@ -1918,34 +2039,43 @@ namespace OpenSim.Region.Framework.Scenes
1918 2039
1919 foreach (SceneObjectPart part in m_parts.Values) 2040 foreach (SceneObjectPart part in m_parts.Values)
1920 { 2041 {
2042
1921 part.SendScheduledUpdates(); 2043 part.SendScheduledUpdates();
2044
1922 } 2045 }
1923 } 2046 }
2047 lockPartsForRead(false);
1924 } 2048 }
1925 2049
1926 public void ScheduleFullUpdateToAvatar(ScenePresence presence) 2050 public void ScheduleFullUpdateToAvatar(ScenePresence presence)
1927 { 2051 {
1928 RootPart.AddFullUpdateToAvatar(presence); 2052 RootPart.AddFullUpdateToAvatar(presence);
1929 2053
1930 lock (m_parts) 2054 lockPartsForRead(true);
1931 { 2055 {
1932 foreach (SceneObjectPart part in m_parts.Values) 2056 foreach (SceneObjectPart part in m_parts.Values)
1933 { 2057 {
2058
1934 if (part != RootPart) 2059 if (part != RootPart)
1935 part.AddFullUpdateToAvatar(presence); 2060 part.AddFullUpdateToAvatar(presence);
2061
1936 } 2062 }
1937 } 2063 }
2064 lockPartsForRead(false);
1938 } 2065 }
1939 2066
1940 public void ScheduleTerseUpdateToAvatar(ScenePresence presence) 2067 public void ScheduleTerseUpdateToAvatar(ScenePresence presence)
1941 { 2068 {
1942 lock (m_parts) 2069 lockPartsForRead(true);
1943 { 2070 {
1944 foreach (SceneObjectPart part in m_parts.Values) 2071 foreach (SceneObjectPart part in m_parts.Values)
1945 { 2072 {
2073
1946 part.AddTerseUpdateToAvatar(presence); 2074 part.AddTerseUpdateToAvatar(presence);
2075
1947 } 2076 }
1948 } 2077 }
2078 lockPartsForRead(false);
1949 } 2079 }
1950 2080
1951 /// <summary> 2081 /// <summary>
@@ -1956,14 +2086,17 @@ namespace OpenSim.Region.Framework.Scenes
1956 checkAtTargets(); 2086 checkAtTargets();
1957 RootPart.ScheduleFullUpdate(); 2087 RootPart.ScheduleFullUpdate();
1958 2088
1959 lock (m_parts) 2089 lockPartsForRead(true);
1960 { 2090 {
1961 foreach (SceneObjectPart part in m_parts.Values) 2091 foreach (SceneObjectPart part in m_parts.Values)
1962 { 2092 {
2093
1963 if (part != RootPart) 2094 if (part != RootPart)
1964 part.ScheduleFullUpdate(); 2095 part.ScheduleFullUpdate();
2096
1965 } 2097 }
1966 } 2098 }
2099 lockPartsForRead(false);
1967 } 2100 }
1968 2101
1969 /// <summary> 2102 /// <summary>
@@ -1971,13 +2104,16 @@ namespace OpenSim.Region.Framework.Scenes
1971 /// </summary> 2104 /// </summary>
1972 public void ScheduleGroupForTerseUpdate() 2105 public void ScheduleGroupForTerseUpdate()
1973 { 2106 {
1974 lock (m_parts) 2107 lockPartsForRead(true);
1975 { 2108 {
1976 foreach (SceneObjectPart part in m_parts.Values) 2109 foreach (SceneObjectPart part in m_parts.Values)
1977 { 2110 {
2111
1978 part.ScheduleTerseUpdate(); 2112 part.ScheduleTerseUpdate();
2113
1979 } 2114 }
1980 } 2115 }
2116 lockPartsForRead(false);
1981 } 2117 }
1982 2118
1983 /// <summary> 2119 /// <summary>
@@ -1990,14 +2126,17 @@ namespace OpenSim.Region.Framework.Scenes
1990 2126
1991 RootPart.SendFullUpdateToAllClients(); 2127 RootPart.SendFullUpdateToAllClients();
1992 2128
1993 lock (m_parts) 2129 lockPartsForRead(true);
1994 { 2130 {
1995 foreach (SceneObjectPart part in m_parts.Values) 2131 foreach (SceneObjectPart part in m_parts.Values)
1996 { 2132 {
2133
1997 if (part != RootPart) 2134 if (part != RootPart)
1998 part.SendFullUpdateToAllClients(); 2135 part.SendFullUpdateToAllClients();
2136
1999 } 2137 }
2000 } 2138 }
2139 lockPartsForRead(false);
2001 } 2140 }
2002 2141
2003 /// <summary> 2142 /// <summary>
@@ -2028,14 +2167,15 @@ namespace OpenSim.Region.Framework.Scenes
2028 { 2167 {
2029 if (IsDeleted) 2168 if (IsDeleted)
2030 return; 2169 return;
2031 2170
2032 lock (m_parts) 2171 lockPartsForRead(true);
2033 { 2172 {
2034 foreach (SceneObjectPart part in m_parts.Values) 2173 foreach (SceneObjectPart part in m_parts.Values)
2035 { 2174 {
2036 part.SendTerseUpdateToAllClients(); 2175 part.SendTerseUpdateToAllClients();
2037 } 2176 }
2038 } 2177 }
2178 lockPartsForRead(false);
2039 } 2179 }
2040 2180
2041 #endregion 2181 #endregion
@@ -2049,16 +2189,18 @@ namespace OpenSim.Region.Framework.Scenes
2049 /// <returns>null if no child part with that linknum or child part</returns> 2189 /// <returns>null if no child part with that linknum or child part</returns>
2050 public SceneObjectPart GetLinkNumPart(int linknum) 2190 public SceneObjectPart GetLinkNumPart(int linknum)
2051 { 2191 {
2052 lock (m_parts) 2192 lockPartsForRead(true);
2053 { 2193 {
2054 foreach (SceneObjectPart part in m_parts.Values) 2194 foreach (SceneObjectPart part in m_parts.Values)
2055 { 2195 {
2056 if (part.LinkNum == linknum) 2196 if (part.LinkNum == linknum)
2057 { 2197 {
2198 lockPartsForRead(false);
2058 return part; 2199 return part;
2059 } 2200 }
2060 } 2201 }
2061 } 2202 }
2203 lockPartsForRead(false);
2062 2204
2063 return null; 2205 return null;
2064 } 2206 }
@@ -2086,17 +2228,19 @@ namespace OpenSim.Region.Framework.Scenes
2086 public SceneObjectPart GetChildPart(uint localID) 2228 public SceneObjectPart GetChildPart(uint localID)
2087 { 2229 {
2088 //m_log.DebugFormat("Entered looking for {0}", localID); 2230 //m_log.DebugFormat("Entered looking for {0}", localID);
2089 lock (m_parts) 2231 lockPartsForRead(true);
2090 { 2232 {
2091 foreach (SceneObjectPart part in m_parts.Values) 2233 foreach (SceneObjectPart part in m_parts.Values)
2092 { 2234 {
2093 //m_log.DebugFormat("Found {0}", part.LocalId); 2235 //m_log.DebugFormat("Found {0}", part.LocalId);
2094 if (part.LocalId == localID) 2236 if (part.LocalId == localID)
2095 { 2237 {
2238 lockPartsForRead(false);
2096 return part; 2239 return part;
2097 } 2240 }
2098 } 2241 }
2099 } 2242 }
2243 lockPartsForRead(false);
2100 2244
2101 return null; 2245 return null;
2102 } 2246 }
@@ -2126,17 +2270,19 @@ namespace OpenSim.Region.Framework.Scenes
2126 public bool HasChildPrim(uint localID) 2270 public bool HasChildPrim(uint localID)
2127 { 2271 {
2128 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); 2272 //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID);
2129 lock (m_parts) 2273 lockPartsForRead(true);
2130 { 2274 {
2131 foreach (SceneObjectPart part in m_parts.Values) 2275 foreach (SceneObjectPart part in m_parts.Values)
2132 { 2276 {
2133 //m_log.DebugFormat("Found {0}", part.LocalId); 2277 //m_log.DebugFormat("Found {0}", part.LocalId);
2134 if (part.LocalId == localID) 2278 if (part.LocalId == localID)
2135 { 2279 {
2280 lockPartsForRead(false);
2136 return true; 2281 return true;
2137 } 2282 }
2138 } 2283 }
2139 } 2284 }
2285 lockPartsForRead(false);
2140 2286
2141 return false; 2287 return false;
2142 } 2288 }
@@ -2152,14 +2298,14 @@ namespace OpenSim.Region.Framework.Scenes
2152 public void LinkToGroup(SceneObjectGroup objectGroup) 2298 public void LinkToGroup(SceneObjectGroup objectGroup)
2153 { 2299 {
2154 // Make sure we have sent any pending unlinks or stuff. 2300 // Make sure we have sent any pending unlinks or stuff.
2155 if (objectGroup.RootPart.UpdateFlag > 0) 2301 //if (objectGroup.RootPart.UpdateFlag > 0)
2156 { 2302 //{
2157 m_log.WarnFormat( 2303 // m_log.WarnFormat(
2158 "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", 2304 // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.",
2159 objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); 2305 // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID);
2160 2306
2161 objectGroup.RootPart.SendScheduledUpdates(); 2307 // objectGroup.RootPart.SendScheduledUpdates();
2162 } 2308 //}
2163 2309
2164// m_log.DebugFormat( 2310// m_log.DebugFormat(
2165// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", 2311// "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}",
@@ -2186,53 +2332,57 @@ namespace OpenSim.Region.Framework.Scenes
2186 if (m_rootPart.LinkNum == 0) 2332 if (m_rootPart.LinkNum == 0)
2187 m_rootPart.LinkNum = 1; 2333 m_rootPart.LinkNum = 1;
2188 2334
2189 lock (m_parts) 2335 lockPartsForWrite(true);
2190 { 2336
2191 m_parts.Add(linkPart.UUID, linkPart); 2337 m_parts.Add(linkPart.UUID, linkPart);
2338
2339 lockPartsForWrite(false);
2192 2340
2193 // Insert in terms of link numbers, the new links 2341 // Insert in terms of link numbers, the new links
2194 // before the current ones (with the exception of 2342 // before the current ones (with the exception of
2195 // the root prim. Shuffle the old ones up 2343 // the root prim. Shuffle the old ones up
2196 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts) 2344 lockPartsForRead(true);
2345 foreach (KeyValuePair<UUID, SceneObjectPart> kvp in m_parts)
2346 {
2347 if (kvp.Value.LinkNum != 1)
2197 { 2348 {
2198 if (kvp.Value.LinkNum != 1) 2349 // Don't update root prim link number
2199 { 2350 kvp.Value.LinkNum += objectGroup.PrimCount;
2200 // Don't update root prim link number
2201 kvp.Value.LinkNum += objectGroup.PrimCount;
2202 }
2203 } 2351 }
2352 }
2353 lockPartsForRead(false);
2204 2354
2205 linkPart.LinkNum = 2; 2355 linkPart.LinkNum = 2;
2206 2356
2207 linkPart.SetParent(this); 2357 linkPart.SetParent(this);
2208 linkPart.AddFlag(PrimFlags.CreateSelected); 2358 linkPart.AddFlag(PrimFlags.CreateSelected);
2209 2359
2210 //if (linkPart.PhysActor != null) 2360 //if (linkPart.PhysActor != null)
2211 //{ 2361 //{
2212 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); 2362 // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor);
2213 2363
2214 //linkPart.PhysActor = null; 2364 //linkPart.PhysActor = null;
2215 //} 2365 //}
2216 2366
2217 //TODO: rest of parts 2367 //TODO: rest of parts
2218 int linkNum = 3; 2368 int linkNum = 3;
2219 foreach (SceneObjectPart part in objectGroup.Children.Values) 2369 foreach (SceneObjectPart part in objectGroup.Children.Values)
2370 {
2371 if (part.UUID != objectGroup.m_rootPart.UUID)
2220 { 2372 {
2221 if (part.UUID != objectGroup.m_rootPart.UUID) 2373 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2222 {
2223 LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++);
2224 }
2225 part.ClearUndoState();
2226 } 2374 }
2375 part.ClearUndoState();
2227 } 2376 }
2228 2377
2229 m_scene.UnlinkSceneObject(objectGroup.UUID, true); 2378 m_scene.UnlinkSceneObject(objectGroup.UUID, true);
2230 objectGroup.m_isDeleted = true; 2379 objectGroup.m_isDeleted = true;
2380
2381 objectGroup.lockPartsForWrite(true);
2231 2382
2232 lock (objectGroup.m_parts) 2383 objectGroup.m_parts.Clear();
2233 { 2384
2234 objectGroup.m_parts.Clear(); 2385 objectGroup.lockPartsForWrite(false);
2235 }
2236 2386
2237 // Can't do this yet since backup still makes use of the root part without any synchronization 2387 // Can't do this yet since backup still makes use of the root part without any synchronization
2238// objectGroup.m_rootPart = null; 2388// objectGroup.m_rootPart = null;
@@ -2245,8 +2395,8 @@ namespace OpenSim.Region.Framework.Scenes
2245 // unmoved prims! 2395 // unmoved prims!
2246 ResetChildPrimPhysicsPositions(); 2396 ResetChildPrimPhysicsPositions();
2247 2397
2248 HasGroupChanged = true; 2398 //HasGroupChanged = true;
2249 ScheduleGroupForFullUpdate(); 2399 //ScheduleGroupForFullUpdate();
2250 } 2400 }
2251 2401
2252 /// <summary> 2402 /// <summary>
@@ -2291,11 +2441,12 @@ namespace OpenSim.Region.Framework.Scenes
2291 Quaternion worldRot = linkPart.GetWorldRotation(); 2441 Quaternion worldRot = linkPart.GetWorldRotation();
2292 2442
2293 // Remove the part from this object 2443 // Remove the part from this object
2294 lock (m_parts) 2444 lockPartsForWrite(true);
2295 { 2445 {
2296 m_parts.Remove(linkPart.UUID); 2446 m_parts.Remove(linkPart.UUID);
2297 } 2447 }
2298 2448 lockPartsForWrite(false);
2449 lockPartsForRead(true);
2299 if (m_parts.Count == 1 && RootPart != null) //Single prim is left 2450 if (m_parts.Count == 1 && RootPart != null) //Single prim is left
2300 RootPart.LinkNum = 0; 2451 RootPart.LinkNum = 0;
2301 else 2452 else
@@ -2306,6 +2457,7 @@ namespace OpenSim.Region.Framework.Scenes
2306 p.LinkNum--; 2457 p.LinkNum--;
2307 } 2458 }
2308 } 2459 }
2460 lockPartsForRead(false);
2309 2461
2310 linkPart.ParentID = 0; 2462 linkPart.ParentID = 0;
2311 linkPart.LinkNum = 0; 2463 linkPart.LinkNum = 0;
@@ -2337,8 +2489,8 @@ namespace OpenSim.Region.Framework.Scenes
2337 2489
2338 linkPart.Rezzed = RootPart.Rezzed; 2490 linkPart.Rezzed = RootPart.Rezzed;
2339 2491
2340 HasGroupChanged = true; 2492 //HasGroupChanged = true;
2341 ScheduleGroupForFullUpdate(); 2493 //ScheduleGroupForFullUpdate();
2342 } 2494 }
2343 2495
2344 /// <summary> 2496 /// <summary>
@@ -2623,22 +2775,28 @@ namespace OpenSim.Region.Framework.Scenes
2623 2775
2624 if (selectionPart != null) 2776 if (selectionPart != null)
2625 { 2777 {
2626 lock (m_parts) 2778 lockPartsForRead(true);
2779 List<SceneObjectPart> parts = new List<SceneObjectPart>(m_parts.Values);
2780 lockPartsForRead(false);
2781 foreach (SceneObjectPart part in parts)
2627 { 2782 {
2628 foreach (SceneObjectPart part in m_parts.Values) 2783 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0)
2629 { 2784 {
2630 if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) 2785 if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax ||
2786 part.Scale.Y > m_scene.RegionInfo.PhysPrimMax ||
2787 part.Scale.Z > m_scene.RegionInfo.PhysPrimMax)
2631 { 2788 {
2632 UsePhysics = false; // Reset physics 2789 UsePhysics = false; // Reset physics
2633 break; 2790 break;
2634 } 2791 }
2635 } 2792 }
2793 }
2636 2794
2637 foreach (SceneObjectPart part in m_parts.Values) 2795 foreach (SceneObjectPart part in parts)
2638 { 2796 {
2639 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 2797 part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
2640 }
2641 } 2798 }
2799
2642 } 2800 }
2643 } 2801 }
2644 2802
@@ -2724,11 +2882,9 @@ namespace OpenSim.Region.Framework.Scenes
2724 scale.Y = m_scene.m_maxNonphys; 2882 scale.Y = m_scene.m_maxNonphys;
2725 if (scale.Z > m_scene.m_maxNonphys) 2883 if (scale.Z > m_scene.m_maxNonphys)
2726 scale.Z = m_scene.m_maxNonphys; 2884 scale.Z = m_scene.m_maxNonphys;
2727
2728 SceneObjectPart part = GetChildPart(localID); 2885 SceneObjectPart part = GetChildPart(localID);
2729 if (part != null) 2886 if (part != null)
2730 { 2887 {
2731 part.Resize(scale);
2732 if (part.PhysActor != null) 2888 if (part.PhysActor != null)
2733 { 2889 {
2734 if (part.PhysActor.IsPhysical) 2890 if (part.PhysActor.IsPhysical)
@@ -2743,7 +2899,7 @@ namespace OpenSim.Region.Framework.Scenes
2743 part.PhysActor.Size = scale; 2899 part.PhysActor.Size = scale;
2744 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); 2900 m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor);
2745 } 2901 }
2746 //if (part.UUID != m_rootPart.UUID) 2902 part.Resize(scale);
2747 2903
2748 HasGroupChanged = true; 2904 HasGroupChanged = true;
2749 ScheduleGroupForFullUpdate(); 2905 ScheduleGroupForFullUpdate();
@@ -2784,77 +2940,76 @@ namespace OpenSim.Region.Framework.Scenes
2784 float y = (scale.Y / part.Scale.Y); 2940 float y = (scale.Y / part.Scale.Y);
2785 float z = (scale.Z / part.Scale.Z); 2941 float z = (scale.Z / part.Scale.Z);
2786 2942
2787 lock (m_parts) 2943 lockPartsForRead(true);
2944 if (x > 1.0f || y > 1.0f || z > 1.0f)
2788 { 2945 {
2789 if (x > 1.0f || y > 1.0f || z > 1.0f) 2946 foreach (SceneObjectPart obPart in m_parts.Values)
2790 { 2947 {
2791 foreach (SceneObjectPart obPart in m_parts.Values) 2948 if (obPart.UUID != m_rootPart.UUID)
2792 { 2949 {
2793 if (obPart.UUID != m_rootPart.UUID) 2950 Vector3 oldSize = new Vector3(obPart.Scale);
2794 {
2795 Vector3 oldSize = new Vector3(obPart.Scale);
2796 2951
2797 float f = 1.0f; 2952 float f = 1.0f;
2798 float a = 1.0f; 2953 float a = 1.0f;
2799 2954
2800 if (part.PhysActor != null && part.PhysActor.IsPhysical) 2955 if (part.PhysActor != null && part.PhysActor.IsPhysical)
2956 {
2957 if (oldSize.X*x > m_scene.m_maxPhys)
2801 { 2958 {
2802 if (oldSize.X*x > m_scene.m_maxPhys) 2959 f = m_scene.m_maxPhys / oldSize.X;
2803 { 2960 a = f / x;
2804 f = m_scene.m_maxPhys / oldSize.X; 2961 x *= a;
2805 a = f / x; 2962 y *= a;
2806 x *= a; 2963 z *= a;
2807 y *= a;
2808 z *= a;
2809 }
2810 if (oldSize.Y*y > m_scene.m_maxPhys)
2811 {
2812 f = m_scene.m_maxPhys / oldSize.Y;
2813 a = f / y;
2814 x *= a;
2815 y *= a;
2816 z *= a;
2817 }
2818 if (oldSize.Z*z > m_scene.m_maxPhys)
2819 {
2820 f = m_scene.m_maxPhys / oldSize.Z;
2821 a = f / z;
2822 x *= a;
2823 y *= a;
2824 z *= a;
2825 }
2826 } 2964 }
2827 else 2965 if (oldSize.Y*y > m_scene.m_maxPhys)
2828 { 2966 {
2829 if (oldSize.X*x > m_scene.m_maxNonphys) 2967 f = m_scene.m_maxPhys / oldSize.Y;
2830 { 2968 a = f / y;
2831 f = m_scene.m_maxNonphys / oldSize.X; 2969 x *= a;
2832 a = f / x; 2970 y *= a;
2833 x *= a; 2971 z *= a;
2834 y *= a; 2972 }
2835 z *= a; 2973 if (oldSize.Z*z > m_scene.m_maxPhys)
2836 } 2974 {
2837 if (oldSize.Y*y > m_scene.m_maxNonphys) 2975 f = m_scene.m_maxPhys / oldSize.Z;
2838 { 2976 a = f / z;
2839 f = m_scene.m_maxNonphys / oldSize.Y; 2977 x *= a;
2840 a = f / y; 2978 y *= a;
2841 x *= a; 2979 z *= a;
2842 y *= a; 2980 }
2843 z *= a; 2981 }
2844 } 2982 else
2845 if (oldSize.Z*z > m_scene.m_maxNonphys) 2983 {
2846 { 2984 if (oldSize.X*x > m_scene.m_maxNonphys)
2847 f = m_scene.m_maxNonphys / oldSize.Z; 2985 {
2848 a = f / z; 2986 f = m_scene.m_maxNonphys / oldSize.X;
2849 x *= a; 2987 a = f / x;
2850 y *= a; 2988 x *= a;
2851 z *= a; 2989 y *= a;
2852 } 2990 z *= a;
2991 }
2992 if (oldSize.Y*y > m_scene.m_maxNonphys)
2993 {
2994 f = m_scene.m_maxNonphys / oldSize.Y;
2995 a = f / y;
2996 x *= a;
2997 y *= a;
2998 z *= a;
2999 }
3000 if (oldSize.Z*z > m_scene.m_maxNonphys)
3001 {
3002 f = m_scene.m_maxNonphys / oldSize.Z;
3003 a = f / z;
3004 x *= a;
3005 y *= a;
3006 z *= a;
2853 } 3007 }
2854 } 3008 }
2855 } 3009 }
2856 } 3010 }
2857 } 3011 }
3012 lockPartsForRead(false);
2858 3013
2859 Vector3 prevScale = part.Scale; 3014 Vector3 prevScale = part.Scale;
2860 prevScale.X *= x; 3015 prevScale.X *= x;
@@ -2862,7 +3017,7 @@ namespace OpenSim.Region.Framework.Scenes
2862 prevScale.Z *= z; 3017 prevScale.Z *= z;
2863 part.Resize(prevScale); 3018 part.Resize(prevScale);
2864 3019
2865 lock (m_parts) 3020 lockPartsForRead(true);
2866 { 3021 {
2867 foreach (SceneObjectPart obPart in m_parts.Values) 3022 foreach (SceneObjectPart obPart in m_parts.Values)
2868 { 3023 {
@@ -2881,6 +3036,7 @@ namespace OpenSim.Region.Framework.Scenes
2881 } 3036 }
2882 } 3037 }
2883 } 3038 }
3039 lockPartsForRead(false);
2884 3040
2885 if (part.PhysActor != null) 3041 if (part.PhysActor != null)
2886 { 3042 {
@@ -2961,7 +3117,7 @@ namespace OpenSim.Region.Framework.Scenes
2961 axDiff *= Quaternion.Inverse(partRotation); 3117 axDiff *= Quaternion.Inverse(partRotation);
2962 diff = axDiff; 3118 diff = axDiff;
2963 3119
2964 lock (m_parts) 3120 lockPartsForRead(true);
2965 { 3121 {
2966 foreach (SceneObjectPart obPart in m_parts.Values) 3122 foreach (SceneObjectPart obPart in m_parts.Values)
2967 { 3123 {
@@ -2971,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes
2971 } 3127 }
2972 } 3128 }
2973 } 3129 }
3130 lockPartsForRead(false);
2974 3131
2975 AbsolutePosition = newPos; 3132 AbsolutePosition = newPos;
2976 3133
@@ -3088,7 +3245,7 @@ namespace OpenSim.Region.Framework.Scenes
3088 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); 3245 m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
3089 } 3246 }
3090 3247
3091 lock (m_parts) 3248 lockPartsForRead(true);
3092 { 3249 {
3093 foreach (SceneObjectPart prim in m_parts.Values) 3250 foreach (SceneObjectPart prim in m_parts.Values)
3094 { 3251 {
@@ -3106,6 +3263,7 @@ namespace OpenSim.Region.Framework.Scenes
3106 } 3263 }
3107 } 3264 }
3108 } 3265 }
3266 lockPartsForRead(false);
3109 3267
3110 m_rootPart.ScheduleTerseUpdate(); 3268 m_rootPart.ScheduleTerseUpdate();
3111 } 3269 }
@@ -3204,7 +3362,7 @@ namespace OpenSim.Region.Framework.Scenes
3204 if (atTargets.Count > 0) 3362 if (atTargets.Count > 0)
3205 { 3363 {
3206 uint[] localids = new uint[0]; 3364 uint[] localids = new uint[0];
3207 lock (m_parts) 3365 lockPartsForRead(true);
3208 { 3366 {
3209 localids = new uint[m_parts.Count]; 3367 localids = new uint[m_parts.Count];
3210 int cntr = 0; 3368 int cntr = 0;
@@ -3214,6 +3372,7 @@ namespace OpenSim.Region.Framework.Scenes
3214 cntr++; 3372 cntr++;
3215 } 3373 }
3216 } 3374 }
3375 lockPartsForRead(false);
3217 3376
3218 for (int ctr = 0; ctr < localids.Length; ctr++) 3377 for (int ctr = 0; ctr < localids.Length; ctr++)
3219 { 3378 {
@@ -3232,7 +3391,7 @@ namespace OpenSim.Region.Framework.Scenes
3232 { 3391 {
3233 //trigger not_at_target 3392 //trigger not_at_target
3234 uint[] localids = new uint[0]; 3393 uint[] localids = new uint[0];
3235 lock (m_parts) 3394 lockPartsForRead(true);
3236 { 3395 {
3237 localids = new uint[m_parts.Count]; 3396 localids = new uint[m_parts.Count];
3238 int cntr = 0; 3397 int cntr = 0;
@@ -3242,7 +3401,8 @@ namespace OpenSim.Region.Framework.Scenes
3242 cntr++; 3401 cntr++;
3243 } 3402 }
3244 } 3403 }
3245 3404 lockPartsForRead(false);
3405
3246 for (int ctr = 0; ctr < localids.Length; ctr++) 3406 for (int ctr = 0; ctr < localids.Length; ctr++)
3247 { 3407 {
3248 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); 3408 m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]);
@@ -3255,19 +3415,20 @@ namespace OpenSim.Region.Framework.Scenes
3255 public float GetMass() 3415 public float GetMass()
3256 { 3416 {
3257 float retmass = 0f; 3417 float retmass = 0f;
3258 lock (m_parts) 3418 lockPartsForRead(true);
3259 { 3419 {
3260 foreach (SceneObjectPart part in m_parts.Values) 3420 foreach (SceneObjectPart part in m_parts.Values)
3261 { 3421 {
3262 retmass += part.GetMass(); 3422 retmass += part.GetMass();
3263 } 3423 }
3264 } 3424 }
3425 lockPartsForRead(false);
3265 return retmass; 3426 return retmass;
3266 } 3427 }
3267 3428
3268 public void CheckSculptAndLoad() 3429 public void CheckSculptAndLoad()
3269 { 3430 {
3270 lock (m_parts) 3431 lockPartsForRead(true);
3271 { 3432 {
3272 if (!IsDeleted) 3433 if (!IsDeleted)
3273 { 3434 {
@@ -3292,6 +3453,7 @@ namespace OpenSim.Region.Framework.Scenes
3292 } 3453 }
3293 } 3454 }
3294 } 3455 }
3456 lockPartsForRead(false);
3295 } 3457 }
3296 3458
3297 protected void AssetReceived(string id, Object sender, AssetBase asset) 3459 protected void AssetReceived(string id, Object sender, AssetBase asset)
@@ -3312,7 +3474,7 @@ namespace OpenSim.Region.Framework.Scenes
3312 /// <param name="client"></param> 3474 /// <param name="client"></param>
3313 public void SetGroup(UUID GroupID, IClientAPI client) 3475 public void SetGroup(UUID GroupID, IClientAPI client)
3314 { 3476 {
3315 lock (m_parts) 3477 lockPartsForRead(true);
3316 { 3478 {
3317 foreach (SceneObjectPart part in m_parts.Values) 3479 foreach (SceneObjectPart part in m_parts.Values)
3318 { 3480 {
@@ -3322,7 +3484,7 @@ namespace OpenSim.Region.Framework.Scenes
3322 3484
3323 HasGroupChanged = true; 3485 HasGroupChanged = true;
3324 } 3486 }
3325 3487 lockPartsForRead(false);
3326 ScheduleGroupForFullUpdate(); 3488 ScheduleGroupForFullUpdate();
3327 } 3489 }
3328 3490
@@ -3341,11 +3503,12 @@ namespace OpenSim.Region.Framework.Scenes
3341 3503
3342 public void SetAttachmentPoint(byte point) 3504 public void SetAttachmentPoint(byte point)
3343 { 3505 {
3344 lock (m_parts) 3506 lockPartsForRead(true);
3345 { 3507 {
3346 foreach (SceneObjectPart part in m_parts.Values) 3508 foreach (SceneObjectPart part in m_parts.Values)
3347 part.SetAttachmentPoint(point); 3509 part.SetAttachmentPoint(point);
3348 } 3510 }
3511 lockPartsForRead(false);
3349 } 3512 }
3350 3513
3351 #region ISceneObject 3514 #region ISceneObject
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index eca8588..b57d912 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -269,8 +269,9 @@ namespace OpenSim.Region.Framework.Scenes
269 { 269 {
270 m_log.ErrorFormat( 270 m_log.ErrorFormat(
271 "[PRIM INVENTORY]: " + 271 "[PRIM INVENTORY]: " +
272 "Couldn't start script {0}, {1} since asset ID {2} could not be found", 272 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
273 item.Name, item.ItemID, item.AssetID); 273 item.Name, item.ItemID, m_part.AbsolutePosition,
274 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
274 } 275 }
275 else 276 else
276 { 277 {
@@ -317,9 +318,20 @@ namespace OpenSim.Region.Framework.Scenes
317 m_items.LockItemsForRead(true); 318 m_items.LockItemsForRead(true);
318 if (m_items.ContainsKey(itemId)) 319 if (m_items.ContainsKey(itemId))
319 { 320 {
320 TaskInventoryItem item = m_items[itemId]; 321 if (m_items.ContainsKey(itemId))
321 m_items.LockItemsForRead(false); 322 {
322 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 323 m_items.LockItemsForRead(false);
324 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
325 }
326 else
327 {
328 m_items.LockItemsForRead(false);
329 m_log.ErrorFormat(
330 "[PRIM INVENTORY]: " +
331 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
332 itemId, m_part.Name, m_part.UUID,
333 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
334 }
323 } 335 }
324 else 336 else
325 { 337 {
@@ -347,8 +359,9 @@ namespace OpenSim.Region.Framework.Scenes
347 { 359 {
348 m_log.ErrorFormat( 360 m_log.ErrorFormat(
349 "[PRIM INVENTORY]: " + 361 "[PRIM INVENTORY]: " +
350 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2}", 362 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
351 itemId, m_part.Name, m_part.UUID); 363 itemId, m_part.Name, m_part.UUID,
364 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
352 } 365 }
353 } 366 }
354 367
@@ -542,8 +555,9 @@ namespace OpenSim.Region.Framework.Scenes
542 { 555 {
543 m_log.ErrorFormat( 556 m_log.ErrorFormat(
544 "[PRIM INVENTORY]: " + 557 "[PRIM INVENTORY]: " +
545 "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", 558 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
546 item.ItemID, m_part.Name, m_part.UUID); 559 item.ItemID, m_part.Name, m_part.UUID,
560 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
547 } 561 }
548 m_items.LockItemsForWrite(false); 562 m_items.LockItemsForWrite(false);
549 563
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5d0218f..fbc4ed5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -791,11 +791,11 @@ namespace OpenSim.Region.Framework.Scenes
791 /// </summary> 791 /// </summary>
792 public void SendPrimUpdates() 792 public void SendPrimUpdates()
793 { 793 {
794 m_perfMonMS = Environment.TickCount; 794 m_perfMonMS = Util.EnvironmentTickCount();
795 795
796 m_sceneViewer.SendPrimUpdates(); 796 m_sceneViewer.SendPrimUpdates();
797 797
798 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 798 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
799 } 799 }
800 800
801 #region Status Methods 801 #region Status Methods
@@ -1143,7 +1143,7 @@ namespace OpenSim.Region.Framework.Scenes
1143 /// <param name="collisionPoint"></param> 1143 /// <param name="collisionPoint"></param>
1144 /// <param name="localid"></param> 1144 /// <param name="localid"></param>
1145 /// <param name="distance"></param> 1145 /// <param name="distance"></param>
1146 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) 1146 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
1147 { 1147 {
1148 const float POSITION_TOLERANCE = 0.02f; 1148 const float POSITION_TOLERANCE = 0.02f;
1149 const float VELOCITY_TOLERANCE = 0.02f; 1149 const float VELOCITY_TOLERANCE = 0.02f;
@@ -1185,7 +1185,8 @@ namespace OpenSim.Region.Framework.Scenes
1185 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); 1185 // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent");
1186 // return; 1186 // return;
1187 //} 1187 //}
1188 m_perfMonMS = Environment.TickCount; 1188
1189 m_perfMonMS = Util.EnvironmentTickCount();
1189 1190
1190 ++m_movementUpdateCount; 1191 ++m_movementUpdateCount;
1191 if (m_movementUpdateCount < 1) 1192 if (m_movementUpdateCount < 1)
@@ -1515,7 +1516,7 @@ namespace OpenSim.Region.Framework.Scenes
1515 1516
1516 m_scene.EventManager.TriggerOnClientMovement(this); 1517 m_scene.EventManager.TriggerOnClientMovement(this);
1517 1518
1518 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 1519 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
1519 } 1520 }
1520 1521
1521 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) 1522 public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client)
@@ -1831,7 +1832,7 @@ namespace OpenSim.Region.Framework.Scenes
1831 StandUp(); 1832 StandUp();
1832 } 1833 }
1833 m_nextSitAnimation = "SIT"; 1834 m_nextSitAnimation = "SIT";
1834 1835
1835 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); 1836 //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID);
1836 SceneObjectPart part = FindNextAvailableSitTarget(targetID); 1837 SceneObjectPart part = FindNextAvailableSitTarget(targetID);
1837 1838
@@ -1843,12 +1844,23 @@ namespace OpenSim.Region.Framework.Scenes
1843 } 1844 }
1844 m_requestedSitTargetID = part.LocalId; 1845 m_requestedSitTargetID = part.LocalId;
1845 //m_requestedSitOffset = offset; 1846 //m_requestedSitOffset = offset;
1847 //offset.X += part.Scale.X;// *offset.X;
1848 //offset.Y += part.Scale.Y;// * offset.Y;
1849 //offset.Z += part.Scale.Z;// * offset.Z;
1850 //m_requestedSitOffset = offset;
1851 m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
1846 } 1852 }
1847 else 1853 else
1848 { 1854 {
1849 1855
1850 m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); 1856 m_log.Warn("Sit requested on unknown object: " + targetID.ToString());
1851 } 1857 }
1858
1859 if (m_scene.PhysicsScene.SupportsRayCast())
1860 {
1861 //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
1862 }
1863
1852 SendSitResponse(remoteClient, targetID, offset); 1864 SendSitResponse(remoteClient, targetID, offset);
1853 } 1865 }
1854 1866
@@ -1966,7 +1978,7 @@ namespace OpenSim.Region.Framework.Scenes
1966 SendFullUpdateToAllClients(); 1978 SendFullUpdateToAllClients();
1967 } 1979 }
1968 1980
1969 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) // KF: Nov 2009 1981 public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal)
1970 { 1982 {
1971 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer 1983 // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer
1972 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. 1984 // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height.
@@ -2046,7 +2058,7 @@ namespace OpenSim.Region.Framework.Scenes
2046 return; 2058 return;
2047 } 2059 }
2048 2060
2049 m_perfMonMS = Environment.TickCount; 2061 m_perfMonMS = Util.EnvironmentTickCount();
2050 2062
2051 Rotation = rotation; 2063 Rotation = rotation;
2052 Vector3 direc = vec * rotation; 2064 Vector3 direc = vec * rotation;
@@ -2088,7 +2100,7 @@ namespace OpenSim.Region.Framework.Scenes
2088 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2100 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2089 m_forceToApply = direc; 2101 m_forceToApply = direc;
2090 m_isNudging = Nudging; 2102 m_isNudging = Nudging;
2091 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2103 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2092 } 2104 }
2093 2105
2094 #endregion 2106 #endregion
@@ -2157,7 +2169,7 @@ namespace OpenSim.Region.Framework.Scenes
2157 // server. 2169 // server.
2158 if (remoteClient.IsActive) 2170 if (remoteClient.IsActive)
2159 { 2171 {
2160 m_perfMonMS = Environment.TickCount; 2172 m_perfMonMS = Util.EnvironmentTickCount();
2161 2173
2162 PhysicsActor actor = m_physicsActor; 2174 PhysicsActor actor = m_physicsActor;
2163 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; 2175 Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero;
@@ -2170,7 +2182,7 @@ namespace OpenSim.Region.Framework.Scenes
2170 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, 2182 remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId,
2171 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient))); 2183 pos, velocity, Vector3.Zero, m_bodyRot, CollisionPlane, m_uuid, null, GetUpdatePriority(remoteClient)));
2172 2184
2173 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2185 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2174 m_scene.StatsReporter.AddAgentUpdates(1); 2186 m_scene.StatsReporter.AddAgentUpdates(1);
2175 } 2187 }
2176 } 2188 }
@@ -2180,11 +2192,11 @@ namespace OpenSim.Region.Framework.Scenes
2180 /// </summary> 2192 /// </summary>
2181 public void SendTerseUpdateToAllClients() 2193 public void SendTerseUpdateToAllClients()
2182 { 2194 {
2183 m_perfMonMS = Environment.TickCount; 2195 m_perfMonMS = Util.EnvironmentTickCount();
2184 2196
2185 m_scene.ForEachClient(SendTerseUpdateToClient); 2197 m_scene.ForEachClient(SendTerseUpdateToClient);
2186 2198
2187 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2199 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2188 } 2200 }
2189 2201
2190 public void SendCoarseLocations() 2202 public void SendCoarseLocations()
@@ -2204,7 +2216,7 @@ namespace OpenSim.Region.Framework.Scenes
2204 2216
2205 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p) 2217 public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p)
2206 { 2218 {
2207 m_perfMonMS = Environment.TickCount; 2219 m_perfMonMS = Util.EnvironmentTickCount();
2208 2220
2209 List<Vector3> CoarseLocations = new List<Vector3>(); 2221 List<Vector3> CoarseLocations = new List<Vector3>();
2210 List<UUID> AvatarUUIDs = new List<UUID>(); 2222 List<UUID> AvatarUUIDs = new List<UUID>();
@@ -2240,7 +2252,7 @@ namespace OpenSim.Region.Framework.Scenes
2240 2252
2241 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations); 2253 m_controllingClient.SendCoarseLocationUpdate(AvatarUUIDs, CoarseLocations);
2242 2254
2243 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2255 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2244 } 2256 }
2245 2257
2246 public void CoarseLocationChange() 2258 public void CoarseLocationChange()
@@ -2277,7 +2289,7 @@ namespace OpenSim.Region.Framework.Scenes
2277 /// </summary> 2289 /// </summary>
2278 public void SendInitialFullUpdateToAllClients() 2290 public void SendInitialFullUpdateToAllClients()
2279 { 2291 {
2280 m_perfMonMS = Environment.TickCount; 2292 m_perfMonMS = Util.EnvironmentTickCount();
2281 2293
2282 ScenePresence[] avatars = m_scene.GetScenePresences(); 2294 ScenePresence[] avatars = m_scene.GetScenePresences();
2283 2295
@@ -2303,14 +2315,14 @@ namespace OpenSim.Region.Framework.Scenes
2303 } 2315 }
2304 2316
2305 m_scene.StatsReporter.AddAgentUpdates(avatars.Length); 2317 m_scene.StatsReporter.AddAgentUpdates(avatars.Length);
2306 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2318 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2307 2319
2308 //Animator.SendAnimPack(); 2320 //Animator.SendAnimPack();
2309 } 2321 }
2310 2322
2311 public void SendFullUpdateToAllClients() 2323 public void SendFullUpdateToAllClients()
2312 { 2324 {
2313 m_perfMonMS = Environment.TickCount; 2325 m_perfMonMS = Util.EnvironmentTickCount();
2314 2326
2315 // only send update from root agents to other clients; children are only "listening posts" 2327 // only send update from root agents to other clients; children are only "listening posts"
2316 List<ScenePresence> avatars = m_scene.GetAvatars(); 2328 List<ScenePresence> avatars = m_scene.GetAvatars();
@@ -2320,7 +2332,7 @@ namespace OpenSim.Region.Framework.Scenes
2320 2332
2321 } 2333 }
2322 m_scene.StatsReporter.AddAgentUpdates(avatars.Count); 2334 m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
2323 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2335 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2324 2336
2325 Animator.SendAnimPack(); 2337 Animator.SendAnimPack();
2326 } 2338 }
@@ -2362,7 +2374,7 @@ namespace OpenSim.Region.Framework.Scenes
2362 /// </summary> 2374 /// </summary>
2363 public void SendAppearanceToAllOtherAgents() 2375 public void SendAppearanceToAllOtherAgents()
2364 { 2376 {
2365 m_perfMonMS = Environment.TickCount; 2377 m_perfMonMS = Util.EnvironmentTickCount();
2366 2378
2367 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) 2379 m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
2368 { 2380 {
@@ -2371,8 +2383,8 @@ namespace OpenSim.Region.Framework.Scenes
2371 SendAppearanceToOtherAgent(scenePresence); 2383 SendAppearanceToOtherAgent(scenePresence);
2372 } 2384 }
2373 }); 2385 });
2374 2386
2375 m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); 2387 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2376 } 2388 }
2377 2389
2378 /// <summary> 2390 /// <summary>
@@ -3073,7 +3085,9 @@ namespace OpenSim.Region.Framework.Scenes
3073 3085
3074 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( 3086 // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents(
3075 // as of this comment the interval is set in AddToPhysicalScene 3087 // as of this comment the interval is set in AddToPhysicalScene
3076 3088 if (Animator!=null)
3089 Animator.UpdateMovementAnimations();
3090
3077 CollisionEventUpdate collisionData = (CollisionEventUpdate)e; 3091 CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
3078 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; 3092 Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
3079 3093
@@ -3085,7 +3099,7 @@ namespace OpenSim.Region.Framework.Scenes
3085 m_lastColCount = coldata.Count; 3099 m_lastColCount = coldata.Count;
3086 } 3100 }
3087 3101
3088 if (coldata.Count != 0) 3102 if (coldata.Count != 0 && Animator != null)
3089 { 3103 {
3090 switch (Animator.CurrentMovementAnimation) 3104 switch (Animator.CurrentMovementAnimation)
3091 { 3105 {
@@ -3189,11 +3203,13 @@ namespace OpenSim.Region.Framework.Scenes
3189 3203
3190 // I don't get it but mono crashes when you try to dispose of this timer, 3204 // I don't get it but mono crashes when you try to dispose of this timer,
3191 // unsetting the elapsed callback should be enough to allow for cleanup however. 3205 // unsetting the elapsed callback should be enough to allow for cleanup however.
3192 //m_reprioritizationTimer.Dispose(); 3206 // m_reprioritizationTimer.Dispose();
3193 3207
3194 m_sceneViewer.Close(); 3208 m_sceneViewer.Close();
3195 3209
3196 RemoveFromPhysicalScene(); 3210 RemoveFromPhysicalScene();
3211 m_animator.Close();
3212 m_animator = null;
3197 } 3213 }
3198 3214
3199 public ScenePresence() 3215 public ScenePresence()
diff --git a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
index 56c6ed6..e368c2a 100644
--- a/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
+++ b/OpenSim/Region/Framework/Scenes/SimStatsReporter.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes
75 UnAckedBytes = 24, 75 UnAckedBytes = 24,
76 } 76 }
77 77
78 // Sending a stats update every 3 seconds 78 // Sending a stats update every 3 seconds-
79 private int statsUpdatesEveryMS = 3000; 79 private int statsUpdatesEveryMS = 3000;
80 private float statsUpdateFactor = 0; 80 private float statsUpdateFactor = 0;
81 private float m_timeDilation = 0; 81 private float m_timeDilation = 0;
@@ -193,6 +193,9 @@ namespace OpenSim.Region.Framework.Scenes
193 // / 10 divides the value by the number of times the sim heartbeat runs (10fps) 193 // / 10 divides the value by the number of times the sim heartbeat runs (10fps)
194 // Then we divide the whole amount by the amount of seconds pass in between stats updates. 194 // Then we divide the whole amount by the amount of seconds pass in between stats updates.
195 195
196 // 'statsUpdateFactor' is how often stats packets are sent in seconds. Used below to change
197 // values to X-per-second values.
198
196 for (int i = 0; i<21;i++) 199 for (int i = 0; i<21;i++)
197 { 200 {
198 sb[i] = new SimStatsPacket.StatBlock(); 201 sb[i] = new SimStatsPacket.StatBlock();
@@ -238,7 +241,7 @@ namespace OpenSim.Region.Framework.Scenes
238 sb[12].StatValue = m_otherMS / statsUpdateFactor; 241 sb[12].StatValue = m_otherMS / statsUpdateFactor;
239 242
240 sb[13].StatID = (uint)Stats.InPacketsPerSecond; 243 sb[13].StatID = (uint)Stats.InPacketsPerSecond;
241 sb[13].StatValue = (m_inPacketsPerSecond); 244 sb[13].StatValue = (m_inPacketsPerSecond / statsUpdateFactor);
242 245
243 sb[14].StatID = (uint)Stats.OutPacketsPerSecond; 246 sb[14].StatID = (uint)Stats.OutPacketsPerSecond;
244 sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor); 247 sb[14].StatValue = (m_outPacketsPerSecond / statsUpdateFactor);
@@ -285,8 +288,8 @@ namespace OpenSim.Region.Framework.Scenes
285 m_fps = 0; 288 m_fps = 0;
286 m_pfps = 0; 289 m_pfps = 0;
287 m_agentUpdates = 0; 290 m_agentUpdates = 0;
288 m_inPacketsPerSecond = 0; 291 //m_inPacketsPerSecond = 0;
289 m_outPacketsPerSecond = 0; 292 //m_outPacketsPerSecond = 0;
290 m_unAckedBytes = 0; 293 m_unAckedBytes = 0;
291 m_scriptLinesPerSecond = 0; 294 m_scriptLinesPerSecond = 0;
292 295
@@ -373,12 +376,12 @@ namespace OpenSim.Region.Framework.Scenes
373 376
374 public void AddInPackets(int numPackets) 377 public void AddInPackets(int numPackets)
375 { 378 {
376 m_inPacketsPerSecond += numPackets; 379 m_inPacketsPerSecond = numPackets;
377 } 380 }
378 381
379 public void AddOutPackets(int numPackets) 382 public void AddOutPackets(int numPackets)
380 { 383 {
381 m_outPacketsPerSecond += numPackets; 384 m_outPacketsPerSecond = numPackets;
382 } 385 }
383 386
384 public void AddunAckedBytes(int numBytes) 387 public void AddunAckedBytes(int numBytes)
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8a27b7b..5abbb82 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -101,7 +101,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests
101 { 101 {
102 throw new NotImplementedException(); 102 throw new NotImplementedException();
103 } 103 }
104 104 public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID)
105 {
106 //This connector doesn't support the windlight module yet
107 //Return default LL windlight settings
108 return new RegionMeta7WindlightData();
109 }
110 public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl)
111 {
112 //This connector doesn't support the windlight module yet
113 }
105 public RegionSettings LoadRegionSettings(UUID regionUUID) 114 public RegionSettings LoadRegionSettings(UUID regionUUID)
106 { 115 {
107 return null; 116 return null;