diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 325 |
1 files changed, 170 insertions, 155 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b8ae553..42cd4be 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
118 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is | 118 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is |
119 | /// necessary. | 119 | /// necessary. |
120 | /// </remarks> | 120 | /// </remarks> |
121 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 121 | private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
122 | 122 | ||
123 | public Object AttachmentsSyncLock { get; private set; } | 123 | public Object AttachmentsSyncLock { get; private set; } |
124 | 124 | ||
@@ -550,8 +550,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
550 | } | 550 | } |
551 | } | 551 | } |
552 | 552 | ||
553 | m_pos = value; | 553 | // Don't update while sitting |
554 | ParentPosition = Vector3.Zero; | 554 | if (ParentID == 0) |
555 | { | ||
556 | m_pos = value; | ||
557 | ParentPosition = Vector3.Zero; | ||
558 | } | ||
555 | 559 | ||
556 | //m_log.DebugFormat( | 560 | //m_log.DebugFormat( |
557 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", | 561 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", |
@@ -566,6 +570,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
566 | public Vector3 OffsetPosition | 570 | public Vector3 OffsetPosition |
567 | { | 571 | { |
568 | get { return m_pos; } | 572 | get { return m_pos; } |
573 | // Don't remove setter. It's not currently used in core but | ||
574 | // upcoming Avination code needs it. | ||
575 | set | ||
576 | { | ||
577 | // There is no offset position when not seated | ||
578 | if (ParentID == 0) | ||
579 | return; | ||
580 | m_pos = value; | ||
581 | } | ||
569 | } | 582 | } |
570 | 583 | ||
571 | /// <summary> | 584 | /// <summary> |
@@ -1161,10 +1174,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1161 | public void CompleteMovement(IClientAPI client, bool openChildAgents) | 1174 | public void CompleteMovement(IClientAPI client, bool openChildAgents) |
1162 | { | 1175 | { |
1163 | // DateTime startTime = DateTime.Now; | 1176 | // DateTime startTime = DateTime.Now; |
1164 | 1177 | ||
1165 | // m_log.DebugFormat( | 1178 | m_log.DebugFormat( |
1166 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1}", | 1179 | "[SCENE PRESENCE]: Completing movement of {0} into region {1} in position {2}", |
1167 | // client.Name, Scene.RegionInfo.RegionName); | 1180 | client.Name, Scene.RegionInfo.RegionName, AbsolutePosition); |
1168 | 1181 | ||
1169 | Vector3 look = Velocity; | 1182 | Vector3 look = Velocity; |
1170 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) | 1183 | if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) |
@@ -2383,9 +2396,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2383 | m_lastVelocity = Velocity; | 2396 | m_lastVelocity = Velocity; |
2384 | } | 2397 | } |
2385 | 2398 | ||
2386 | // followed suggestion from mic bowman. reversed the two lines below. | 2399 | CheckForBorderCrossing(); |
2387 | if (ParentID == 0 && PhysicsActor != null || ParentID != 0) // Check that we have a physics actor or we're sitting on something | ||
2388 | CheckForBorderCrossing(); | ||
2389 | 2400 | ||
2390 | CheckForSignificantMovement(); // sends update to the modules. | 2401 | CheckForSignificantMovement(); // sends update to the modules. |
2391 | } | 2402 | } |
@@ -2738,143 +2749,146 @@ namespace OpenSim.Region.Framework.Scenes | |||
2738 | /// </remarks> | 2749 | /// </remarks> |
2739 | protected void CheckForBorderCrossing() | 2750 | protected void CheckForBorderCrossing() |
2740 | { | 2751 | { |
2741 | if (IsChildAgent) | 2752 | // Check that we we are not a child |
2753 | if (IsChildAgent) | ||
2742 | return; | 2754 | return; |
2743 | 2755 | ||
2744 | Vector3 pos2 = AbsolutePosition; | 2756 | // If we don't have a PhysActor, we can't cross anyway |
2745 | Vector3 vel = Velocity; | 2757 | // Also don't do this while sat, sitting avatars cross with the |
2746 | int neighbor = 0; | 2758 | // object they sit on. |
2747 | int[] fix = new int[2]; | 2759 | if (ParentID != 0 || PhysicsActor == null) |
2748 | 2760 | return; | |
2749 | float timeStep = 0.1f; | ||
2750 | pos2.X = pos2.X + (vel.X*timeStep); | ||
2751 | pos2.Y = pos2.Y + (vel.Y*timeStep); | ||
2752 | pos2.Z = pos2.Z + (vel.Z*timeStep); | ||
2753 | 2761 | ||
2754 | if (!IsInTransit) | 2762 | if (!IsInTransit) |
2755 | { | 2763 | { |
2756 | // Checks if where it's headed exists a region | 2764 | Vector3 pos2 = AbsolutePosition; |
2765 | Vector3 vel = Velocity; | ||
2766 | int neighbor = 0; | ||
2767 | int[] fix = new int[2]; | ||
2757 | 2768 | ||
2758 | bool needsTransit = false; | 2769 | float timeStep = 0.1f; |
2759 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) | 2770 | pos2.X = pos2.X + (vel.X * timeStep); |
2771 | pos2.Y = pos2.Y + (vel.Y * timeStep); | ||
2772 | pos2.Z = pos2.Z + (vel.Z * timeStep); | ||
2773 | |||
2774 | if (!IsInTransit) | ||
2760 | { | 2775 | { |
2761 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | 2776 | // Checks if where it's headed exists a region |
2762 | { | 2777 | bool needsTransit = false; |
2763 | needsTransit = true; | 2778 | if (m_scene.TestBorderCross(pos2, Cardinals.W)) |
2764 | neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix); | ||
2765 | } | ||
2766 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
2767 | { | 2779 | { |
2768 | needsTransit = true; | 2780 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
2769 | neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix); | 2781 | { |
2782 | needsTransit = true; | ||
2783 | neighbor = m_scene.HaveNeighbor(Cardinals.SW, ref fix); | ||
2784 | } | ||
2785 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
2786 | { | ||
2787 | needsTransit = true; | ||
2788 | neighbor = m_scene.HaveNeighbor(Cardinals.NW, ref fix); | ||
2789 | } | ||
2790 | else | ||
2791 | { | ||
2792 | needsTransit = true; | ||
2793 | neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix); | ||
2794 | } | ||
2770 | } | 2795 | } |
2771 | else | 2796 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) |
2772 | { | 2797 | { |
2773 | needsTransit = true; | 2798 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
2774 | neighbor = m_scene.HaveNeighbor(Cardinals.W, ref fix); | 2799 | { |
2800 | needsTransit = true; | ||
2801 | neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix); | ||
2802 | } | ||
2803 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
2804 | { | ||
2805 | needsTransit = true; | ||
2806 | neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix); | ||
2807 | } | ||
2808 | else | ||
2809 | { | ||
2810 | needsTransit = true; | ||
2811 | neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix); | ||
2812 | } | ||
2775 | } | 2813 | } |
2776 | } | 2814 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) |
2777 | else if (m_scene.TestBorderCross(pos2, Cardinals.E)) | ||
2778 | { | ||
2779 | if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
2780 | { | 2815 | { |
2781 | needsTransit = true; | 2816 | needsTransit = true; |
2782 | neighbor = m_scene.HaveNeighbor(Cardinals.SE, ref fix); | 2817 | neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix); |
2783 | } | 2818 | } |
2784 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | 2819 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) |
2785 | { | 2820 | { |
2786 | needsTransit = true; | 2821 | needsTransit = true; |
2787 | neighbor = m_scene.HaveNeighbor(Cardinals.NE, ref fix); | 2822 | neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix); |
2788 | } | 2823 | } |
2789 | else | ||
2790 | { | ||
2791 | needsTransit = true; | ||
2792 | neighbor = m_scene.HaveNeighbor(Cardinals.E, ref fix); | ||
2793 | } | ||
2794 | } | ||
2795 | else if (m_scene.TestBorderCross(pos2, Cardinals.S)) | ||
2796 | { | ||
2797 | needsTransit = true; | ||
2798 | neighbor = m_scene.HaveNeighbor(Cardinals.S, ref fix); | ||
2799 | } | ||
2800 | else if (m_scene.TestBorderCross(pos2, Cardinals.N)) | ||
2801 | { | ||
2802 | needsTransit = true; | ||
2803 | neighbor = m_scene.HaveNeighbor(Cardinals.N, ref fix); | ||
2804 | } | ||
2805 | 2824 | ||
2806 | // Makes sure avatar does not end up outside region | 2825 | // Makes sure avatar does not end up outside region |
2807 | if (neighbor <= 0) | 2826 | if (neighbor <= 0) |
2808 | { | ||
2809 | if (needsTransit) | ||
2810 | { | 2827 | { |
2811 | if (m_requestedSitTargetUUID == UUID.Zero) | 2828 | if (needsTransit) |
2812 | { | 2829 | { |
2813 | bool isFlying = Flying; | 2830 | if (m_requestedSitTargetUUID == UUID.Zero) |
2814 | RemoveFromPhysicalScene(); | 2831 | { |
2815 | 2832 | bool isFlying = Flying; | |
2816 | Vector3 pos = AbsolutePosition; | 2833 | RemoveFromPhysicalScene(); |
2817 | if (AbsolutePosition.X < 0) | 2834 | |
2818 | pos.X += Velocity.X * 2; | 2835 | Vector3 pos = AbsolutePosition; |
2819 | else if (AbsolutePosition.X > Constants.RegionSize) | 2836 | if (AbsolutePosition.X < 0) |
2820 | pos.X -= Velocity.X * 2; | 2837 | pos.X += Velocity.X * 2; |
2821 | if (AbsolutePosition.Y < 0) | 2838 | else if (AbsolutePosition.X > Constants.RegionSize) |
2822 | pos.Y += Velocity.Y * 2; | 2839 | pos.X -= Velocity.X * 2; |
2823 | else if (AbsolutePosition.Y > Constants.RegionSize) | 2840 | if (AbsolutePosition.Y < 0) |
2824 | pos.Y -= Velocity.Y * 2; | 2841 | pos.Y += Velocity.Y * 2; |
2825 | Velocity = Vector3.Zero; | 2842 | else if (AbsolutePosition.Y > Constants.RegionSize) |
2826 | AbsolutePosition = pos; | 2843 | pos.Y -= Velocity.Y * 2; |
2827 | 2844 | Velocity = Vector3.Zero; | |
2828 | // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition); | 2845 | AbsolutePosition = pos; |
2829 | 2846 | ||
2830 | AddToPhysicalScene(isFlying); | 2847 | // m_log.DebugFormat("[SCENE PRESENCE]: Prevented flyoff for {0} at {1}", Name, AbsolutePosition); |
2848 | |||
2849 | AddToPhysicalScene(isFlying); | ||
2850 | } | ||
2831 | } | 2851 | } |
2832 | } | 2852 | } |
2833 | } | 2853 | else if (neighbor > 0) |
2834 | else if (neighbor > 0) | ||
2835 | { | ||
2836 | if (!CrossToNewRegion()) | ||
2837 | { | 2854 | { |
2838 | if (m_requestedSitTargetUUID == UUID.Zero) | 2855 | if (!CrossToNewRegion()) |
2839 | { | 2856 | { |
2840 | bool isFlying = Flying; | 2857 | if (m_requestedSitTargetUUID == UUID.Zero) |
2841 | RemoveFromPhysicalScene(); | 2858 | { |
2842 | 2859 | bool isFlying = Flying; | |
2843 | Vector3 pos = AbsolutePosition; | 2860 | RemoveFromPhysicalScene(); |
2844 | if (AbsolutePosition.X < 0) | 2861 | |
2845 | pos.X += Velocity.X * 2; | 2862 | Vector3 pos = AbsolutePosition; |
2846 | else if (AbsolutePosition.X > Constants.RegionSize) | 2863 | if (AbsolutePosition.X < 0) |
2847 | pos.X -= Velocity.X * 2; | 2864 | pos.X += Velocity.X * 2; |
2848 | if (AbsolutePosition.Y < 0) | 2865 | else if (AbsolutePosition.X > Constants.RegionSize) |
2849 | pos.Y += Velocity.Y * 2; | 2866 | pos.X -= Velocity.X * 2; |
2850 | else if (AbsolutePosition.Y > Constants.RegionSize) | 2867 | if (AbsolutePosition.Y < 0) |
2851 | pos.Y -= Velocity.Y * 2; | 2868 | pos.Y += Velocity.Y * 2; |
2852 | Velocity = Vector3.Zero; | 2869 | else if (AbsolutePosition.Y > Constants.RegionSize) |
2853 | AbsolutePosition = pos; | 2870 | pos.Y -= Velocity.Y * 2; |
2854 | 2871 | Velocity = Vector3.Zero; | |
2855 | AddToPhysicalScene(isFlying); | 2872 | AbsolutePosition = pos; |
2873 | |||
2874 | AddToPhysicalScene(isFlying); | ||
2875 | } | ||
2856 | } | 2876 | } |
2857 | } | 2877 | } |
2858 | } | 2878 | } |
2859 | } | 2879 | else |
2860 | else | 2880 | { |
2861 | { | 2881 | // This constant has been inferred from experimentation |
2862 | // We must remove the agent from the physical scene if it has been placed in transit. If we don't, | 2882 | // I'm not sure what this value should be, so I tried a few values. |
2863 | // then this method continues to be called from ScenePresence.Update() until the handover of the client between | 2883 | timeStep = 0.04f; |
2864 | // regions is completed. Since this handover can take more than 1000ms (due to the 1000ms | 2884 | pos2 = AbsolutePosition; |
2865 | // event queue polling response from the server), this results in the avatar pausing on the border | 2885 | pos2.X = pos2.X + (vel.X * timeStep); |
2866 | // for the handover period. | 2886 | pos2.Y = pos2.Y + (vel.Y * timeStep); |
2867 | RemoveFromPhysicalScene(); | 2887 | // Don't touch the Z |
2868 | 2888 | m_pos = pos2; | |
2869 | // This constant has been inferred from experimentation | 2889 | m_log.DebugFormat("[SCENE PRESENCE]: In transit m_pos={0}", m_pos); |
2870 | // I'm not sure what this value should be, so I tried a few values. | 2890 | } |
2871 | timeStep = 0.04f; | 2891 | } |
2872 | pos2 = AbsolutePosition; | ||
2873 | pos2.X = pos2.X + (vel.X * timeStep); | ||
2874 | pos2.Y = pos2.Y + (vel.Y * timeStep); | ||
2875 | pos2.Z = pos2.Z + (vel.Z * timeStep); | ||
2876 | m_pos = pos2; | ||
2877 | } | ||
2878 | } | 2892 | } |
2879 | 2893 | ||
2880 | /// <summary> | 2894 | /// <summary> |
@@ -3104,30 +3118,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3104 | catch { } | 3118 | catch { } |
3105 | 3119 | ||
3106 | // Attachment objects | 3120 | // Attachment objects |
3107 | lock (m_attachments) | 3121 | List<SceneObjectGroup> attachments = GetAttachments(); |
3122 | if (attachments.Count > 0) | ||
3108 | { | 3123 | { |
3109 | if (m_attachments.Count > 0) | 3124 | cAgent.AttachmentObjects = new List<ISceneObject>(); |
3110 | { | 3125 | cAgent.AttachmentObjectStates = new List<string>(); |
3111 | cAgent.AttachmentObjects = new List<ISceneObject>(); | 3126 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); |
3112 | cAgent.AttachmentObjectStates = new List<string>(); | 3127 | InTransitScriptStates.Clear(); |
3113 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3114 | InTransitScriptStates.Clear(); | ||
3115 | 3128 | ||
3116 | foreach (SceneObjectGroup sog in m_attachments) | 3129 | foreach (SceneObjectGroup sog in attachments) |
3117 | { | 3130 | { |
3118 | // We need to make a copy and pass that copy | 3131 | // We need to make a copy and pass that copy |
3119 | // because of transfers withn the same sim | 3132 | // because of transfers withn the same sim |
3120 | ISceneObject clone = sog.CloneForNewScene(); | 3133 | ISceneObject clone = sog.CloneForNewScene(); |
3121 | // Attachment module assumes that GroupPosition holds the offsets...! | 3134 | // Attachment module assumes that GroupPosition holds the offsets...! |
3122 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | 3135 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; |
3123 | ((SceneObjectGroup)clone).IsAttachment = false; | 3136 | ((SceneObjectGroup)clone).IsAttachment = false; |
3124 | cAgent.AttachmentObjects.Add(clone); | 3137 | cAgent.AttachmentObjects.Add(clone); |
3125 | string state = sog.GetStateSnapshot(); | 3138 | string state = sog.GetStateSnapshot(); |
3126 | cAgent.AttachmentObjectStates.Add(state); | 3139 | cAgent.AttachmentObjectStates.Add(state); |
3127 | InTransitScriptStates.Add(state); | 3140 | InTransitScriptStates.Add(state); |
3128 | // Let's remove the scripts of the original object here | 3141 | // Let's remove the scripts of the original object here |
3129 | sog.RemoveScriptInstances(true); | 3142 | sog.RemoveScriptInstances(true); |
3130 | } | ||
3131 | } | 3143 | } |
3132 | } | 3144 | } |
3133 | } | 3145 | } |
@@ -3535,26 +3547,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
3535 | /// <param name="args">The arguments for the event</param> | 3547 | /// <param name="args">The arguments for the event</param> |
3536 | public void SendScriptEventToAttachments(string eventName, Object[] args) | 3548 | public void SendScriptEventToAttachments(string eventName, Object[] args) |
3537 | { | 3549 | { |
3538 | if (m_scriptEngines.Length == 0) | 3550 | Util.FireAndForget(delegate(object x) |
3539 | return; | ||
3540 | |||
3541 | lock (m_attachments) | ||
3542 | { | 3551 | { |
3543 | foreach (SceneObjectGroup grp in m_attachments) | 3552 | if (m_scriptEngines.Length == 0) |
3553 | return; | ||
3554 | |||
3555 | lock (m_attachments) | ||
3544 | { | 3556 | { |
3545 | // 16384 is CHANGED_ANIMATION | 3557 | foreach (SceneObjectGroup grp in m_attachments) |
3546 | // | ||
3547 | // Send this to all attachment root prims | ||
3548 | // | ||
3549 | foreach (IScriptModule m in m_scriptEngines) | ||
3550 | { | 3558 | { |
3551 | if (m == null) // No script engine loaded | 3559 | // 16384 is CHANGED_ANIMATION |
3552 | continue; | 3560 | // |
3561 | // Send this to all attachment root prims | ||
3562 | // | ||
3563 | foreach (IScriptModule m in m_scriptEngines) | ||
3564 | { | ||
3565 | if (m == null) // No script engine loaded | ||
3566 | continue; | ||
3553 | 3567 | ||
3554 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); | 3568 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); |
3569 | } | ||
3555 | } | 3570 | } |
3556 | } | 3571 | } |
3557 | } | 3572 | }); |
3558 | } | 3573 | } |
3559 | 3574 | ||
3560 | internal void PushForce(Vector3 impulse) | 3575 | internal void PushForce(Vector3 impulse) |