aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
authordiva2009-02-12 23:23:44 +0000
committerdiva2009-02-12 23:23:44 +0000
commit7a274a7e1dfa651c17cb33ca1994f321ccddc005 (patch)
tree2864e53e24a97c3d77a83f2b2d852bf1119415d9 /OpenSim/Region/Framework/Scenes/ScenePresence.cs
parent* Make it possible to load and save inventory archives while a user is not lo... (diff)
downloadopensim-SC-7a274a7e1dfa651c17cb33ca1994f321ccddc005.zip
opensim-SC-7a274a7e1dfa651c17cb33ca1994f321ccddc005.tar.gz
opensim-SC-7a274a7e1dfa651c17cb33ca1994f321ccddc005.tar.bz2
opensim-SC-7a274a7e1dfa651c17cb33ca1994f321ccddc005.tar.xz
Makes region crossings asynchronous. Moved the bulk of the original code out of ScenePresence and into SceneCommunicationService, where it should be (next to RequestTeleportToLocation). No changes in the crossing mechanism itself, yet. But this change opens the way to doing crossings as slowly as it needs to be, outside the simulator Update loop.
Note: weirdnesses may occur!
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs164
1 files changed, 35 insertions, 129 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2dd305a..f841707 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -547,6 +547,13 @@ namespace OpenSim.Region.Framework.Scenes
547 get { return m_animations; } 547 get { return m_animations; }
548 } 548 }
549 549
550 private bool m_inTransit;
551 public bool IsInTransit
552 {
553 get { return m_inTransit; }
554 set { m_inTransit = value; }
555 }
556
550 #endregion 557 #endregion
551 558
552 #region Constructor(s) 559 #region Constructor(s)
@@ -850,7 +857,7 @@ namespace OpenSim.Region.Framework.Scenes
850 857
851 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); 858 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid);
852 if (userInfo != null) 859 if (userInfo != null)
853 userInfo.FetchInventory(); 860 userInfo.FetchInventory();
854 else 861 else
855 m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); 862 m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid);
856 863
@@ -2377,15 +2384,31 @@ namespace OpenSim.Region.Framework.Scenes
2377 pos2.Y = pos2.Y + (vel.Y*timeStep); 2384 pos2.Y = pos2.Y + (vel.Y*timeStep);
2378 pos2.Z = pos2.Z + (vel.Z*timeStep); 2385 pos2.Z = pos2.Z + (vel.Z*timeStep);
2379 2386
2380 if ((pos2.X < 0) || (pos2.X > Constants.RegionSize)) 2387 if (!IsInTransit)
2381 { 2388 {
2382 CrossToNewRegion(); 2389 if ((pos2.X < 0) || (pos2.X > Constants.RegionSize))
2383 } 2390 {
2391 CrossToNewRegion();
2392 }
2384 2393
2385 if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize)) 2394 if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize))
2395 {
2396 CrossToNewRegion();
2397 }
2398 }
2399 else
2386 { 2400 {
2387 CrossToNewRegion(); 2401 RemoveFromPhysicalScene();
2402 // This constant has been inferred from experimentation
2403 // I'm not sure what this value should be, so I tried a few values.
2404 timeStep = 0.04f;
2405 pos2 = AbsolutePosition;
2406 pos2.X = pos2.X + (vel.X * timeStep);
2407 pos2.Y = pos2.Y + (vel.Y * timeStep);
2408 pos2.Z = pos2.Z + (vel.Z * timeStep);
2409 m_pos = pos2;
2388 } 2410 }
2411
2389 } 2412 }
2390 2413
2391 /// <summary> 2414 /// <summary>
@@ -2396,130 +2419,13 @@ namespace OpenSim.Region.Framework.Scenes
2396 /// </summary> 2419 /// </summary>
2397 protected void CrossToNewRegion() 2420 protected void CrossToNewRegion()
2398 { 2421 {
2399 Vector3 pos = AbsolutePosition; 2422 m_inTransit = true;
2400 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); 2423 m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying);
2401 uint neighbourx = m_regionInfo.RegionLocX; 2424 }
2402 uint neighboury = m_regionInfo.RegionLocY;
2403
2404 // distance to edge that will trigger crossing
2405 const float boundaryDistance = 1.7f;
2406
2407 // distance into new region to place avatar
2408 const float enterDistance = 0.1f;
2409
2410 if (pos.X < boundaryDistance)
2411 {
2412 neighbourx--;
2413 newpos.X = Constants.RegionSize - enterDistance;
2414 }
2415 else if (pos.X > Constants.RegionSize - boundaryDistance)
2416 {
2417 neighbourx++;
2418 newpos.X = enterDistance;
2419 }
2420
2421 if (pos.Y < boundaryDistance)
2422 {
2423 neighboury--;
2424 newpos.Y = Constants.RegionSize - enterDistance;
2425 }
2426 else if (pos.Y > Constants.RegionSize - boundaryDistance)
2427 {
2428 neighboury++;
2429 newpos.Y = enterDistance;
2430 }
2431
2432 Vector3 vel = m_velocity;
2433 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
2434 SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle);
2435 if (neighbourRegion != null && ValidateAttachments())
2436 {
2437 // When the neighbour is informed of the border crossing, it will set up CAPS handlers for the avatar
2438 // This means we need to remove the current caps handler here and possibly compensate later,
2439 // in case both scenes are being hosted on the same region server. Messy
2440 //m_scene.RemoveCapsHandler(UUID);
2441 newpos = newpos + (vel);
2442
2443 CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(UUID);
2444 if (userInfo != null)
2445 {
2446 userInfo.DropInventory();
2447 }
2448 else
2449 {
2450 m_log.WarnFormat("[SCENE PRESENCE]: No cached user info found for {0} {1} on leaving region", Name, UUID);
2451 }
2452
2453 bool crossingSuccessful =
2454 m_scene.InformNeighbourOfCrossing(neighbourHandle, m_controllingClient.AgentId, newpos,
2455 m_physicsActor.Flying);
2456 if (crossingSuccessful)
2457 {
2458 // Next, let's close the child agent connections that are too far away.
2459 CloseChildAgents(neighbourx, neighboury);
2460
2461 //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo();
2462 m_controllingClient.RequestClientInfo();
2463
2464 //Console.WriteLine("BEFORE CROSS");
2465 //Scene.DumpChildrenSeeds(UUID);
2466 //DumpKnownRegions();
2467 string agentcaps;
2468 if (!m_knownChildRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
2469 {
2470 m_log.ErrorFormat("[SCENE PRESENCE]: No CAPS information for region handle {0}, exiting CrossToNewRegion.",
2471 neighbourRegion.RegionHandle);
2472 return;
2473 }
2474 // TODO Should construct this behind a method
2475 string capsPath =
2476 "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort
2477 + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/";
2478
2479 m_log.DebugFormat("[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, m_uuid);
2480
2481 IEventQueue eq = m_scene.RequestModuleInterface<IEventQueue>();
2482 if (eq != null)
2483 {
2484 eq.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint,
2485 capsPath, UUID, ControllingClient.SessionId);
2486 }
2487 else
2488 {
2489 m_controllingClient.CrossRegion(neighbourHandle, newpos, vel, neighbourRegion.ExternalEndPoint,
2490 capsPath);
2491 }
2492
2493 MakeChildAgent();
2494 // now we have a child agent in this region. Request all interesting data about other (root) agents
2495 SendInitialFullUpdateToAllClients();
2496
2497 CrossAttachmentsIntoNewRegion(neighbourHandle, true);
2498
2499 // m_scene.SendKillObject(m_localId);
2500
2501 m_scene.NotifyMyCoarseLocationChange();
2502 // the user may change their profile information in other region,
2503 // so the userinfo in UserProfileCache is not reliable any more, delete it
2504 if (m_scene.NeedSceneCacheClear(UUID))
2505 {
2506 m_scene.CommsManager.UserProfileCacheService.RemoveUser(UUID);
2507 m_log.DebugFormat(
2508 "[SCENE PRESENCE]: User {0} is going to another region, profile cache removed", UUID);
2509 }
2510 }
2511 else
2512 {
2513 // Restore the user structures that we needed to delete before asking the receiving region
2514 // to complete the crossing
2515 userInfo.FetchInventory();
2516 m_scene.CapsModule.AddCapsHandler(UUID);
2517 }
2518 }
2519 2425
2520 //Console.WriteLine("AFTER CROSS"); 2426 public void RestoreInCurrentScene()
2521 //Scene.DumpChildrenSeeds(UUID); 2427 {
2522 //DumpKnownRegions(); 2428 AddToPhysicalScene();
2523 } 2429 }
2524 2430
2525 /// <summary> 2431 /// <summary>