aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs333
1 files changed, 174 insertions, 159 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 02a0268..1a6a70b 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -83,6 +83,13 @@ namespace OpenSim.Region.Framework.Scenes
83 public bool m_useFlySlow; 83 public bool m_useFlySlow;
84 public bool m_usePreJump; 84 public bool m_usePreJump;
85 public bool m_seeIntoRegionFromNeighbor; 85 public bool m_seeIntoRegionFromNeighbor;
86
87 protected float m_defaultDrawDistance = 255.0f;
88 public float DefaultDrawDistance
89 {
90 get { return m_defaultDrawDistance; }
91 }
92
86 // TODO: need to figure out how allow client agents but deny 93 // TODO: need to figure out how allow client agents but deny
87 // root agents when ACL denies access to root agent 94 // root agents when ACL denies access to root agent
88 public bool m_strictAccessControl = true; 95 public bool m_strictAccessControl = true;
@@ -129,7 +136,16 @@ namespace OpenSim.Region.Framework.Scenes
129 protected ICapabilitiesModule m_capsModule; 136 protected ICapabilitiesModule m_capsModule;
130 // Central Update Loop 137 // Central Update Loop
131 protected int m_fps = 10; 138 protected int m_fps = 10;
132 protected uint m_frame; 139
140 /// <summary>
141 /// Current scene frame number
142 /// </summary>
143 public uint Frame
144 {
145 get;
146 protected set;
147 }
148
133 protected float m_timespan = 0.089f; 149 protected float m_timespan = 0.089f;
134 protected DateTime m_lastupdate = DateTime.UtcNow; 150 protected DateTime m_lastupdate = DateTime.UtcNow;
135 151
@@ -618,6 +634,8 @@ namespace OpenSim.Region.Framework.Scenes
618 // 634 //
619 IConfig startupConfig = m_config.Configs["Startup"]; 635 IConfig startupConfig = m_config.Configs["Startup"];
620 636
637 m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance",m_defaultDrawDistance);
638
621 //Animation states 639 //Animation states
622 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 640 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
623 // TODO: Change default to true once the feature is supported 641 // TODO: Change default to true once the feature is supported
@@ -1183,7 +1201,8 @@ namespace OpenSim.Region.Framework.Scenes
1183 1201
1184 try 1202 try
1185 { 1203 {
1186 Update(); 1204 while (!shuttingdown)
1205 Update();
1187 1206
1188 m_lastUpdate = Util.EnvironmentTickCount(); 1207 m_lastUpdate = Util.EnvironmentTickCount();
1189 m_firstHeartbeat = false; 1208 m_firstHeartbeat = false;
@@ -1200,187 +1219,176 @@ namespace OpenSim.Region.Framework.Scenes
1200 Watchdog.RemoveThread(); 1219 Watchdog.RemoveThread();
1201 } 1220 }
1202 1221
1203 /// <summary>
1204 /// Performs per-frame updates on the scene, this should be the central scene loop
1205 /// </summary>
1206 public override void Update() 1222 public override void Update()
1207 { 1223 {
1208 float physicsFPS; 1224 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate;
1209 int maintc; 1225 float physicsFPS = 0f;
1226
1227 int maintc = Util.EnvironmentTickCount();
1228 int tmpFrameMS = maintc;
1229 tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1230
1231 // Increment the frame counter
1232 ++Frame;
1210 1233
1211 while (!shuttingdown) 1234 try
1212 { 1235 {
1213 TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; 1236 // Check if any objects have reached their targets
1214 physicsFPS = 0f; 1237 CheckAtTargets();
1215 1238
1216 maintc = Util.EnvironmentTickCount(); 1239 // Update SceneObjectGroups that have scheduled themselves for updates
1217 int tmpFrameMS = maintc; 1240 // Objects queue their updates onto all scene presences
1218 tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0; 1241 if (Frame % m_update_objects == 0)
1242 m_sceneGraph.UpdateObjectGroups();
1219 1243
1220 // Increment the frame counter 1244 // Run through all ScenePresences looking for updates
1221 ++m_frame; 1245 // Presence updates and queued object updates for each presence are sent to clients
1246 if (Frame % m_update_presences == 0)
1247 m_sceneGraph.UpdatePresences();
1222 1248
1223 try 1249 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1250 if (Frame % m_update_coarse_locations == 0)
1224 { 1251 {
1225 // Check if any objects have reached their targets 1252 List<Vector3> coarseLocations;
1226 CheckAtTargets(); 1253 List<UUID> avatarUUIDs;
1227 1254 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1228 // Update SceneObjectGroups that have scheduled themselves for updates 1255 // Send coarse locations to clients
1229 // Objects queue their updates onto all scene presences 1256 ForEachScenePresence(delegate(ScenePresence presence)
1230 if (m_frame % m_update_objects == 0) 1257 {
1231 m_sceneGraph.UpdateObjectGroups(); 1258 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1259 });
1260 }
1232 1261
1233 // Run through all ScenePresences looking for updates 1262 int tmpPhysicsMS2 = Util.EnvironmentTickCount();
1234 // Presence updates and queued object updates for each presence are sent to clients 1263 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1235 if (m_frame % m_update_presences == 0) 1264 m_sceneGraph.UpdatePreparePhysics();
1236 m_sceneGraph.UpdatePresences(); 1265 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1237 1266
1238 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1267 // Apply any pending avatar force input to the avatar's velocity
1239 if (m_frame % m_update_coarse_locations == 0) 1268 if (Frame % m_update_entitymovement == 0)
1240 { 1269 m_sceneGraph.UpdateScenePresenceMovement();
1241 List<Vector3> coarseLocations;
1242 List<UUID> avatarUUIDs;
1243 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1244 // Send coarse locations to clients
1245 ForEachScenePresence(delegate(ScenePresence presence)
1246 {
1247 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1248 });
1249 }
1250 1270
1251 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1271 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1252 if ((m_frame % m_update_physics == 0) && m_physics_enabled) 1272 // velocity
1253 m_sceneGraph.UpdatePreparePhysics(); 1273 int tmpPhysicsMS = Util.EnvironmentTickCount();
1254 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2); 1274 if (Frame % m_update_physics == 0)
1275 {
1276 if (m_physics_enabled)
1277 physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan));
1278 if (SynchronizeScene != null)
1279 SynchronizeScene(this);
1280 }
1281 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1255 1282
1256 // Apply any pending avatar force input to the avatar's velocity 1283 // Delete temp-on-rez stuff
1257 if (m_frame % m_update_entitymovement == 0) 1284 if (Frame % 1000 == 0 && !m_cleaningTemps)
1258 m_sceneGraph.UpdateScenePresenceMovement(); 1285 {
1286 int tmpTempOnRezMS = Util.EnvironmentTickCount();
1287 m_cleaningTemps = true;
1288 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1289 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1290 }
1259 1291
1260 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their 1292 if (RegionStatus != RegionStatus.SlaveScene)
1261 // velocity 1293 {
1262 int tmpPhysicsMS = Util.EnvironmentTickCount(); 1294 if (Frame % m_update_events == 0)
1263 if (m_frame % m_update_physics == 0)
1264 { 1295 {
1265 if (m_physics_enabled) 1296 int evMS = Util.EnvironmentTickCount();
1266 physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); 1297 UpdateEvents();
1267 if (SynchronizeScene != null) 1298 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1268 SynchronizeScene(this);
1269 } 1299 }
1270 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1271 1300
1272 // Delete temp-on-rez stuff 1301 if (Frame % m_update_backup == 0)
1273 if (m_frame % 1000 == 0 && !m_cleaningTemps)
1274 { 1302 {
1275 int tmpTempOnRezMS = Util.EnvironmentTickCount(); 1303 int backMS = Util.EnvironmentTickCount();
1276 m_cleaningTemps = true; 1304 UpdateStorageBackup();
1277 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; }); 1305 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1278 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1279 } 1306 }
1280 1307
1281 if (RegionStatus != RegionStatus.SlaveScene) 1308 if (Frame % m_update_terrain == 0)
1282 { 1309 {
1283 if (m_frame % m_update_events == 0) 1310 int terMS = Util.EnvironmentTickCount();
1284 { 1311 UpdateTerrain();
1285 int evMS = Util.EnvironmentTickCount(); 1312 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1286 UpdateEvents(); 1313 }
1287 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1288 }
1289
1290 if (m_frame % m_update_backup == 0)
1291 {
1292 int backMS = Util.EnvironmentTickCount();
1293 UpdateStorageBackup();
1294 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1295 }
1296 1314
1297 if (m_frame % m_update_terrain == 0) 1315 //if (Frame % m_update_land == 0)
1298 { 1316 //{
1299 int terMS = Util.EnvironmentTickCount(); 1317 // int ldMS = Util.EnvironmentTickCount();
1300 UpdateTerrain(); 1318 // UpdateLand();
1301 terrainMS = Util.EnvironmentTickCountSubtract(terMS); 1319 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1302 } 1320 //}
1303 1321
1304 //if (m_frame % m_update_land == 0) 1322 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1305 //{ 1323 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1306 // int ldMS = Util.EnvironmentTickCount(); 1324 lastCompletedFrame = Util.EnvironmentTickCount();
1307 // UpdateLand(); 1325
1308 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1326 // if (Frame%m_update_avatars == 0)
1309 //} 1327 // UpdateInWorldTime();
1328 StatsReporter.AddPhysicsFPS(physicsFPS);
1329 StatsReporter.AddTimeDilation(TimeDilation);
1330 StatsReporter.AddFPS(1);
1331 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1332 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1333 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1334 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1335 StatsReporter.addFrameMS(frameMS);
1336 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1337 StatsReporter.addOtherMS(otherMS);
1338 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1339 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1340 }
1310 1341
1311 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS); 1342 if (LoginsDisabled && Frame == 20)
1312 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1343 {
1313 lastCompletedFrame = Util.EnvironmentTickCount(); 1344 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1314 1345 // this is a rare case where we know we have just went through a long cycle of heap
1315 // if (m_frame%m_update_avatars == 0) 1346 // allocations, and there is no more work to be done until someone logs in
1316 // UpdateInWorldTime(); 1347 GC.Collect();
1317 StatsReporter.AddPhysicsFPS(physicsFPS);
1318 StatsReporter.AddTimeDilation(TimeDilation);
1319 StatsReporter.AddFPS(1);
1320 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1321 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1322 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1323 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1324 StatsReporter.addFrameMS(frameMS);
1325 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1326 StatsReporter.addOtherMS(otherMS);
1327 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1328 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1329 }
1330 1348
1331 if (LoginsDisabled && m_frame == 20) 1349 IConfig startupConfig = m_config.Configs["Startup"];
1350 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1332 { 1351 {
1333 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1352 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1334 // this is a rare case where we know we have just went through a long cycle of heap 1353 LoginsDisabled = false;
1335 // allocations, and there is no more work to be done until someone logs in 1354 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1336 GC.Collect();
1337
1338 IConfig startupConfig = m_config.Configs["Startup"];
1339 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1340 {
1341 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1342 LoginsDisabled = false;
1343 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1344 }
1345 } 1355 }
1346 } 1356 }
1347 catch (NotImplementedException) 1357 }
1348 { 1358 catch (NotImplementedException)
1349 throw; 1359 {
1350 } 1360 throw;
1351 catch (AccessViolationException e) 1361 }
1352 { 1362 catch (AccessViolationException e)
1353 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1363 {
1354 } 1364 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1355 //catch (NullReferenceException e) 1365 }
1356 //{ 1366 //catch (NullReferenceException e)
1357 // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1367 //{
1358 //} 1368 // m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1359 catch (InvalidOperationException e) 1369 //}
1360 { 1370 catch (InvalidOperationException e)
1361 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1371 {
1362 } 1372 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1363 catch (Exception e) 1373 }
1364 { 1374 catch (Exception e)
1365 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName); 1375 {
1366 } 1376 m_log.Error("[REGION]: Failed with exception " + e.ToString() + " On Region: " + RegionInfo.RegionName);
1367 finally 1377 }
1368 { 1378 finally
1369 m_lastupdate = DateTime.UtcNow; 1379 {
1370 } 1380 m_lastupdate = DateTime.UtcNow;
1371 1381 }
1372 maintc = Util.EnvironmentTickCountSubtract(maintc);
1373 maintc = (int)(m_timespan * 1000) - maintc;
1374 1382
1375 if (maintc > 0) 1383 maintc = Util.EnvironmentTickCountSubtract(maintc);
1376 Thread.Sleep(maintc); 1384 maintc = (int)(m_timespan * 1000) - maintc;
1377 1385
1378 // Tell the watchdog that this thread is still alive 1386 if (maintc > 0)
1379 Watchdog.UpdateThread(); 1387 Thread.Sleep(maintc);
1380 }
1381 }
1382 1388
1383 1389 // Tell the watchdog that this thread is still alive
1390 Watchdog.UpdateThread();
1391 }
1384 1392
1385 public void AddGroupTarget(SceneObjectGroup grp) 1393 public void AddGroupTarget(SceneObjectGroup grp)
1386 { 1394 {
@@ -3011,7 +3019,9 @@ namespace OpenSim.Region.Framework.Scenes
3011 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName); 3019 (childagentYN ? "child" : "root"), agentID, RegionInfo.RegionName);
3012 3020
3013 m_sceneGraph.removeUserCount(!childagentYN); 3021 m_sceneGraph.removeUserCount(!childagentYN);
3014 CapsModule.RemoveCapsHandler(agentID); 3022
3023 if (CapsModule != null)
3024 CapsModule.RemoveCapsHandler(agentID);
3015 3025
3016 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever 3026 // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3017 // this method is doing is HORRIBLE!!! 3027 // this method is doing is HORRIBLE!!!
@@ -3200,7 +3210,7 @@ namespace OpenSim.Region.Framework.Scenes
3200 // TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport 3210 // TeleportFlags.ViaLandmark | TeleportFlags.ViaLocation | TeleportFlags.ViaLandmark | TeleportFlags.Default - Regular Teleport
3201 3211
3202 // Don't disable this log message - it's too helpful 3212 // Don't disable this log message - it's too helpful
3203 m_log.InfoFormat( 3213 m_log.DebugFormat(
3204 "[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6})", 3214 "[CONNECTION BEGIN]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, teleportflags {6})",
3205 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3215 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3206 agent.AgentID, agent.circuitcode, teleportFlags); 3216 agent.AgentID, agent.circuitcode, teleportFlags);
@@ -3266,8 +3276,11 @@ namespace OpenSim.Region.Framework.Scenes
3266 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 3276 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname,
3267 agent.AgentID, agent.circuitcode); 3277 agent.AgentID, agent.circuitcode);
3268 3278
3269 CapsModule.NewUserConnection(agent); 3279 if (CapsModule != null)
3270 CapsModule.AddCapsHandler(agent.AgentID); 3280 {
3281 CapsModule.NewUserConnection(agent);
3282 CapsModule.AddCapsHandler(agent.AgentID);
3283 }
3271 } 3284 }
3272 else 3285 else
3273 { 3286 {
@@ -3282,7 +3295,9 @@ namespace OpenSim.Region.Framework.Scenes
3282 agent.AgentID, RegionInfo.RegionName); 3295 agent.AgentID, RegionInfo.RegionName);
3283 3296
3284 sp.AdjustKnownSeeds(); 3297 sp.AdjustKnownSeeds();
3285 CapsModule.NewUserConnection(agent); 3298
3299 if (CapsModule != null)
3300 CapsModule.NewUserConnection(agent);
3286 } 3301 }
3287 } 3302 }
3288 3303