aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorDiva Canto2012-03-20 17:19:14 -0700
committerDiva Canto2012-03-20 17:19:14 -0700
commit3fa51f66ec2f032134f333bf1fa047275a77f6e0 (patch)
tree952df67fcc209ecc81ce66b92f4bdf93a7017e08 /OpenSim/Region
parentHG Friends: allow the establishment of HG friendships without requiring co-pr... (diff)
parentAdd ability to log warn if a frame takes longer than twice the expected time.... (diff)
downloadopensim-SC_OLD-3fa51f66ec2f032134f333bf1fa047275a77f6e0.zip
opensim-SC_OLD-3fa51f66ec2f032134f333bf1fa047275a77f6e0.tar.gz
opensim-SC_OLD-3fa51f66ec2f032134f333bf1fa047275a77f6e0.tar.bz2
opensim-SC_OLD-3fa51f66ec2f032134f333bf1fa047275a77f6e0.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Conflicts: OpenSim/Framework/Util.cs
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs9
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs352
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneBase.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs12
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs16
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs2
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs12
-rw-r--r--OpenSim/Region/Physics/Meshing/Meshmerizer.cs2
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs21
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODEPrim.cs26
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs8
17 files changed, 264 insertions, 232 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 35cb575..ed3430a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -761,7 +761,7 @@ namespace OpenSim.Region.ClientStack.Linden
761 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID); 761 SceneObjectPart part = m_Scene.GetSceneObjectPart(objectID);
762 if (part != null) 762 if (part != null)
763 { 763 {
764 TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID); 764// TaskInventoryItem taskItem = part.Inventory.GetInventoryItem(notecardID);
765 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID)) 765 if (!m_Scene.Permissions.CanCopyObjectInventory(notecardID, objectID, m_HostCapsObj.AgentID))
766 { 766 {
767 return LLSDHelpers.SerialiseLLSDReply(response); 767 return LLSDHelpers.SerialiseLLSDReply(response);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
index fb94355..d76927b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/MockScene.cs
@@ -50,7 +50,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
50 m_regStatus = RegionStatus.Up; 50 m_regStatus = RegionStatus.Up;
51 } 51 }
52 52
53 public override void Update() {} 53 public override void Update(int frames) {}
54 public override void LoadWorldMap() {} 54 public override void LoadWorldMap() {}
55 55
56 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 56 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
index c982db6..267fb9e 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/LocalAuthorizationServiceConnector.cs
@@ -93,8 +93,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
93 93
94 scene.RegisterModuleInterface<IAuthorizationService>(this); 94 scene.RegisterModuleInterface<IAuthorizationService>(this);
95 m_Scene = scene; 95 m_Scene = scene;
96
97 scene.EventManager.OnLoginsEnabled += new EventManager.LoginsEnabled(OnLoginsEnabled);
98 } 96 }
99 97
100 public void RemoveRegion(Scene scene) 98 public void RemoveRegion(Scene scene)
@@ -106,16 +104,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization
106 if (!m_Enabled) 104 if (!m_Enabled)
107 return; 105 return;
108 106
107 m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
108
109 m_log.InfoFormat( 109 m_log.InfoFormat(
110 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}", 110 "[AUTHORIZATION CONNECTOR]: Enabled local authorization for region {0}",
111 scene.RegionInfo.RegionName); 111 scene.RegionInfo.RegionName);
112 } 112 }
113 113
114 private void OnLoginsEnabled(string regionName)
115 {
116 m_AuthorizationService = new AuthorizationService(m_AuthorizationConfig, m_Scene);
117 }
118
119 public bool IsAuthorizedForRegion( 114 public bool IsAuthorizedForRegion(
120 string userID, string firstName, string lastName, string regionID, out string message) 115 string userID, string firstName, string lastName, string regionID, out string message)
121 { 116 {
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index 61d604f..4c6f73e 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -604,7 +604,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
604 604
605 public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1) 605 public void handleOnEstateManageTelehub (IClientAPI client, UUID invoice, UUID senderID, string cmd, uint param1)
606 { 606 {
607 uint ObjectLocalID;
608 SceneObjectPart part; 607 SceneObjectPart part;
609 608
610 switch (cmd) 609 switch (cmd)
@@ -877,7 +876,6 @@ namespace OpenSim.Region.CoreModules.World.Estate
877 return; 876 return;
878 877
879 Dictionary<uint, float> sceneData = null; 878 Dictionary<uint, float> sceneData = null;
880 List<UUID> uuidNameLookupList = new List<UUID>();
881 879
882 if (reportType == 1) 880 if (reportType == 1)
883 { 881 {
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 6ff2a6f..1e1fcb7 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -481,6 +481,13 @@ namespace OpenSim.Region.Framework.Scenes
481 public event RegionHeartbeatEnd OnRegionHeartbeatEnd; 481 public event RegionHeartbeatEnd OnRegionHeartbeatEnd;
482 482
483 public delegate void LoginsEnabled(string regionName); 483 public delegate void LoginsEnabled(string regionName);
484
485 /// <summary>
486 /// This should only fire in all circumstances if the RegionReady module is active.
487 /// </summary>
488 /// <remarks>
489 /// TODO: Fire this even when the RegionReady module is not active.
490 /// </remarks>
484 public event LoginsEnabled OnLoginsEnabled; 491 public event LoginsEnabled OnLoginsEnabled;
485 492
486 public delegate void PrimsLoaded(Scene s); 493 public delegate void PrimsLoaded(Scene s);
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0706905..790ec63 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -190,7 +190,11 @@ namespace OpenSim.Region.Framework.Scenes
190 private int backupMS; 190 private int backupMS;
191 private int terrainMS; 191 private int terrainMS;
192 private int landMS; 192 private int landMS;
193 private int lastCompletedFrame; 193
194 /// <summary>
195 /// Tick at which the last frame was processed.
196 /// </summary>
197 private int m_lastFrameTick;
194 198
195 /// <summary> 199 /// <summary>
196 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched 200 /// Signals whether temporary objects are currently being cleaned up. Needed because this is launched
@@ -464,7 +468,7 @@ namespace OpenSim.Region.Framework.Scenes
464 public int MonitorBackupTime { get { return backupMS; } } 468 public int MonitorBackupTime { get { return backupMS; } }
465 public int MonitorTerrainTime { get { return terrainMS; } } 469 public int MonitorTerrainTime { get { return terrainMS; } }
466 public int MonitorLandTime { get { return landMS; } } 470 public int MonitorLandTime { get { return landMS; } }
467 public int MonitorLastFrameTick { get { return lastCompletedFrame; } } 471 public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
468 472
469 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } 473 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
470 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } 474 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@@ -1175,18 +1179,15 @@ namespace OpenSim.Region.Framework.Scenes
1175 // The first frame can take a very long time due to physics actors being added on startup. Therefore, 1179 // The first frame can take a very long time due to physics actors being added on startup. Therefore,
1176 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false 1180 // don't turn on the watchdog alarm for this thread until the second frame, in order to prevent false
1177 // alarms for scenes with many objects. 1181 // alarms for scenes with many objects.
1178 Update(); 1182 Update(1);
1179 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true; 1183 Watchdog.GetCurrentThreadInfo().AlarmIfTimeout = true;
1180 1184
1181 while (!shuttingdown) 1185 while (!shuttingdown)
1182 Update(); 1186 Update(-1);
1183 1187
1184 m_lastUpdate = Util.EnvironmentTickCount(); 1188 m_lastUpdate = Util.EnvironmentTickCount();
1185 m_firstHeartbeat = false; 1189 m_firstHeartbeat = false;
1186 } 1190 }
1187 catch (ThreadAbortException)
1188 {
1189 }
1190 finally 1191 finally
1191 { 1192 {
1192 Monitor.Pulse(m_heartbeatLock); 1193 Monitor.Pulse(m_heartbeatLock);
@@ -1196,188 +1197,207 @@ namespace OpenSim.Region.Framework.Scenes
1196 Watchdog.RemoveThread(); 1197 Watchdog.RemoveThread();
1197 } 1198 }
1198 1199
1199 public override void Update() 1200 public override void Update(int frames)
1200 { 1201 {
1201 float physicsFPS = 0f; 1202 long? endFrame = null;
1202 1203
1203 int maintc = Util.EnvironmentTickCount(); 1204 if (frames >= 0)
1204 int tmpFrameMS = maintc; 1205 endFrame = Frame + frames;
1205 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1206 1206
1207 ++Frame; 1207 float physicsFPS = 0f;
1208 1208 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1209// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName); 1209 int previousFrameTick;
1210 int maintc;
1211 List<Vector3> coarseLocations;
1212 List<UUID> avatarUUIDs;
1210 1213
1211 try 1214 while (!shuttingdown && (endFrame == null || Frame < endFrame))
1212 { 1215 {
1213 int tmpPhysicsMS2 = Util.EnvironmentTickCount(); 1216 maintc = Util.EnvironmentTickCount();
1214 if ((Frame % m_update_physics == 0) && m_physics_enabled) 1217 ++Frame;
1215 m_sceneGraph.UpdatePreparePhysics();
1216 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1217
1218 // Apply any pending avatar force input to the avatar's velocity
1219 int tmpAgentMS = Util.EnvironmentTickCount();
1220 if (Frame % m_update_entitymovement == 0)
1221 m_sceneGraph.UpdateScenePresenceMovement();
1222 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1223
1224 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1225 // velocity
1226 int tmpPhysicsMS = Util.EnvironmentTickCount();
1227 if (Frame % m_update_physics == 0)
1228 {
1229 if (m_physics_enabled)
1230 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1231 1218
1232 if (SynchronizeScene != null) 1219// m_log.DebugFormat("[SCENE]: Processing frame {0} in {1}", Frame, RegionInfo.RegionName);
1233 SynchronizeScene(this);
1234 }
1235 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1236
1237 tmpAgentMS = Util.EnvironmentTickCount();
1238
1239 // Check if any objects have reached their targets
1240 CheckAtTargets();
1241
1242 // Update SceneObjectGroups that have scheduled themselves for updates
1243 // Objects queue their updates onto all scene presences
1244 if (Frame % m_update_objects == 0)
1245 m_sceneGraph.UpdateObjectGroups();
1246 1220
1247 // Run through all ScenePresences looking for updates 1221 agentMS = tempOnRezMS = eventMS = backupMS = terrainMS = landMS = 0;
1248 // Presence updates and queued object updates for each presence are sent to clients
1249 if (Frame % m_update_presences == 0)
1250 m_sceneGraph.UpdatePresences();
1251 1222
1252 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) 1223 try
1253 if (Frame % m_update_coarse_locations == 0)
1254 { 1224 {
1255 List<Vector3> coarseLocations; 1225 tmpPhysicsMS2 = Util.EnvironmentTickCount();
1256 List<UUID> avatarUUIDs; 1226 if ((Frame % m_update_physics == 0) && m_physics_enabled)
1257 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60); 1227 m_sceneGraph.UpdatePreparePhysics();
1258 // Send coarse locations to clients 1228 physicsMS2 = Util.EnvironmentTickCountSubtract(tmpPhysicsMS2);
1259 ForEachScenePresence(delegate(ScenePresence presence) 1229
1230 // Apply any pending avatar force input to the avatar's velocity
1231 tmpAgentMS = Util.EnvironmentTickCount();
1232 if (Frame % m_update_entitymovement == 0)
1233 m_sceneGraph.UpdateScenePresenceMovement();
1234 agentMS = Util.EnvironmentTickCountSubtract(tmpAgentMS);
1235
1236 // Perform the main physics update. This will do the actual work of moving objects and avatars according to their
1237 // velocity
1238 tmpPhysicsMS = Util.EnvironmentTickCount();
1239 if (Frame % m_update_physics == 0)
1260 { 1240 {
1261 presence.SendCoarseLocations(coarseLocations, avatarUUIDs); 1241 if (m_physics_enabled)
1262 }); 1242 physicsFPS = m_sceneGraph.UpdatePhysics(MinFrameTime);
1263 } 1243
1264 1244 if (SynchronizeScene != null)
1265 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS); 1245 SynchronizeScene(this);
1266 1246 }
1267 // Delete temp-on-rez stuff 1247 physicsMS = Util.EnvironmentTickCountSubtract(tmpPhysicsMS);
1268 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1269 {
1270 int tmpTempOnRezMS = Util.EnvironmentTickCount();
1271 m_cleaningTemps = true;
1272 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1273 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1274 }
1275
1276 if (Frame % m_update_events == 0)
1277 {
1278 int evMS = Util.EnvironmentTickCount();
1279 UpdateEvents();
1280 eventMS = Util.EnvironmentTickCountSubtract(evMS); ;
1281 }
1282
1283 if (Frame % m_update_backup == 0)
1284 {
1285 int backMS = Util.EnvironmentTickCount();
1286 UpdateStorageBackup();
1287 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1288 }
1289
1290 if (Frame % m_update_terrain == 0)
1291 {
1292 int terMS = Util.EnvironmentTickCount();
1293 UpdateTerrain();
1294 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1295 }
1296
1297 //if (Frame % m_update_land == 0)
1298 //{
1299 // int ldMS = Util.EnvironmentTickCount();
1300 // UpdateLand();
1301 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1302 //}
1303
1304 frameMS = Util.EnvironmentTickCountSubtract(tmpFrameMS);
1305 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1306 lastCompletedFrame = Util.EnvironmentTickCount();
1307
1308 // if (Frame%m_update_avatars == 0)
1309 // UpdateInWorldTime();
1310 StatsReporter.AddPhysicsFPS(physicsFPS);
1311 StatsReporter.AddTimeDilation(TimeDilation);
1312 StatsReporter.AddFPS(1);
1313 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1314 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1315 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1316 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1317 StatsReporter.addFrameMS(frameMS);
1318 StatsReporter.addAgentMS(agentMS);
1319 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1320 StatsReporter.addOtherMS(otherMS);
1321 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1322 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1323
1324 if (LoginsDisabled && Frame == 20)
1325 {
1326// m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1327 1248
1328 // In 99.9% of cases it is a bad idea to manually force garbage collection. However, 1249 tmpAgentMS = Util.EnvironmentTickCount();
1329 // this is a rare case where we know we have just went through a long cycle of heap 1250
1330 // allocations, and there is no more work to be done until someone logs in 1251 // Check if any objects have reached their targets
1331 GC.Collect(); 1252 CheckAtTargets();
1253
1254 // Update SceneObjectGroups that have scheduled themselves for updates
1255 // Objects queue their updates onto all scene presences
1256 if (Frame % m_update_objects == 0)
1257 m_sceneGraph.UpdateObjectGroups();
1258
1259 // Run through all ScenePresences looking for updates
1260 // Presence updates and queued object updates for each presence are sent to clients
1261 if (Frame % m_update_presences == 0)
1262 m_sceneGraph.UpdatePresences();
1263
1264 // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client)
1265 if (Frame % m_update_coarse_locations == 0)
1266 {
1267 SceneGraph.GetCoarseLocations(out coarseLocations, out avatarUUIDs, 60);
1268 // Send coarse locations to clients
1269 ForEachScenePresence(delegate(ScenePresence presence)
1270 {
1271 presence.SendCoarseLocations(coarseLocations, avatarUUIDs);
1272 });
1273 }
1274
1275 agentMS += Util.EnvironmentTickCountSubtract(tmpAgentMS);
1276
1277 // Delete temp-on-rez stuff
1278 if (Frame % m_update_temp_cleaning == 0 && !m_cleaningTemps)
1279 {
1280 tmpTempOnRezMS = Util.EnvironmentTickCount();
1281 m_cleaningTemps = true;
1282 Util.FireAndForget(delegate { CleanTempObjects(); m_cleaningTemps = false; });
1283 tempOnRezMS = Util.EnvironmentTickCountSubtract(tmpTempOnRezMS);
1284 }
1285
1286 if (Frame % m_update_events == 0)
1287 {
1288 evMS = Util.EnvironmentTickCount();
1289 UpdateEvents();
1290 eventMS = Util.EnvironmentTickCountSubtract(evMS);
1291 }
1292
1293 if (Frame % m_update_backup == 0)
1294 {
1295 backMS = Util.EnvironmentTickCount();
1296 UpdateStorageBackup();
1297 backupMS = Util.EnvironmentTickCountSubtract(backMS);
1298 }
1299
1300 if (Frame % m_update_terrain == 0)
1301 {
1302 terMS = Util.EnvironmentTickCount();
1303 UpdateTerrain();
1304 terrainMS = Util.EnvironmentTickCountSubtract(terMS);
1305 }
1306
1307 //if (Frame % m_update_land == 0)
1308 //{
1309 // int ldMS = Util.EnvironmentTickCount();
1310 // UpdateLand();
1311 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1312 //}
1332 1313
1333 IConfig startupConfig = m_config.Configs["Startup"]; 1314 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1334 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false)) 1315 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1316
1317 // if (Frame%m_update_avatars == 0)
1318 // UpdateInWorldTime();
1319 StatsReporter.AddPhysicsFPS(physicsFPS);
1320 StatsReporter.AddTimeDilation(TimeDilation);
1321 StatsReporter.AddFPS(1);
1322 StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount());
1323 StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount());
1324 StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount());
1325 StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount());
1326
1327 // frameMS currently records work frame times, not total frame times (work + any required sleep to
1328 // reach min frame time.
1329 StatsReporter.addFrameMS(frameMS);
1330
1331 StatsReporter.addAgentMS(agentMS);
1332 StatsReporter.addPhysicsMS(physicsMS + physicsMS2);
1333 StatsReporter.addOtherMS(otherMS);
1334 StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount());
1335 StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS());
1336
1337 if (LoginsDisabled && Frame == 20)
1335 { 1338 {
1336 // This handles a case of a region having no scripts for the RegionReady module 1339 // m_log.DebugFormat("{0} {1} {2}", LoginsDisabled, m_sceneGraph.GetActiveScriptsCount(), LoginLock);
1337 if (m_sceneGraph.GetActiveScriptsCount() == 0) 1340
1341 // In 99.9% of cases it is a bad idea to manually force garbage collection. However,
1342 // this is a rare case where we know we have just went through a long cycle of heap
1343 // allocations, and there is no more work to be done until someone logs in
1344 GC.Collect();
1345
1346 IConfig startupConfig = m_config.Configs["Startup"];
1347 if (startupConfig == null || !startupConfig.GetBoolean("StartDisabled", false))
1338 { 1348 {
1339 // need to be able to tell these have changed in RegionReady 1349 // This handles a case of a region having no scripts for the RegionReady module
1340 LoginLock = false; 1350 if (m_sceneGraph.GetActiveScriptsCount() == 0)
1341 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName); 1351 {
1352 // need to be able to tell these have changed in RegionReady
1353 LoginLock = false;
1354 EventManager.TriggerLoginsEnabled(RegionInfo.RegionName);
1355 }
1356 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName);
1357
1358 // For RegionReady lockouts
1359 if(LoginLock == false)
1360 {
1361 LoginsDisabled = false;
1362 }
1363
1364 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1342 } 1365 }
1343 m_log.DebugFormat("[REGION]: Enabling logins for {0}", RegionInfo.RegionName); 1366 else
1344
1345 // For RegionReady lockouts
1346 if(LoginLock == false)
1347 { 1367 {
1348 LoginsDisabled = false; 1368 StartDisabled = true;
1369 LoginsDisabled = true;
1349 } 1370 }
1350
1351 m_sceneGridService.InformNeighborsThatRegionisUp(RequestModuleInterface<INeighbourService>(), RegionInfo);
1352 }
1353 else
1354 {
1355 StartDisabled = true;
1356 LoginsDisabled = true;
1357 } 1371 }
1358 } 1372 }
1359 } 1373 catch (Exception e)
1360 catch (NotImplementedException) 1374 {
1361 { 1375 m_log.ErrorFormat(
1362 throw; 1376 "[SCENE]: Failed on region {0} with exception {1}{2}",
1363 } 1377 RegionInfo.RegionName, e.Message, e.StackTrace);
1364 catch (Exception e) 1378 }
1365 { 1379
1366 m_log.ErrorFormat( 1380 EventManager.TriggerRegionHeartbeatEnd(this);
1367 "[SCENE]: Failed on region {0} with exception {1}{2}",
1368 RegionInfo.RegionName, e.Message, e.StackTrace);
1369 }
1370 1381
1371 EventManager.TriggerRegionHeartbeatEnd(this); 1382 // Tell the watchdog that this thread is still alive
1383 Watchdog.UpdateThread();
1372 1384
1373 maintc = Util.EnvironmentTickCountSubtract(maintc); 1385// previousFrameTick = m_lastFrameTick;
1374 maintc = (int)(MinFrameTime * 1000) - maintc; 1386 m_lastFrameTick = Util.EnvironmentTickCount();
1387 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1388 maintc = (int)(MinFrameTime * 1000) - maintc;
1375 1389
1376 if (maintc > 0) 1390 if (maintc > 0)
1377 Thread.Sleep(maintc); 1391 Thread.Sleep(maintc);
1378 1392
1379 // Tell the watchdog that this thread is still alive 1393 // Optionally warn if a frame takes double the amount of time that it should.
1380 Watchdog.UpdateThread(); 1394// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
1395// m_log.WarnFormat(
1396// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1397// Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1398// MinFrameTime * 1000,
1399// RegionInfo.RegionName);
1400 }
1381 } 1401 }
1382 1402
1383 public void AddGroupTarget(SceneObjectGroup grp) 1403 public void AddGroupTarget(SceneObjectGroup grp)
diff --git a/OpenSim/Region/Framework/Scenes/SceneBase.cs b/OpenSim/Region/Framework/Scenes/SceneBase.cs
index 495cede..9c6b884 100644
--- a/OpenSim/Region/Framework/Scenes/SceneBase.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneBase.cs
@@ -149,9 +149,13 @@ namespace OpenSim.Region.Framework.Scenes
149 #region Update Methods 149 #region Update Methods
150 150
151 /// <summary> 151 /// <summary>
152 /// Normally called once every frame/tick to let the world preform anything required (like running the physics simulation) 152 /// Called to update the scene loop by a number of frames and until shutdown.
153 /// </summary> 153 /// </summary>
154 public abstract void Update(); 154 /// <param name="frames">
155 /// Number of frames to update. Exits on shutdown even if there are frames remaining.
156 /// If -1 then updates until shutdown.
157 /// </param>
158 public abstract void Update(int frames);
155 159
156 #endregion 160 #endregion
157 161
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index b84660a..704d12d 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2293,7 +2293,7 @@ namespace OpenSim.Region.Framework.Scenes
2293 { 2293 {
2294 if (direc.Z > 2.0f) 2294 if (direc.Z > 2.0f)
2295 { 2295 {
2296 direc.Z *= 3.0f; 2296 direc.Z *= 2.6f;
2297 2297
2298 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. 2298 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2299 Animator.TrySetMovementAnimation("PREJUMP"); 2299 Animator.TrySetMovementAnimation("PREJUMP");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
index 442cb8b..cfea10d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change. 81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
82 sp.Flying = true; 82 sp.Flying = true;
83 83
84 m_scene.Update(); 84 m_scene.Update(1);
85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos)); 85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
86 86
87 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 87 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -91,7 +91,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
91 Assert.That( 91 Assert.That(
92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); 92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
93 93
94 m_scene.Update(); 94 m_scene.Update(1);
95 95
96 // We should really check the exact figure. 96 // We should really check the exact figure.
97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X)); 97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -99,8 +99,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X)); 100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
101 101
102 for (int i = 0; i < 10; i++) 102 m_scene.Update(10);
103 m_scene.Update();
104 103
105 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 104 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
106 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move"); 105 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
@@ -116,7 +115,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
116 Assert.That( 115 Assert.That(
117 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); 116 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
118 117
119 m_scene.Update(); 118 m_scene.Update(1);
120 119
121 // We should really check the exact figure. 120 // We should really check the exact figure.
122 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X)); 121 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -124,8 +123,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
124 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 123 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 124 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
126 125
127 for (int i = 0; i < 10; i++) 126 m_scene.Update(10);
128 m_scene.Update();
129 127
130 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos); 128 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
131 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move"); 129 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
index c5a76b2..bebc10c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs
@@ -63,17 +63,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests
63 63
64 Thread testThread = new Thread(testClass.run); 64 Thread testThread = new Thread(testClass.run);
65 65
66 try 66 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against
67 { 67 // A thread abort exception in the simulator code.
68 // Seems kind of redundant to start a thread and then join it, however.. We need to protect against 68 testThread.Start();
69 // A thread abort exception in the simulator code. 69 testThread.Join();
70 testThread.Start(); 70
71 testThread.Join();
72 }
73 catch (ThreadAbortException)
74 {
75
76 }
77 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message); 71 Assert.That(testClass.results.Result, Is.EqualTo(true), testClass.results.Message);
78 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod()); 72 // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
79 } 73 }
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
index 8b8aea5..5c9a77d 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs
@@ -61,7 +61,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
61 TestHelpers.InMethod(); 61 TestHelpers.InMethod();
62 62
63 Scene scene = SceneHelpers.SetupScene(); 63 Scene scene = SceneHelpers.SetupScene();
64 scene.Update(); 64 scene.Update(1);
65 65
66 Assert.That(scene.Frame, Is.EqualTo(1)); 66 Assert.That(scene.Frame, Is.EqualTo(1));
67 } 67 }
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index 9a7e9e8..eea0b2e 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -238,7 +238,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
238 // For now, we'll make the scene presence fly to simplify this test, but this needs to change. 238 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
239 npc.Flying = true; 239 npc.Flying = true;
240 240
241 m_scene.Update(); 241 m_scene.Update(1);
242 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 242 Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
243 243
244 Vector3 targetPos = startPos + new Vector3(0, 10, 0); 244 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
@@ -249,7 +249,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
249 Assert.That( 249 Assert.That(
250 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); 250 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
251 251
252 m_scene.Update(); 252 m_scene.Update(1);
253 253
254 // We should really check the exact figure. 254 // We should really check the exact figure.
255 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); 255 Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X));
@@ -257,8 +257,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
257 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 257 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
258 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); 258 Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X));
259 259
260 for (int i = 0; i < 10; i++) 260 m_scene.Update(10);
261 m_scene.Update();
262 261
263 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); 262 double distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
264 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move"); 263 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on first move");
@@ -275,7 +274,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
275 Assert.That( 274 Assert.That(
276 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); 275 npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
277 276
278 m_scene.Update(); 277 m_scene.Update(1);
279 278
280 // We should really check the exact figure. 279 // We should really check the exact figure.
281 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X)); 280 Assert.That(npc.AbsolutePosition.X, Is.GreaterThan(startPos.X));
@@ -283,8 +282,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
283 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); 282 Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
284 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); 283 Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
285 284
286 for (int i = 0; i < 10; i++) 285 m_scene.Update(10);
287 m_scene.Update();
288 286
289 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos); 287 distanceToTarget = Util.GetDistanceTo(npc.AbsolutePosition, targetPos);
290 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move"); 288 Assert.That(distanceToTarget, Is.LessThan(1), "NPC not within 1 unit of target position on second move");
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index 6f6ed7f..3bd15ce 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.Physics.Meshing
358 358
359 if (physicsParms == null) 359 if (physicsParms == null)
360 { 360 {
361 m_log.Warn("[MESH]: no recognized physics mesh found in mesh asset"); 361 m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
362 return false; 362 return false;
363 } 363 }
364 364
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 6d1f41d..8397eb4 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -115,6 +115,11 @@ namespace OpenSim.Region.Physics.OdePlugin
115 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. 115 private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes.
116 116
117 /// <summary> 117 /// <summary>
118 /// Base movement for calculating tilt.
119 /// </summary>
120 private float m_tiltBaseMovement = (float)Math.Sqrt(2);
121
122 /// <summary>
118 /// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider 123 /// Used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider
119 /// </summary> 124 /// </summary>
120 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; 125 private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f;
@@ -524,14 +529,14 @@ namespace OpenSim.Region.Physics.OdePlugin
524 if (movementVector.Y > 0) 529 if (movementVector.Y > 0)
525 { 530 {
526 // northeast 531 // northeast
527 movementVector.X = (float)Math.Sqrt(2.0); 532 movementVector.X = m_tiltBaseMovement;
528 movementVector.Y = (float)Math.Sqrt(2.0); 533 movementVector.Y = m_tiltBaseMovement;
529 } 534 }
530 else 535 else
531 { 536 {
532 // southeast 537 // southeast
533 movementVector.X = (float)Math.Sqrt(2.0); 538 movementVector.X = m_tiltBaseMovement;
534 movementVector.Y = -(float)Math.Sqrt(2.0); 539 movementVector.Y = -m_tiltBaseMovement;
535 } 540 }
536 } 541 }
537 else 542 else
@@ -540,14 +545,14 @@ namespace OpenSim.Region.Physics.OdePlugin
540 if (movementVector.Y > 0) 545 if (movementVector.Y > 0)
541 { 546 {
542 // northwest 547 // northwest
543 movementVector.X = -(float)Math.Sqrt(2.0); 548 movementVector.X = -m_tiltBaseMovement;
544 movementVector.Y = (float)Math.Sqrt(2.0); 549 movementVector.Y = m_tiltBaseMovement;
545 } 550 }
546 else 551 else
547 { 552 {
548 // southwest 553 // southwest
549 movementVector.X = -(float)Math.Sqrt(2.0); 554 movementVector.X = -m_tiltBaseMovement;
550 movementVector.Y = -(float)Math.Sqrt(2.0); 555 movementVector.Y = -m_tiltBaseMovement;
551 } 556 }
552 } 557 }
553 558
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 97890ee..1f79cd8 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -842,17 +842,23 @@ namespace OpenSim.Region.Physics.OdePlugin
842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage 842 mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
843 843
844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory 844 mesh.releaseSourceMeshData(); // free up the original mesh data to save memory
845 if (m_MeshToTriMeshMap.ContainsKey(mesh))
846 {
847 _triMeshData = m_MeshToTriMeshMap[mesh];
848 }
849 else
850 {
851 _triMeshData = d.GeomTriMeshDataCreate();
852 845
853 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); 846 // We must lock here since m_MeshToTriMeshMap is static and multiple scene threads may call this method at
854 d.GeomTriMeshDataPreprocess(_triMeshData); 847 // the same time.
855 m_MeshToTriMeshMap[mesh] = _triMeshData; 848 lock (m_MeshToTriMeshMap)
849 {
850 if (m_MeshToTriMeshMap.ContainsKey(mesh))
851 {
852 _triMeshData = m_MeshToTriMeshMap[mesh];
853 }
854 else
855 {
856 _triMeshData = d.GeomTriMeshDataCreate();
857
858 d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
859 d.GeomTriMeshDataPreprocess(_triMeshData);
860 m_MeshToTriMeshMap[mesh] = _triMeshData;
861 }
856 } 862 }
857 863
858// _parent_scene.waitForSpaceUnlock(m_targetSpace); 864// _parent_scene.waitForSpaceUnlock(m_targetSpace);
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 598530c..842ff91 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -181,8 +181,15 @@ namespace OpenSim.Region.Physics.OdePlugin
181 private float avPIDP = 1400f; 181 private float avPIDP = 1400f;
182 private float avCapRadius = 0.37f; 182 private float avCapRadius = 0.37f;
183 private float avStandupTensor = 2000000f; 183 private float avStandupTensor = 2000000f;
184 private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode 184
185 public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } } 185 /// <summary>
186 /// true = old compatibility mode with leaning capsule; false = new corrected mode
187 /// </summary>
188 /// <remarks>
189 /// Even when set to false, the capsule still tilts but this is done in a different way.
190 /// </remarks>
191 public bool IsAvCapsuleTilted { get; private set; }
192
186 private float avDensity = 80f; 193 private float avDensity = 80f;
187// private float avHeightFudgeFactor = 0.52f; 194// private float avHeightFudgeFactor = 0.52f;
188 private float avMovementDivisorWalk = 1.3f; 195 private float avMovementDivisorWalk = 1.3f;
@@ -501,7 +508,7 @@ namespace OpenSim.Region.Physics.OdePlugin
501 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); 508 avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f);
502 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); 509 avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f);
503 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); 510 avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
504 avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); 511 IsAvCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false);
505 512
506 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); 513 contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
507 514
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index d4108d7..7712076 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -401,16 +401,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
401// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count); 401// sb.AppendFormat("Assemblies loaded : {0}\n", m_Assemblies.Count);
402 402
403 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this); 403 SensorRepeat sr = AsyncCommandManager.GetSensorRepeatPlugin(this);
404 sb.AppendFormat("Sensors : {0}\n", sr.SensorsCount); 404 sb.AppendFormat("Sensors : {0}\n", sr != null ? sr.SensorsCount : 0);
405 405
406 Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this); 406 Dataserver ds = AsyncCommandManager.GetDataserverPlugin(this);
407 sb.AppendFormat("Dataserver requests : {0}\n", ds.DataserverRequestsCount); 407 sb.AppendFormat("Dataserver requests : {0}\n", ds != null ? ds.DataserverRequestsCount : 0);
408 408
409 Timer t = AsyncCommandManager.GetTimerPlugin(this); 409 Timer t = AsyncCommandManager.GetTimerPlugin(this);
410 sb.AppendFormat("Timers : {0}\n", t.TimersCount); 410 sb.AppendFormat("Timers : {0}\n", t != null ? t.TimersCount : 0);
411 411
412 Listener l = AsyncCommandManager.GetListenerPlugin(this); 412 Listener l = AsyncCommandManager.GetListenerPlugin(this);
413 sb.AppendFormat("Listeners : {0}\n", l.ListenerCount); 413 sb.AppendFormat("Listeners : {0}\n", l != null ? l.ListenerCount : 0);
414 414
415 return sb.ToString(); 415 return sb.ToString();
416 } 416 }