aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2014-10-24 18:10:28 +0100
committerUbitUmarov2014-10-24 18:10:28 +0100
commit4571e5bc3e284c916d1ae4dd6429b80a8028b8e0 (patch)
tree29420430b8535b1498b3fb656cb6b20e6409619f
parent TEST**** wingridproxy detection at grid login. Untested possible not (diff)
downloadopensim-SC_OLD-4571e5bc3e284c916d1ae4dd6429b80a8028b8e0.zip
opensim-SC_OLD-4571e5bc3e284c916d1ae4dd6429b80a8028b8e0.tar.gz
opensim-SC_OLD-4571e5bc3e284c916d1ae4dd6429b80a8028b8e0.tar.bz2
opensim-SC_OLD-4571e5bc3e284c916d1ae4dd6429b80a8028b8e0.tar.xz
try to make SOG crossings full async. Simplify some borders checking....
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs2
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs182
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs6
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs357
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs146
5 files changed, 426 insertions, 267 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 6385aed..6f42990 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3865,7 +3865,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3865 { 3865 {
3866 SceneObjectPart part = (SceneObjectPart)update.Entity; 3866 SceneObjectPart part = (SceneObjectPart)update.Entity;
3867 3867
3868 if (part.ParentGroup.IsDeleted) 3868 if (part.ParentGroup.IsDeleted || part.ParentGroup.inTransit)
3869 continue; 3869 continue;
3870 3870
3871 if (part.ParentGroup.IsAttachment) 3871 if (part.ParentGroup.IsAttachment)
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index c898946..b855233 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -1385,13 +1385,61 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1385 1385
1386 1386
1387 #region Agent Crossings 1387 #region Agent Crossings
1388 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) 1388
1389 public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, out string version, out string reason)
1390 {
1391 reason = String.Empty;
1392 version = String.Empty;
1393
1394 UUID agentID = agent.UUID;
1395 ulong destinyHandle = destiny.RegionHandle;
1396
1397 ExpiringCache<ulong, DateTime> r;
1398 DateTime banUntil;
1399 if (m_bannedRegions.TryGetValue(agentID, out r))
1400 {
1401 if (r.TryGetValue(destinyHandle, out banUntil))
1402 {
1403 if (DateTime.Now < banUntil)
1404 {
1405 reason = "Cannot connect to region";
1406 return false;
1407 }
1408 r.Remove(destinyHandle);
1409 }
1410 }
1411 else
1412 {
1413 r = null;
1414 }
1415
1416 Scene ascene = agent.Scene;
1417
1418 if (!ascene.SimulationService.QueryAccess(destiny, agentID, position, out version, out reason))
1419 {
1420 if (r == null)
1421 {
1422 r = new ExpiringCache<ulong, DateTime>();
1423 r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
1424
1425 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(30));
1426 }
1427 else
1428 {
1429 r.Add(destinyHandle, DateTime.Now + TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
1430 }
1431 return false;
1432 }
1433 return true;
1434 }
1435
1436 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos)
1389 { 1437 {
1390 string r = String.Empty; 1438 string r = String.Empty;
1391 return GetDestination(scene, agentID, pos, out xDest, out yDest, out version, out newpos, out r); 1439 return GetDestination(scene, agentID, pos, out version, out newpos, out r);
1392 } 1440 }
1393 1441
1394 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos, out string reason) 1442 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos, out string reason)
1395 { 1443 {
1396 version = String.Empty; 1444 version = String.Empty;
1397 reason = String.Empty; 1445 reason = String.Empty;
@@ -1400,9 +1448,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1400// m_log.DebugFormat( 1448// m_log.DebugFormat(
1401// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1449// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1402 1450
1403 uint neighbourx = scene.RegionInfo.RegionLocX; 1451 RegionInfo regInfo = scene.RegionInfo;
1404 uint neighboury = scene.RegionInfo.RegionLocY; 1452
1453 uint neighbourx = regInfo.RegionLocX;
1454 uint neighboury = regInfo.RegionLocY;
1405 const float boundaryDistance = 0.7f; 1455 const float boundaryDistance = 0.7f;
1456
1457/*
1406 Vector3 northCross = new Vector3(0, boundaryDistance, 0); 1458 Vector3 northCross = new Vector3(0, boundaryDistance, 0);
1407 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); 1459 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
1408 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); 1460 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
@@ -1463,11 +1515,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1463 1515
1464 newpos.X = Util.Clamp(newpos.X, enterDistance, maxX); 1516 newpos.X = Util.Clamp(newpos.X, enterDistance, maxX);
1465 newpos.Y = Util.Clamp(newpos.Y, enterDistance, maxY); 1517 newpos.Y = Util.Clamp(newpos.Y, enterDistance, maxY);
1518*/
1519 float regionSizeX = regInfo.RegionSizeX;
1520 float regionSizeY = regInfo.RegionSizeY;
1521
1522 if (pos.X < boundaryDistance)
1523 neighbourx--;
1524 else if (pos.X > regionSizeX - boundaryDistance)
1525 neighbourx += (uint)(regionSizeX / Constants.RegionSize);
1466 1526
1467 xDest = neighbourx; 1527 if (pos.Y < boundaryDistance)
1468 yDest = neighboury; 1528 neighboury--;
1529 else if (pos.Y > regionSizeY - boundaryDistance)
1530 neighboury += (uint)(regionSizeY / Constants.RegionSize);
1469 1531
1470 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 1532 int x = (int)(neighbourx * Constants.RegionSize);
1533 int y = (int)(neighboury * Constants.RegionSize);
1471 1534
1472 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); 1535 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
1473 1536
@@ -1489,6 +1552,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1489 } 1552 }
1490 1553
1491 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 1554 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
1555 if (neighbourRegion == null)
1556 {
1557 reason = "";
1558 return null;
1559 }
1560
1561 float newRegionSizeX = neighbourRegion.RegionSizeX;
1562 float newRegionSizeY = neighbourRegion.RegionSizeY;
1563
1564 if (pos.X < boundaryDistance)
1565 newpos.X += newRegionSizeX;
1566 else if (pos.X > regionSizeX - boundaryDistance)
1567 newpos.X -= regionSizeX;
1568
1569 if (pos.Y < boundaryDistance)
1570 newpos.Y += newRegionSizeY;
1571 else if (pos.Y > regionSizeY - boundaryDistance)
1572 newpos.Y -= regionSizeY;
1573
1574 const float enterDistance = 0.5f;
1575 newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
1576 newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
1492 1577
1493 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) 1578 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
1494 { 1579 {
@@ -1543,13 +1628,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1543 1628
1544 Vector3 pos = agent.AbsolutePosition + agent.Velocity; 1629 Vector3 pos = agent.AbsolutePosition + agent.Velocity;
1545 1630
1546 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, out x, out y, out version, out newpos, out reason); 1631 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos, out version, out newpos, out reason);
1547 if (neighbourRegion == null) 1632 if (neighbourRegion == null)
1548 { 1633 {
1549 if (reason == String.Empty) 1634 if (reason != String.Empty)
1550 agent.ControllingClient.SendAlertMessage("Cannot cross to region"); 1635 agent.ControllingClient.SendAlertMessage("Cannot cross to region");
1551 else
1552 agent.ControllingClient.SendAlertMessage("Cannot cross to region: " + reason);
1553 return agent; 1636 return agent;
1554 } 1637 }
1555 1638
@@ -2346,6 +2429,62 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2346 2429
2347 #region Object Transfers 2430 #region Object Transfers
2348 2431
2432 public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos)
2433 {
2434 newpos = targetPosition;
2435
2436 Scene scene = grp.Scene;
2437 if (scene == null)
2438 return null;
2439
2440 RegionInfo srcRegionInfo = scene.RegionInfo;
2441 int neighbourx = (int)srcRegionInfo.RegionLocX;
2442 int neighboury = (int)srcRegionInfo.RegionLocY;
2443 float regionSizeX = srcRegionInfo.RegionSizeX;
2444 float regionSizeY = srcRegionInfo.RegionSizeY;
2445
2446 float edgeJitter = 0.2f;
2447
2448 if (targetPosition.X < edgeJitter)
2449 neighbourx--;
2450 else if (targetPosition.X > regionSizeX - edgeJitter)
2451 neighbourx += (int)(regionSizeX / Constants.RegionSize);
2452
2453 if (targetPosition.Y < edgeJitter)
2454 neighboury--;
2455 else if (targetPosition.Y > regionSizeY - edgeJitter)
2456 neighboury += (int)(regionSizeY / Constants.RegionSize);
2457
2458 int x = neighbourx * (int)Constants.RegionSize;
2459 int y = neighboury * (int)Constants.RegionSize;
2460
2461 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
2462 if (neighbourRegion == null)
2463 {
2464 return null;
2465 }
2466
2467 float newRegionSizeX = neighbourRegion.RegionSizeX;
2468 float newRegionSizeY = neighbourRegion.RegionSizeY;
2469
2470 if (targetPosition.X < edgeJitter)
2471 newpos.X += newRegionSizeX;
2472 else if (targetPosition.X > regionSizeX - edgeJitter)
2473 newpos.X -= regionSizeX;
2474
2475 if (targetPosition.Y < edgeJitter)
2476 newpos.Y += newRegionSizeY;
2477 else if (targetPosition.Y > regionSizeY - edgeJitter)
2478 newpos.Y -= regionSizeY;
2479
2480 const float enterDistance = 0.2f;
2481 newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
2482 newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
2483
2484 return neighbourRegion;
2485 }
2486
2487
2349 /// <summary> 2488 /// <summary>
2350 /// Move the given scene object into a new region depending on which region its absolute position has moved 2489 /// Move the given scene object into a new region depending on which region its absolute position has moved
2351 /// into. 2490 /// into.
@@ -2365,23 +2504,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2365 if (scene == null) 2504 if (scene == null)
2366 return; 2505 return;
2367 2506
2368// http://wiki.secondlife.com/wiki/STATUS_DIE_AT_EDGE
2369// DieAtEdge does NOT mean that objects can't cross regions.
2370// It just means they die when they go off world, unless
2371// RETURN_AT_EDGE is set.
2372// if (grp.RootPart.DIE_AT_EDGE)
2373// {
2374// // We remove the object here
2375// try
2376// {
2377// scene.DeleteSceneObject(grp, false);
2378// }
2379// catch (Exception)
2380// {
2381// m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
2382// }
2383// return;
2384// }
2385 2507
2386 int thisx = (int)scene.RegionInfo.RegionLocX; 2508 int thisx = (int)scene.RegionInfo.RegionLocX;
2387 int thisy = (int)scene.RegionInfo.RegionLocY; 2509 int thisy = (int)scene.RegionInfo.RegionLocY;
@@ -2594,7 +2716,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2594 /// true if the crossing itself was successful, false on failure 2716 /// true if the crossing itself was successful, false on failure
2595 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region 2717 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
2596 /// </returns> 2718 /// </returns>
2597 protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent) 2719 public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent)
2598 { 2720 {
2599 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); 2721 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
2600 2722
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index 0c34c90..84cdc15 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -93,9 +93,11 @@ namespace OpenSim.Region.Framework.Interfaces
93 93
94 void EnableChildAgent(ScenePresence agent, GridRegion region); 94 void EnableChildAgent(ScenePresence agent, GridRegion region);
95 95
96 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos); 96 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out string version, out Vector3 newpos);
97 97 GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition, out Vector3 newpos);
98 bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position, out string version, out string reason);
98 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 99 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
100 bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent);
99 101
100 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version); 102 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, string version);
101 103
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 0eed64e..a7e7294 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -516,6 +516,10 @@ namespace OpenSim.Region.Framework.Scenes
516 public uint ParentID; 516 public uint ParentID;
517 } 517 }
518 518
519
520 public bool inTransit = false;
521 public delegate SceneObjectGroup SOGCrossDelegate(SceneObjectGroup sog,Vector3 pos);
522
519 /// <summary> 523 /// <summary>
520 /// The absolute position of this scene object in the scene 524 /// The absolute position of this scene object in the scene
521 /// </summary> 525 /// </summary>
@@ -525,8 +529,8 @@ namespace OpenSim.Region.Framework.Scenes
525 set 529 set
526 { 530 {
527 Vector3 val = value; 531 Vector3 val = value;
528 532
529 if (Scene != null) 533 if (Scene != null && !inTransit)
530 { 534 {
531 if ( 535 if (
532 // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) 536 // (Scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E)
@@ -543,130 +547,10 @@ namespace OpenSim.Region.Framework.Scenes
543 || Scene.TestBorderCross(val, Cardinals.S)) 547 || Scene.TestBorderCross(val, Cardinals.S))
544 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 548 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
545 { 549 {
546 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 550 inTransit = true;
547 uint x = 0; 551 SOGCrossDelegate d = CrossAsync;
548 uint y = 0; 552 d.BeginInvoke(this, val, CrossAsyncCompleted, d);
549 string version = String.Empty; 553 return;
550 Vector3 newpos = Vector3.Zero;
551 OpenSim.Services.Interfaces.GridRegion destination = null;
552
553 if (m_rootPart.DIE_AT_EDGE || m_rootPart.RETURN_AT_EDGE)
554 {
555 // this should delete the grp in this case
556 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
557 // actually assume this sog was removed from simulation
558 return;
559 }
560
561 if (m_rootPart.KeyframeMotion != null)
562 m_rootPart.KeyframeMotion.StartCrossingCheck();
563
564 bool canCross = true;
565
566 foreach (ScenePresence av in m_linkedAvatars)
567 {
568 // We need to cross these agents. First, let's find
569 // out if any of them can't cross for some reason.
570 // We have to deny the crossing entirely if any
571 // of them are banned. Alternatively, we could
572 // unsit banned agents....
573
574
575 // We set the avatar position as being the object
576 // position to get the region to send to
577 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
578 {
579 canCross = false;
580 break;
581 }
582
583 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
584 }
585
586 if (canCross)
587 {
588 // We unparent the SP quietly so that it won't
589 // be made to stand up
590
591 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
592
593 foreach (ScenePresence av in m_linkedAvatars)
594 {
595 avtocrossInfo avinfo = new avtocrossInfo();
596 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
597 if (parentPart != null)
598 av.ParentUUID = parentPart.UUID;
599
600 avinfo.av = av;
601 avinfo.ParentID = av.ParentID;
602 avsToCross.Add(avinfo);
603
604 av.PrevSitOffset = av.OffsetPosition;
605 av.ParentID = 0;
606 }
607
608 // m_linkedAvatars.Clear();
609 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
610
611 // Normalize
612 if (val.X >= Constants.RegionSize)
613 val.X -= Constants.RegionSize;
614 if (val.Y >= Constants.RegionSize)
615 val.Y -= Constants.RegionSize;
616 if (val.X < 0)
617 val.X += Constants.RegionSize;
618 if (val.Y < 0)
619 val.Y += Constants.RegionSize;
620
621 // If it's deleted, crossing was successful
622 if (IsDeleted)
623 {
624 // foreach (ScenePresence av in m_linkedAvatars)
625 foreach (avtocrossInfo avinfo in avsToCross)
626 {
627 ScenePresence av = avinfo.av;
628 if (!av.IsInTransit) // just in case...
629 {
630 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
631
632 av.IsInTransit = true;
633
634 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
635 d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
636 }
637 else
638 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val);
639 }
640 avsToCross.Clear();
641 return;
642 }
643 else // cross failed, put avas back ??
644 {
645 foreach (avtocrossInfo avinfo in avsToCross)
646 {
647 ScenePresence av = avinfo.av;
648 av.ParentUUID = UUID.Zero;
649 av.ParentID = avinfo.ParentID;
650 // m_linkedAvatars.Add(av);
651 }
652 }
653 avsToCross.Clear();
654 }
655 else
656 {
657 if (m_rootPart.KeyframeMotion != null)
658 m_rootPart.KeyframeMotion.CrossingFailure();
659
660 if (RootPart.PhysActor != null)
661 {
662 RootPart.PhysActor.CrossingFailure();
663 }
664 }
665 Vector3 oldp = AbsolutePosition;
666 val.X = Util.Clamp<float>(oldp.X, 0.5f, (float)Constants.RegionSize - 0.5f);
667 val.Y = Util.Clamp<float>(oldp.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
668 // dont crash land StarShips
669 // val.Z = Util.Clamp<float>(oldp.Z, 0.5f, 4096.0f);
670 } 554 }
671 } 555 }
672 556
@@ -714,46 +598,197 @@ namespace OpenSim.Region.Framework.Scenes
714 part.TriggerScriptChangedEvent(Changed.POSITION); 598 part.TriggerScriptChangedEvent(Changed.POSITION);
715 } 599 }
716 } 600 }
601
602 Scene.EventManager.TriggerParcelPrimCountTainted();
603 }
604 }
717 605
718/* 606 public SceneObjectGroup CrossAsync(SceneObjectGroup sog, Vector3 val)
719 This seems not needed and should not be needed: 607 {
720 sp absolute position depends on sit part absolute position fixed above. 608 Scene sogScene = sog.m_scene;
721 sp ParentPosition is not used anywhere. 609 IEntityTransferModule entityTransfer = sogScene.RequestModuleInterface<IEntityTransferModule>();
722 Since presence is sitting, viewer considers it 'linked' to root prim, so it will move/rotate it 610
723 Sending a extra packet with avatar position is not only bandwidth waste, but may cause jitter in viewers due to UPD nature. 611 Vector3 newpos = Vector3.Zero;
724 612 OpenSim.Services.Interfaces.GridRegion destination = null;
725 if (!m_dupeInProgress) 613
614 if (sog.RootPart.DIE_AT_EDGE)
615 {
616 try
617 {
618 sogScene.DeleteSceneObject(sog, false);
619 }
620 catch (Exception)
621 {
622 m_log.Warn("[SCENE]: exception when trying to remove the prim that crossed the border.");
623 }
624 return sog;
625 }
626
627 if (sog.RootPart.RETURN_AT_EDGE)
628 {
629 // We remove the object here
630 try
631 {
632 List<uint> localIDs = new List<uint>();
633 localIDs.Add(sog.RootPart.LocalId);
634 sogScene.AddReturn(sog.OwnerID, sog.Name, sog.AbsolutePosition,
635 "Returned at region cross");
636 sogScene.DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, UUID.Zero);
637 }
638 catch (Exception)
639 {
640 m_log.Warn("[SCENE]: exception when trying to return the prim that crossed the border.");
641 }
642 return sog;
643 }
644
645 if (sog.m_rootPart.KeyframeMotion != null)
646 sog.m_rootPart.KeyframeMotion.StartCrossingCheck();
647
648 if (entityTransfer == null)
649 return sog;
650
651 destination = entityTransfer.GetObjectDestination(sog, val, out newpos);
652 if (destination == null)
653 return sog;
654
655 if (sog.m_linkedAvatars.Count == 0)
656 {
657 entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true);
658 return sog;
659 }
660
661 string reason = String.Empty;
662 string version = String.Empty;
663
664 foreach (ScenePresence av in sog.m_linkedAvatars)
665 {
666 // We need to cross these agents. First, let's find
667 // out if any of them can't cross for some reason.
668 // We have to deny the crossing entirely if any
669 // of them are banned. Alternatively, we could
670 // unsit banned agents....
671
672 // We set the avatar position as being the object
673 // position to get the region to send to
674 if(!entityTransfer.checkAgentAccessToRegion(av, destination, newpos, out version, out reason))
675 {
676 return sog;
677 }
678 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
679 }
680
681 // We unparent the SP quietly so that it won't
682 // be made to stand up
683
684 List<avtocrossInfo> avsToCross = new List<avtocrossInfo>();
685
686 foreach (ScenePresence av in sog.m_linkedAvatars)
687 {
688 avtocrossInfo avinfo = new avtocrossInfo();
689 SceneObjectPart parentPart = sogScene.GetSceneObjectPart(av.ParentID);
690 if (parentPart != null)
691 av.ParentUUID = parentPart.UUID;
692
693 avinfo.av = av;
694 avinfo.ParentID = av.ParentID;
695 avsToCross.Add(avinfo);
696
697 av.PrevSitOffset = av.OffsetPosition;
698 av.ParentID = 0;
699 }
700
701 if (entityTransfer.CrossPrimGroupIntoNewRegion(destination, newpos, sog, true))
702 {
703 foreach (avtocrossInfo avinfo in avsToCross)
726 { 704 {
727 foreach (ScenePresence av in m_linkedAvatars) 705 ScenePresence av = avinfo.av;
706 if (!av.IsInTransit) // just in case...
728 { 707 {
729 SceneObjectPart p = m_scene.GetSceneObjectPart(av.ParentID); 708 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
730 if (p != null && m_parts.TryGetValue(p.UUID, out p)) 709
710 av.IsInTransit = true;
711
712// CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
713// d.BeginInvoke(av, val, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
714 entityTransfer.CrossAgentToNewRegionAsync(av, newpos, destination, av.Flying, version);
715 if(av.IsChildAgent)
731 { 716 {
732 Vector3 offset = p.GetWorldPosition() - av.ParentPosition; 717 if (av.ParentUUID != UUID.Zero)
733 av.AbsolutePosition += offset; 718 {
734// av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition 719 av.ClearControls();
735 av.SendAvatarDataToAllAgents(); 720 av.ParentPart = null;
721 }
736 } 722 }
723 av.ParentUUID = UUID.Zero;
724 // In any case
725 av.IsInTransit = false;
726
727 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", av.Firstname, av.Lastname);
737 } 728 }
729 else
730 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar already in transit {0} to {1}", av.Name, val);
731 }
732 avsToCross.Clear();
733 return sog;
734 }
735 else // cross failed, put avas back ??
736 {
737 foreach (avtocrossInfo avinfo in avsToCross)
738 {
739 ScenePresence av = avinfo.av;
740 av.ParentUUID = UUID.Zero;
741 av.ParentID = avinfo.ParentID;
738 } 742 }
739*/
740 //if (m_rootPart.PhysActor != null)
741 //{
742 //m_rootPart.PhysActor.Position =
743 //new PhysicsVector(m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y,
744 //m_rootPart.GroupPosition.Z);
745 //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor);
746 //}
747
748 if (Scene != null)
749 Scene.EventManager.TriggerParcelPrimCountTainted();
750 } 743 }
744 avsToCross.Clear();
745
746 return sog;
751 } 747 }
752 748
753 public override Vector3 Velocity 749 public void CrossAsyncCompleted(IAsyncResult iar)
754 { 750 {
755 get { return RootPart.Velocity; } 751 SOGCrossDelegate icon = (SOGCrossDelegate)iar.AsyncState;
756 set { RootPart.Velocity = value; } 752 SceneObjectGroup sog = icon.EndInvoke(iar);
753
754 if (sog.IsDeleted)
755 {
756 sog.inTransit = false; // just in case...
757 }
758 else
759 {
760 SceneObjectPart rootp = sog.m_rootPart;
761 Vector3 oldp = rootp.GroupPosition;
762 oldp.X = Util.Clamp<float>(oldp.X, 0.5f, sog.m_scene.RegionInfo.RegionSizeX - 0.5f);
763 oldp.Y = Util.Clamp<float>(oldp.Y, 0.5f, sog.m_scene.RegionInfo.RegionSizeY - 0.5f);
764 rootp.GroupPosition = oldp;
765
766 SceneObjectPart[] parts = sog.m_parts.GetArray();
767
768 foreach (SceneObjectPart part in parts)
769 {
770 if (part != rootp)
771 part.GroupPosition = oldp;
772 }
773
774 foreach (ScenePresence av in sog.m_linkedAvatars)
775 {
776 av.sitSOGmoved();
777 }
778
779 sog.Velocity = Vector3.Zero;
780
781 if (sog.m_rootPart.KeyframeMotion != null)
782 sog.m_rootPart.KeyframeMotion.CrossingFailure();
783
784 if (sog.RootPart.PhysActor != null)
785 {
786 sog.RootPart.PhysActor.CrossingFailure();
787 }
788
789 sog.inTransit = false;
790 sog.ScheduleGroupForFullUpdate();
791 }
757 } 792 }
758 793
759 private void CrossAgentToNewRegionCompleted(IAsyncResult iar) 794 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
@@ -784,6 +819,12 @@ namespace OpenSim.Region.Framework.Scenes
784 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); 819 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
785 } 820 }
786 821
822 public override Vector3 Velocity
823 {
824 get { return RootPart.Velocity; }
825 set { RootPart.Velocity = value; }
826 }
827
787 public override uint LocalId 828 public override uint LocalId
788 { 829 {
789 get { return m_rootPart.LocalId; } 830 get { return m_rootPart.LocalId; }
@@ -2620,7 +2661,7 @@ namespace OpenSim.Region.Framework.Scenes
2620 // an object has been deleted from a scene before update was processed. 2661 // an object has been deleted from a scene before update was processed.
2621 // A more fundamental overhaul of the update mechanism is required to eliminate all 2662 // A more fundamental overhaul of the update mechanism is required to eliminate all
2622 // the race conditions. 2663 // the race conditions.
2623 if (IsDeleted) 2664 if (IsDeleted || inTransit)
2624 return; 2665 return;
2625 2666
2626 // Even temporary objects take part in physics (e.g. temp-on-rez bullets) 2667 // Even temporary objects take part in physics (e.g. temp-on-rez bullets)
@@ -2736,7 +2777,7 @@ namespace OpenSim.Region.Framework.Scenes
2736 /// </summary> 2777 /// </summary>
2737 public void SendGroupRootTerseUpdate() 2778 public void SendGroupRootTerseUpdate()
2738 { 2779 {
2739 if (IsDeleted) 2780 if (IsDeleted || inTransit)
2740 return; 2781 return;
2741 2782
2742 RootPart.SendTerseUpdateToAllClients(); 2783 RootPart.SendTerseUpdateToAllClients();
@@ -2755,7 +2796,7 @@ namespace OpenSim.Region.Framework.Scenes
2755 /// </summary> 2796 /// </summary>
2756 public void SendGroupTerseUpdate() 2797 public void SendGroupTerseUpdate()
2757 { 2798 {
2758 if (IsDeleted) 2799 if (IsDeleted || inTransit)
2759 return; 2800 return;
2760 2801
2761 if (IsAttachment) 2802 if (IsAttachment)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4cc4d94..56c3b52 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1123,6 +1123,11 @@ namespace OpenSim.Region.Framework.Scenes
1123 if (part == null) 1123 if (part == null)
1124 { 1124 {
1125 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); 1125 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
1126 ParentID = 0;
1127 ParentPart = null;
1128 PrevSitOffset = Vector3.Zero;
1129 ClearControls();
1130 IsLoggingIn = false;
1126 } 1131 }
1127 else 1132 else
1128 { 1133 {
@@ -1216,13 +1221,6 @@ namespace OpenSim.Region.Framework.Scenes
1216 else 1221 else
1217 AddToPhysicalScene(isFlying); 1222 AddToPhysicalScene(isFlying);
1218 1223
1219 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1220 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1221 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1222 // the value to a negative position which does not trigger the border cross.
1223 // This may not be the best location for this.
1224 CheckForBorderCrossing();
1225
1226 if (ForceFly) 1224 if (ForceFly)
1227 { 1225 {
1228 Flying = true; 1226 Flying = true;
@@ -1231,12 +1229,18 @@ namespace OpenSim.Region.Framework.Scenes
1231 { 1229 {
1232 Flying = false; 1230 Flying = false;
1233 } 1231 }
1234 }
1235 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
1236 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
1237 // elsewhere anyway
1238 // Animator.SendAnimPack();
1239 1232
1233 // XXX: This is to trigger any secondary teleport needed for a megaregion when the user has teleported to a
1234 // location outside the 'root region' (the south-west 256x256 corner). This is the earlist we can do it
1235 // since it requires a physics actor to be present. If it is left any later, then physics appears to reset
1236 // the value to a negative position which does not trigger the border cross.
1237 // This may not be the best location for this.
1238
1239
1240 // its not
1241// CheckForBorderCrossing();
1242 }
1243
1240 m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts)); 1244 m_log.DebugFormat("[MakeRootAgent] position and physical: {0}ms", Util.EnvironmentTickCountSubtract(ts));
1241 m_scene.SwapRootAgentCount(false); 1245 m_scene.SwapRootAgentCount(false);
1242 1246
@@ -2734,7 +2738,6 @@ namespace OpenSim.Region.Framework.Scenes
2734 ParentID = 0; 2738 ParentID = 0;
2735 ParentPart = null; 2739 ParentPart = null;
2736 2740
2737
2738 if (part.SitTargetAvatar == UUID) 2741 if (part.SitTargetAvatar == UUID)
2739 standRotation = standRotation * part.SitTargetOrientation; 2742 standRotation = standRotation * part.SitTargetOrientation;
2740 else 2743 else
@@ -2761,12 +2764,6 @@ namespace OpenSim.Region.Framework.Scenes
2761 2764
2762 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose; 2765 Vector3 standPos = sitPartWorldPosition + adjustmentForSitPose;
2763 2766
2764// m_log.DebugFormat(
2765// "[SCENE PRESENCE]: Setting stand to pos {0}, (adjustmentForSitPosition {1}, adjustmentForSitPose {2}) rotation {3} for {4} in {5}",
2766// standPos, adjustmentForSitPosition, adjustmentForSitPose, standRotation, Name, Scene.Name);
2767
2768 standPos.X = Util.Clamp<float>(standPos.X, 0.5f, (float)Constants.RegionSize - 0.5f);
2769 standPos.Y = Util.Clamp<float>(standPos.Y, 0.5f, (float)Constants.RegionSize - 0.5f);
2770 m_pos = standPos; 2767 m_pos = standPos;
2771 } 2768 }
2772 2769
@@ -3308,6 +3305,8 @@ namespace OpenSim.Region.Framework.Scenes
3308 3305
3309 if (IsChildAgent == false) 3306 if (IsChildAgent == false)
3310 { 3307 {
3308 CheckForBorderCrossing();
3309
3311 if (IsInTransit) 3310 if (IsInTransit)
3312 return; 3311 return;
3313 3312
@@ -3329,8 +3328,6 @@ namespace OpenSim.Region.Framework.Scenes
3329 m_lastVelocity = Velocity; 3328 m_lastVelocity = Velocity;
3330 } 3329 }
3331 3330
3332 CheckForBorderCrossing();
3333
3334 CheckForSignificantMovement(); // sends update to the modules. 3331 CheckForSignificantMovement(); // sends update to the modules.
3335 } 3332 }
3336 } 3333 }
@@ -3847,7 +3844,7 @@ namespace OpenSim.Region.Framework.Scenes
3847 protected void CheckForBorderCrossing() 3844 protected void CheckForBorderCrossing()
3848 { 3845 {
3849 // Check that we we are not a child 3846 // Check that we we are not a child
3850 if (IsChildAgent) 3847 if (IsChildAgent || IsInTransit)
3851 return; 3848 return;
3852 3849
3853 // If we don't have a PhysActor, we can't cross anyway 3850 // If we don't have a PhysActor, we can't cross anyway
@@ -3857,25 +3854,22 @@ namespace OpenSim.Region.Framework.Scenes
3857 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) 3854 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3858 return; 3855 return;
3859 3856
3860 if (IsInTransit)
3861 return;
3862
3863 Vector3 pos2 = AbsolutePosition; 3857 Vector3 pos2 = AbsolutePosition;
3864 Vector3 vel = Velocity; 3858 Vector3 vel = Velocity;
3865 int neighbor = 0;
3866 int[] fix = new int[2];
3867 3859
3868 float timeStep = 0.1f; 3860 float timeStep = 0.1f;
3869 pos2.X = pos2.X + (vel.X * timeStep); 3861 pos2.X += vel.X * timeStep;
3870 pos2.Y = pos2.Y + (vel.Y * timeStep); 3862 pos2.Y += vel.Y * timeStep;
3871 pos2.Z = pos2.Z + (vel.Z * timeStep); 3863 pos2.Z += vel.Z * timeStep;
3872
3873 3864
3874 // m_log.DebugFormat( 3865 // m_log.DebugFormat(
3875 // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}", 3866 // "[SCENE PRESENCE]: Testing border check for projected position {0} of {1} in {2}",
3876 // pos2, Name, Scene.Name); 3867 // pos2, Name, Scene.Name);
3877 3868/*
3878 // Checks if where it's headed exists a region 3869 // Checks if where it's headed exists a region
3870 int neighbor = 0;
3871 int[] fix = new int[2];
3872
3879 bool needsTransit = false; 3873 bool needsTransit = false;
3880 if (m_scene.TestBorderCross(pos2, Cardinals.W)) 3874 if (m_scene.TestBorderCross(pos2, Cardinals.W))
3881 { 3875 {
@@ -3925,59 +3919,55 @@ namespace OpenSim.Region.Framework.Scenes
3925 } 3919 }
3926 3920
3927 // Makes sure avatar does not end up outside region 3921 // Makes sure avatar does not end up outside region
3922
3928 if (neighbor <= 0) 3923 if (neighbor <= 0)
3929 { 3924 {
3930 if (needsTransit) 3925 if (needsTransit)
3931 { 3926 {
3932 if (m_requestedSitTargetUUID == UUID.Zero) 3927 CrossToNewRegionFail();
3933 {
3934 bool isFlying = Flying;
3935 RemoveFromPhysicalScene();
3936
3937 Vector3 pos = AbsolutePosition;
3938 if (AbsolutePosition.X < 0)
3939 pos.X += Velocity.X * 2;
3940 else if (AbsolutePosition.X > Constants.RegionSize)
3941 pos.X -= Velocity.X * 2;
3942 if (AbsolutePosition.Y < 0)
3943 pos.Y += Velocity.Y * 2;
3944 else if (AbsolutePosition.Y > Constants.RegionSize)
3945 pos.Y -= Velocity.Y * 2;
3946 Velocity = Vector3.Zero;
3947 AbsolutePosition = pos;
3948
3949 // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition);
3950
3951 AddToPhysicalScene(isFlying);
3952 }
3953 } 3928 }
3954 } 3929 }
3955 else if (neighbor > 0) 3930 else if (neighbor > 0)
3956 { 3931 {
3957 if (!CrossToNewRegion()) 3932 if (!CrossToNewRegion())
3958 { 3933 {
3959 if (m_requestedSitTargetUUID == UUID.Zero) 3934 CrossToNewRegionFail();
3960 {
3961 bool isFlying = Flying;
3962 RemoveFromPhysicalScene();
3963
3964 Vector3 pos = AbsolutePosition;
3965 if (AbsolutePosition.X < 0)
3966 pos.X += Velocity.X * 2;
3967 else if (AbsolutePosition.X > Constants.RegionSize)
3968 pos.X -= Velocity.X * 2;
3969 if (AbsolutePosition.Y < 0)
3970 pos.Y += Velocity.Y * 2;
3971 else if (AbsolutePosition.Y > Constants.RegionSize)
3972 pos.Y -= Velocity.Y * 2;
3973 Velocity = Vector3.Zero;
3974 AbsolutePosition = pos;
3975
3976 AddToPhysicalScene(isFlying);
3977 }
3978 } 3935 }
3979 } 3936 }
3937 */
3938 bool needsTransit = false;
3939
3940 if (pos2.X < 0)
3941 needsTransit = true;
3942 else if (pos2.X > m_scene.RegionInfo.RegionSizeX)
3943 needsTransit = true;
3944 else if (pos2.Y < 0)
3945 needsTransit = true;
3946 else if (pos2.Y > m_scene.RegionInfo.RegionSizeY)
3947 needsTransit = true;
3948
3949 if (needsTransit)
3950 {
3951 if (!CrossToNewRegion() && m_requestedSitTargetUUID == UUID.Zero)
3952 {
3953 // we don't have entity transfer module
3954 Vector3 pos = AbsolutePosition;
3955 float px = pos.X;
3956 if (px < 0)
3957 pos.X += Velocity.X * 2;
3958 else if (px > m_scene.RegionInfo.RegionSizeX)
3959 pos.X -= Velocity.X * 2;
3980 3960
3961 float py = pos.Y;
3962 if (py < 0)
3963 pos.Y += Velocity.Y * 2;
3964 else if (py > m_scene.RegionInfo.RegionSizeY)
3965 pos.Y -= Velocity.Y * 2;
3966
3967 Velocity = Vector3.Zero;
3968 AbsolutePosition = pos;
3969 }
3970 }
3981 } 3971 }
3982 3972
3983 public void CrossToNewRegionFail() 3973 public void CrossToNewRegionFail()
@@ -3988,14 +3978,18 @@ namespace OpenSim.Region.Framework.Scenes
3988 RemoveFromPhysicalScene(); 3978 RemoveFromPhysicalScene();
3989 3979
3990 Vector3 pos = AbsolutePosition; 3980 Vector3 pos = AbsolutePosition;
3991 if (AbsolutePosition.X < 0) 3981 float px = pos.X;
3982 if (px < 0)
3992 pos.X += Velocity.X * 2; 3983 pos.X += Velocity.X * 2;
3993 else if (AbsolutePosition.X > Constants.RegionSize) 3984 else if (px > m_scene.RegionInfo.RegionSizeX)
3994 pos.X -= Velocity.X * 2; 3985 pos.X -= Velocity.X * 2;
3995 if (AbsolutePosition.Y < 0) 3986
3987 float py = pos.Y;
3988 if (py < 0)
3996 pos.Y += Velocity.Y * 2; 3989 pos.Y += Velocity.Y * 2;
3997 else if (AbsolutePosition.Y > Constants.RegionSize) 3990 else if (py > m_scene.RegionInfo.RegionSizeY)
3998 pos.Y -= Velocity.Y * 2; 3991 pos.Y -= Velocity.Y * 2;
3992
3999 Velocity = Vector3.Zero; 3993 Velocity = Vector3.Zero;
4000 AbsolutePosition = pos; 3994 AbsolutePosition = pos;
4001 3995