diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 268 |
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 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. |