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