aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs268
2 files changed, 134 insertions, 136 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 3b1c5d8..69491b7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -568,7 +568,7 @@ namespace OpenSim.Region.Framework.Scenes
568 } 568 }
569 else 569 else
570 { 570 {
571 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar alreasy in transit {0} to {1}", av.Name, val); 571 m_log.DebugFormat("[SCENE OBJECT]: Not crossing avatar {0} to {1} because it's already in transit", av.Name, val);
572 } 572 }
573 } 573 }
574 574
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 17f6301..493090c 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1691,109 +1691,122 @@ namespace OpenSim.Region.Framework.Scenes
1691 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", 1691 "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}",
1692 client.Name, Scene.Name, AbsolutePosition); 1692 client.Name, Scene.Name, AbsolutePosition);
1693 1693
1694 // Make sure it's not a login agent. We don't want to wait for updates during login 1694 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); // Get this ahead of time because IsInTransit modifies 'm_AgentControlFlags'
1695 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0) 1695
1696 IsInTransit = true;
1697 try
1696 { 1698 {
1697 // Let's wait until UpdateAgent (called by departing region) is done 1699 // Make sure it's not a login agent. We don't want to wait for updates during login
1698 if (!WaitForUpdateAgent(client)) 1700 if (PresenceType != PresenceType.Npc && (m_teleportFlags & TeleportFlags.ViaLogin) == 0)
1699 // The sending region never sent the UpdateAgent data, we have to refuse 1701 {
1700 return; 1702 // Let's wait until UpdateAgent (called by departing region) is done
1701 } 1703 if (!WaitForUpdateAgent(client))
1704 // The sending region never sent the UpdateAgent data, we have to refuse
1705 return;
1706 }
1702 1707
1703 Vector3 look = Velocity; 1708 Vector3 look = Velocity;
1704 1709
1705 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) 1710 // if ((look.X == 0) && (look.Y == 0) && (look.Z == 0))
1706 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1)) 1711 if ((Math.Abs(look.X) < 0.1) && (Math.Abs(look.Y) < 0.1) && (Math.Abs(look.Z) < 0.1))
1707 { 1712 {
1708 look = new Vector3(0.99f, 0.042f, 0); 1713 look = new Vector3(0.99f, 0.042f, 0);
1709 } 1714 }
1710 1715
1711 // Prevent teleporting to an underground location 1716 // Prevent teleporting to an underground location
1712 // (may crash client otherwise) 1717 // (may crash client otherwise)
1713 // 1718 //
1714 Vector3 pos = AbsolutePosition; 1719 Vector3 pos = AbsolutePosition;
1715 float ground = m_scene.GetGroundHeight(pos.X, pos.Y); 1720 float ground = m_scene.GetGroundHeight(pos.X, pos.Y);
1716 if (pos.Z < ground + 1.5f) 1721 if (pos.Z < ground + 1.5f)
1717 { 1722 {
1718 pos.Z = ground + 1.5f; 1723 pos.Z = ground + 1.5f;
1719 AbsolutePosition = pos; 1724 AbsolutePosition = pos;
1720 } 1725 }
1721 1726
1722 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1727 if (!MakeRootAgent(AbsolutePosition, flying))
1723 if (!MakeRootAgent(AbsolutePosition, flying)) 1728 {
1724 { 1729 m_log.DebugFormat(
1725 m_log.DebugFormat( 1730 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root",
1726 "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", 1731 Name, Scene.Name);
1727 Name, Scene.Name);
1728 1732
1729 return; 1733 return;
1730 } 1734 }
1731 1735
1732 // Tell the client that we're totally ready 1736 // Tell the client that we're totally ready
1733 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); 1737 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1734 1738
1735 // Remember in HandleUseCircuitCode, we delayed this to here 1739 // Remember in HandleUseCircuitCode, we delayed this to here
1736 if (m_teleportFlags > 0) 1740 if (m_teleportFlags > 0)
1737 SendInitialDataToMe(); 1741 SendInitialDataToMe();
1738 1742
1739// m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); 1743 // m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1740 1744
1741 if (!string.IsNullOrEmpty(m_callbackURI)) 1745 if (!string.IsNullOrEmpty(m_callbackURI))
1742 { 1746 {
1743 // We cannot sleep here since this would hold up the inbound packet processing thread, as 1747 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1744 // CompleteMovement() is executed synchronously. However, it might be better to delay the release 1748 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1745 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete 1749 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1746 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this 1750 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1747 // region as the current region, meaning that a close sent before then will fail the teleport. 1751 // region as the current region, meaning that a close sent before then will fail the teleport.
1748// System.Threading.Thread.Sleep(2000); 1752 // System.Threading.Thread.Sleep(2000);
1749 1753
1750 m_log.DebugFormat( 1754 m_log.DebugFormat(
1751 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", 1755 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1752 client.Name, client.AgentId, m_callbackURI); 1756 client.Name, client.AgentId, m_callbackURI);
1753 1757
1754 UUID originID; 1758 UUID originID;
1755 1759
1756 lock (m_originRegionIDAccessLock) 1760 lock (m_originRegionIDAccessLock)
1757 originID = m_originRegionID; 1761 originID = m_originRegionID;
1758 1762
1759 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI); 1763 Scene.SimulationService.ReleaseAgent(originID, UUID, m_callbackURI);
1760 m_callbackURI = null; 1764 m_callbackURI = null;
1761 } 1765 }
1762// else 1766 // else
1763// { 1767 // {
1764// m_log.DebugFormat( 1768 // m_log.DebugFormat(
1765// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", 1769 // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1766// client.Name, client.AgentId, m_scene.RegionInfo.RegionName); 1770 // client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1767// } 1771 // }
1768 1772
1769 ValidateAndSendAppearanceAndAgentData(); 1773 ValidateAndSendAppearanceAndAgentData();
1770 1774
1771 // Create child agents in neighbouring regions 1775 // Create child agents in neighbouring regions
1772 if (openChildAgents && !IsChildAgent) 1776 if (openChildAgents && !IsChildAgent)
1773 { 1777 {
1774 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); 1778 IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
1775 if (m_agentTransfer != null) 1779 if (m_agentTransfer != null)
1776 m_agentTransfer.EnableChildAgents(this); 1780 {
1781 // Note: this call can take a while, because it notifies each of the simulator's neighbours.
1782 // It's important that we don't allow the avatar to cross regions meanwhile, as that will
1783 // cause serious errors. We've prevented that from happening by setting IsInTransit=true.
1784 m_agentTransfer.EnableChildAgents(this);
1785 }
1777 1786
1778 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>(); 1787 IFriendsModule friendsModule = m_scene.RequestModuleInterface<IFriendsModule>();
1779 if (friendsModule != null) 1788 if (friendsModule != null)
1780 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1789 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1781 1790
1782 } 1791 }
1783 1792
1784 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region 1793 // XXX: If we force an update here, then multiple attachments do appear correctly on a destination region
1785 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work. 1794 // If we do it a little bit earlier (e.g. when converting the child to a root agent) then this does not work.
1786 // This may be due to viewer code or it may be something we're not doing properly simulator side. 1795 // This may be due to viewer code or it may be something we're not doing properly simulator side.
1787 lock (m_attachments) 1796 lock (m_attachments)
1797 {
1798 foreach (SceneObjectGroup sog in m_attachments)
1799 sog.ScheduleGroupForFullUpdate();
1800 }
1801
1802 // m_log.DebugFormat(
1803 // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1804 // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
1805 }
1806 finally
1788 { 1807 {
1789 foreach (SceneObjectGroup sog in m_attachments) 1808 IsInTransit = false;
1790 sog.ScheduleGroupForFullUpdate();
1791 } 1809 }
1792
1793// m_log.DebugFormat(
1794// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1795// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
1796
1797 } 1810 }
1798 1811
1799 /// <summary> 1812 /// <summary>
@@ -3587,65 +3600,50 @@ namespace OpenSim.Region.Framework.Scenes
3587 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero) 3600 if (ParentID != 0 || PhysicsActor == null || ParentUUID != UUID.Zero)
3588 return; 3601 return;
3589 3602
3590 if (!IsInTransit) 3603 if (IsInTransit)
3591 { 3604 return;
3592 Vector3 pos2 = AbsolutePosition;
3593 Vector3 origPosition = pos2;
3594 Vector3 vel = Velocity;
3595 3605
3596 // Compute the avatar position in the next physics tick. 3606 Vector3 pos2 = AbsolutePosition;
3597 // If the avatar will be crossing, we force the crossing to happen now 3607 Vector3 origPosition = pos2;
3598 // in the hope that this will make the avatar movement smoother when crossing. 3608 Vector3 vel = Velocity;
3599 float timeStep = 0.1f;
3600 pos2.X = pos2.X + (vel.X * timeStep);
3601 pos2.Y = pos2.Y + (vel.Y * timeStep);
3602 pos2.Z = pos2.Z + (vel.Z * timeStep);
3603 3609
3604 if (!IsInTransit) 3610 // Compute the avatar position in the next physics tick.
3605 { 3611 // If the avatar will be crossing, we force the crossing to happen now
3606 if (!m_scene.PositionIsInCurrentRegion(pos2)) 3612 // in the hope that this will make the avatar movement smoother when crossing.
3607 { 3613 float timeStep = 0.1f;
3608 m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}", 3614 pos2.X = pos2.X + (vel.X * timeStep);
3609 LogHeader, Name, Scene.Name, pos2); 3615 pos2.Y = pos2.Y + (vel.Y * timeStep);
3610 3616 pos2.Z = pos2.Z + (vel.Z * timeStep);
3611 // Disconnect from the current region
3612 bool isFlying = Flying;
3613 RemoveFromPhysicalScene();
3614 // pos2 is the forcasted position so make that the 'current' position so the crossing
3615 // code will move us into the newly addressed region.
3616 m_pos = pos2;
3617 if (CrossToNewRegion())
3618 {
3619 AddToPhysicalScene(isFlying);
3620 }
3621 else
3622 {
3623 // Tried to make crossing happen but it failed.
3624 if (m_requestedSitTargetUUID == UUID.Zero)
3625 {
3626 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
3627 3617
3628 Velocity = Vector3.Zero; 3618 if (m_scene.PositionIsInCurrentRegion(pos2))
3629 AbsolutePosition = EnforceSanityOnPosition(origPosition); 3619 return;
3630 3620
3631 AddToPhysicalScene(isFlying); 3621 m_log.DebugFormat("{0} CheckForBorderCrossing: position outside region. {1} in {2} at pos {3}",
3632 } 3622 LogHeader, Name, Scene.Name, pos2);
3633 } 3623
3634 } 3624 // Disconnect from the current region
3635 } 3625 bool isFlying = Flying;
3636 else 3626 RemoveFromPhysicalScene();
3627 // pos2 is the forcasted position so make that the 'current' position so the crossing
3628 // code will move us into the newly addressed region.
3629 m_pos = pos2;
3630 if (CrossToNewRegion())
3631 {
3632 AddToPhysicalScene(isFlying);
3633 }
3634 else
3635 {
3636 // Tried to make crossing happen but it failed.
3637 if (m_requestedSitTargetUUID == UUID.Zero)
3637 { 3638 {
3638 // This constant has been inferred from experimentation 3639 m_log.DebugFormat("{0} CheckForBorderCrossing: Crossing failed. Restoring old position.", LogHeader);
3639 // I'm not sure what this value should be, so I tried a few values. 3640
3640 timeStep = 0.04f; 3641 Velocity = Vector3.Zero;
3641 pos2 = AbsolutePosition; 3642 AbsolutePosition = EnforceSanityOnPosition(origPosition);
3642 pos2.X = pos2.X + (vel.X * timeStep); 3643
3643 pos2.Y = pos2.Y + (vel.Y * timeStep); 3644 AddToPhysicalScene(isFlying);
3644 // Don't touch the Z
3645 m_pos = pos2;
3646 m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos);
3647 } 3645 }
3648 } 3646 }
3649 } 3647 }
3650 3648
3651 // Given a position, make sure it is within the current region. 3649 // Given a position, make sure it is within the current region.