aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs333
1 files changed, 171 insertions, 162 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index f38a6fc..d4bfd46 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -131,7 +131,16 @@ namespace OpenSim.Region.Framework.Scenes
131 protected ICapabilitiesModule m_capsModule; 131 protected ICapabilitiesModule m_capsModule;
132 // Central Update Loop 132 // Central Update Loop
133 protected int m_fps = 10; 133 protected int m_fps = 10;
134 protected uint m_frame; 134
135 /// <summary>
136 /// Current scene frame number
137 /// </summary>
138 public uint Frame
139 {
140 get;
141 protected set;
142 }
143
135 protected float m_timespan = 0.089f; 144 protected float m_timespan = 0.089f;
136 protected DateTime m_lastupdate = DateTime.UtcNow; 145 protected DateTime m_lastupdate = DateTime.UtcNow;
137 146
@@ -1212,6 +1221,9 @@ namespace OpenSim.Region.Framework.Scenes
1212 try 1221 try
1213 { 1222 {
1214 Update(); 1223 Update();
1224
1225 m_lastUpdate = Util.EnvironmentTickCount();
1226 m_firstHeartbeat = false;
1215 } 1227 }
1216 catch (ThreadAbortException) 1228 catch (ThreadAbortException)
1217 { 1229 {
@@ -1225,190 +1237,180 @@ namespace OpenSim.Region.Framework.Scenes
1225 Watchdog.RemoveThread(); 1237 Watchdog.RemoveThread();
1226 } 1238 }
1227 1239
1228 /// <summary>
1229 /// Performs per-frame updates on the scene, this should be the central scene loop
1230 /// </summary>
1231 public override void Update() 1240 public override void Update()
1232 { 1241 {
1233 float physicsFPS; 1242 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1234 int maintc; 1243 float physicsFPS = 0f;
1244
1245 int maintc = Util.EnvironmentTickCount();
1246 int tmpFrameMS = maintc;
1247 tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1248
1249 // Increment the frame counter
1250 ++Frame;
1235 1251
1236 while (!shuttingdown) 1252 try
1237 { 1253 {
1238 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; 1254 // Check if any objects have reached their targets
1239 physicsFPS = 0f; 1255 CheckAtTargets();
1240 1256
1241 maintc = Util.EnvironmentTickCount(); 1257 // Update SceneObjectGroups that have scheduled themselves for updates
1242 int tmpFrameMS = maintc; 1258 // Objects queue their updates onto all scene presences
1243 tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; 1259 if (Frame % m_update_objects == 0)
1260 m_sceneGraph.UpdateObjectGroups();
1244 1261
1245 // Increment the frame counter 1262 // Run through all ScenePresences looking for updates
1246 ++m_frame; 1263 // Presence updates and queued object updates for each presence are sent to clients
1264 if (Frame % m_update_presences == 0)
1265 m_sceneGraph.UpdatePresences();
1247 1266
1248 try 1267 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1268 if (Frame % m_update_coarse_locations == 0)
1249 { 1269 {
1250 // Check if any objects have reached their targets 1270 List<Vector3> coarseLocations;
1251 CheckAtTargets(); 1271 List<UUID> avatarUUIDs;
1272 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1273 // Send coarse locations to clients
1274 ForEachScenePresence(delegate(ScenePresence presence)
1275 {
1276 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1277 });
1278 }
1252 1279
1253 // Update SceneObjectGroups that have scheduled themselves for updates 1280 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1254 // Objects queue their updates onto all scene presences 1281 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1255 if (m_frame % m_update_objects == 0) 1282 m_sceneGraph.UpdatePreparePhysics();
1256 m_sceneGraph.UpdateObjectGroups(); 1283 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1257 1284
1258 // Run through all ScenePresences looking for updates 1285 // Apply any pending avatar force input to the avatar's velocity
1259 // Presence updates and queued object updates for each presence are sent to clients 1286 if (Frame % m_update_entitymovement == 0)
1260 if (m_frame % m_update_presences == 0) 1287 m_sceneGraph.UpdateScenePresenceMovement();
1261 m_sceneGraph.UpdatePresences();
1262 1288
1263 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1289 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1264 if (m_frame % m_update_coarse_locations == 0) 1290 // velocity
1265 { 1291 int tmpPhysicsMS = Util.EnvironmentTickCount();
1266 List<Vector3> coarseLocations; 1292 if (Frame % m_update_physics == 0)
1267 List<UUID> avatarUUIDs; 1293 {
1268 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); 1294 if (m_physics_enabled)
1269 // Send coarse locations to clients 1295 physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
1270 ForEachScenePresence(delegate(ScenePresence presence) 1296 if (SynchronizeScene != null)
1271 { 1297 SynchronizeScene(this);
1272 presence.SendCoarseLocations(coarseLocations, avatarUUIDs); 1298 }
1273 }); 1299 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1274 }
1275
1276 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1277 if ((m_frame % m_update_physics == 0) && m_physics_enabled)
1278 m_sceneGraph.UpdatePreparePhysics();
1279 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1280 1300
1281 // Apply any pending avatar force input to the avatar's velocity 1301 // Delete temp-on-rez stuff
1282 if (m_frame % m_update_entitymovement == 0) 1302 if (Frame % 1000 == 0 && !m_cleaningTemps)
1283 m_sceneGraph.UpdateScenePresenceMovement(); 1303 {
1304 int tmpTempOnRezMS = Util.EnvironmentTickCount();
1305 m_cleaningTemps = true;
1306 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1307 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1308 }
1284 1309
1285 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1310 if (RegionStatus != RegionStatus.SlaveScene)
1286 // velocity 1311 {
1287 int tmpPhysicsMS = Util.EnvironmentTickCount(); 1312 if (Frame % m_update_events == 0)
1288 if (m_frame % m_update_physics == 0)
1289 { 1313 {
1290 if (m_physics_enabled) 1314 int evMS = Util.EnvironmentTickCount();
1291 physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); 1315 UpdateEvents();
1292 if (SynchronizeScene != null) 1316 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1293 SynchronizeScene(this);
1294 } 1317 }
1295 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1296 1318
1297 // Delete temp-on-rez stuff 1319 if (Frame % m_update_backup == 0)
1298 if (m_frame % 1000 == 0 && !m_cleaningTemps)
1299 { 1320 {
1300 int tmpTempOnRezMS = Util.EnvironmentTickCount(); 1321 int backMS = Util.EnvironmentTickCount();
1301 m_cleaningTemps = true; 1322 UpdateStorageBackup();
1302 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); 1323 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1303 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1304 } 1324 }
1305 1325
1306 if (RegionStatus != RegionStatus.SlaveScene) 1326 if (Frame % m_update_terrain == 0)
1307 { 1327 {
1308 if (m_frame % m_update_events == 0) 1328 int terMS = Util.EnvironmentTickCount();
1309 { 1329 UpdateTerrain();
1310 int evMS = Util.EnvironmentTickCount(); 1330 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1311 UpdateEvents();
1312 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1313 }
1314
1315 if (m_frame % m_update_backup == 0)
1316 {
1317 int backMS = Util.EnvironmentTickCount();
1318 UpdateStorageBackup();
1319 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1320 }
1321
1322 if (m_frame % m_update_terrain == 0)
1323 {
1324 int terMS = Util.EnvironmentTickCount();
1325 UpdateTerrain();
1326 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1327 }
1328
1329 if (m_frame % m_update_land == 0)
1330 {
1331 int ldMS = Util.EnvironmentTickCount();
1332 UpdateLand();
1333 landMS = Util.EnvironmentTickCountSubtract(ldMS);
1334 }
1335
1336 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1337 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1338 lastCompletedFrame = Util.EnvironmentTickCount();
1339
1340 // if (m_frame%m_update_avatars == 0)
1341 // UpdateInWorldTime();
1342 StatsReporter.AddPhysicsFPS(physicsFPS);
1343 StatsReporter.AddTimeDilation(TimeDilation);
1344 StatsReporter.AddFPS(1);
1345 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1346 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1347 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1348 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1349 StatsReporter.addFrameMS(frameMS);
1350 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1351 StatsReporter.addOtherMS(otherMS);
1352 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1353 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1354 } 1331 }
1355 1332
1356 if (LoginsDisabled && m_frame == 20) 1333 if (Frame % m_update_land == 0)
1357 { 1334 {
1358 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1335 int ldMS = Util.EnvironmentTickCount();
1359 // this is a rare case where we know we have just went through a long cycle of heap 1336 UpdateLand();
1360 // allocations, and there is no more work to be done until someone logs in 1337 landMS = Util.EnvironmentTickCountSubtract(ldMS);
1361 GC.Collect(); 1338 }
1362 1339
1363 IConfig startupConfig = m_config.Configs["Startup"]; 1340 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1364 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1341 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1365 { 1342 lastCompletedFrame = Util.EnvironmentTickCount();
1366 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1343
1367 LoginsDisabled = false; 1344 // if (Frame%m_update_avatars == 0)
1368 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo); 1345 // UpdateInWorldTime();
1369 } 1346 StatsReporter.AddPhysicsFPS(physicsFPS);
1347 StatsReporter.AddTimeDilation(TimeDilation);
1348 StatsReporter.AddFPS(1);
1349 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1350 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1351 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1352 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1353 StatsReporter.addFrameMS(frameMS);
1354 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1355 StatsReporter.addOtherMS(otherMS);
1356 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1357 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1358 }
1359
1360 if (LoginsDisabled && Frame == 20)
1361 {
1362 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1363 // this is a rare case where we know we have just went through a long cycle of heap
1364 // allocations, and there is no more work to be done until someone logs in
1365 GC.Collect();
1366
1367 IConfig startupConfig = m_config.Configs["Startup"];
1368 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1369 {
1370 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1371 LoginsDisabled = false;
1372 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1370 } 1373 }
1371 } 1374 }
1372 catch (NotImplementedException) 1375 }
1373 { 1376 catch (NotImplementedException)
1374 throw; 1377 {
1375 } 1378 throw;
1376 catch (AccessViolationException e) 1379 }
1377 { 1380 catch (AccessViolationException e)
1378 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1381 {
1379 } 1382 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1380 //catch (NullReferenceException e) 1383 }
1381 //{ 1384 //catch (NullReferenceException e)
1382 // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1385 //{
1383 //} 1386 // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1384 catch (InvalidOperationException e) 1387 //}
1385 { 1388 catch (InvalidOperationException e)
1386 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1389 {
1387 } 1390 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1388 catch (Exception e) 1391 }
1389 { 1392 catch (Exception e)
1390 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1393 {
1391 } 1394 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1392 finally 1395 }
1393 { 1396 finally
1394 m_lastupdate = DateTime.UtcNow; 1397 {
1395 } 1398 m_lastupdate = DateTime.UtcNow;
1399 }
1396 1400
1397 maintc = Util.EnvironmentTickCountSubtract(maintc); 1401 maintc = Util.EnvironmentTickCountSubtract(maintc);
1398 maintc = (int)(m_timespan * 1000) - maintc; 1402 maintc = (int)(m_timespan * 1000) - maintc;
1399 1403
1400 if (maintc > 0)
1401 Thread.Sleep(maintc);
1402 1404
1403 // Tell the watchdog that this thread is still alive 1405 m_lastUpdate = Util.EnvironmentTickCount();
1404 Watchdog.UpdateThread(); 1406 m_firstHeartbeat = false;
1405 1407
1406 m_lastUpdate = Util.EnvironmentTickCount(); 1408 if (maintc > 0)
1407 m_firstHeartbeat = false; 1409 Thread.Sleep(maintc);
1408 }
1409 }
1410 1410
1411 1411 // Tell the watchdog that this thread is still alive
1412 Watchdog.UpdateThread();
1413 }
1412 1414
1413 public void AddGroupTarget(SceneObjectGroup grp) 1415 public void AddGroupTarget(SceneObjectGroup grp)
1414 { 1416 {
@@ -3127,7 +3129,9 @@ namespace OpenSim.Region.Framework.Scenes
3127 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 3129 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
3128 3130
3129 m_sceneGraph.removeUserCount(!childagentYN); 3131 m_sceneGraph.removeUserCount(!childagentYN);
3130 CapsModule.RemoveCapsHandler(agentID); 3132
3133 if (CapsModule != null)
3134 CapsModule.RemoveCapsHandler(agentID);
3131 3135
3132 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3136 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3133 // this method is doing is HORRIBLE!!! 3137 // this method is doing is HORRIBLE!!!
@@ -3405,8 +3409,11 @@ namespace OpenSim.Region.Framework.Scenes
3405 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3409 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3406 agent.AgentID, agent.circuitcode); 3410 agent.AgentID, agent.circuitcode);
3407 3411
3408 CapsModule.NewUserConnection(agent); 3412 if (CapsModule != null)
3409 CapsModule.AddCapsHandler(agent.AgentID); 3413 {
3414 CapsModule.NewUserConnection(agent);
3415 CapsModule.AddCapsHandler(agent.AgentID);
3416 }
3410 } 3417 }
3411 else 3418 else
3412 { 3419 {
@@ -3421,7 +3428,9 @@ namespace OpenSim.Region.Framework.Scenes
3421 agent.AgentID, RegionInfo.RegionName); 3428 agent.AgentID, RegionInfo.RegionName);
3422 3429
3423 sp.AdjustKnownSeeds(); 3430 sp.AdjustKnownSeeds();
3424 CapsModule.NewUserConnection(agent); 3431
3432 if (CapsModule != null)
3433 CapsModule.NewUserConnection(agent);
3425 } 3434 }
3426 } 3435 }
3427 3436
@@ -3933,15 +3942,15 @@ namespace OpenSim.Region.Framework.Scenes
3933 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position, 3942 public void RequestTeleportLocation(IClientAPI remoteClient, string regionName, Vector3 position,
3934 Vector3 lookat, uint teleportFlags) 3943 Vector3 lookat, uint teleportFlags)
3935 { 3944 {
3936 GridRegion regionInfo = GridService.GetRegionByName(UUID.Zero, regionName); 3945 List<GridRegion> regions = GridService.GetRegionsByName(RegionInfo.ScopeID, regionName, 1);
3937 if (regionInfo == null) 3946 if (regions == null || regions.Count == 0)
3938 { 3947 {
3939 // can't find the region: Tell viewer and abort 3948 // can't find the region: Tell viewer and abort
3940 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found."); 3949 remoteClient.SendTeleportFailed("The region '" + regionName + "' could not be found.");
3941 return; 3950 return;
3942 } 3951 }
3943 3952
3944 RequestTeleportLocation(remoteClient, regionInfo.RegionHandle, position, lookat, teleportFlags); 3953 RequestTeleportLocation(remoteClient, regions[0].RegionHandle, position, lookat, teleportFlags);
3945 } 3954 }
3946 3955
3947 /// <summary> 3956 /// <summary>