aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rwxr-xr-xOpenSim/Region/Framework/Scenes/Scene.cs64
1 files changed, 46 insertions, 18 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 60079e2..9ae0c10 100755
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -5783,27 +5783,34 @@ Environment.Exit(1);
5783 5783
5784 public Vector3 GetNearestAllowedPosition(ScenePresence avatar, ILandObject excludeParcel) 5784 public Vector3 GetNearestAllowedPosition(ScenePresence avatar, ILandObject excludeParcel)
5785 { 5785 {
5786 ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, excludeParcel); 5786 Vector3 pos = avatar.AbsolutePosition;
5787
5788 ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, pos.X, pos.Y, excludeParcel);
5789
5790 Vector3 retPos = Vector3.Zero;
5787 5791
5788 if (nearestParcel != null) 5792 if (nearestParcel != null)
5789 { 5793 {
5790 Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1)); 5794 Vector2? nearestPoint = null;
5791 //Try to get a location that feels like where they came from 5795 Vector3 dir = -avatar.Velocity;
5792 Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); 5796 float dirlen = dir.Length();
5793 if (nearestPoint != null) 5797 if(dirlen > 1.0f)
5794 { 5798 //Try to get a location that feels like where they came from
5795 m_log.Debug("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString()); 5799 nearestPoint = nearestParcel.GetNearestPointAlongDirection(pos, dir);
5796 return nearestPoint.Value; 5800
5797 } 5801 if (nearestPoint == null)
5802 nearestPoint = nearestParcel.GetNearestPoint(pos);
5798 5803
5799 //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel
5800 Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition);
5801 dir = Vector3.Normalize(directionToParcelCenter);
5802 nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel);
5803 if (nearestPoint != null) 5804 if (nearestPoint != null)
5804 { 5805 {
5805 m_log.Debug("They had a zero velocity, sending them to: " + nearestPoint.ToString()); 5806 retPos.X = nearestPoint.Value.X;
5806 return nearestPoint.Value; 5807 retPos.Y = nearestPoint.Value.Y;
5808 float h = GetGroundHeight(retPos.X, retPos.Y) + 0.8f;
5809 if(pos.Z > h)
5810 retPos.Z = pos.Z;
5811 else
5812 retPos.Z = h;
5813 return retPos;
5807 } 5814 }
5808 5815
5809 ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y); 5816 ILandObject dest = LandChannel.GetLandObject(avatar.lastKnownAllowedPosition.X, avatar.lastKnownAllowedPosition.Y);
@@ -5833,15 +5840,36 @@ Environment.Exit(1);
5833 5840
5834 private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel) 5841 private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel)
5835 { 5842 {
5836 Vector3 unitDirection = Vector3.Normalize(direction); 5843 float maxX = RegionInfo.RegionSizeX;
5844 float maxY = RegionInfo.RegionSizeY;
5845
5846 // reduce resolution since regions can be very large now
5847 direction *= 4.0f;
5848 Vector3 testPos = pos;
5837 //Making distance to search go through some sane limit of distance 5849 //Making distance to search go through some sane limit of distance
5838 for (float distance = 0; distance < Math.Max(RegionInfo.RegionSizeX, RegionInfo.RegionSizeY) * 2; distance += .5f) 5850 while(true)
5839 { 5851 {
5840 Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); 5852 testPos += direction;
5841 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y)) 5853 if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y))
5842 { 5854 {
5855 direction *= -0.125f; // .5m resolution
5856 Vector3 testPos2 = testPos - direction;
5857 for(int i = 0; i < 7; i++)
5858 {
5859 if (!parcel.ContainsPoint((int)testPos2.X, (int)testPos2.Y))
5860 return testPos;
5861 testPos = testPos2;
5862 }
5843 return testPos; 5863 return testPos;
5844 } 5864 }
5865 if(testPos.X < 0)
5866 break;
5867 else if (testPos.X >= maxX)
5868 break;
5869 if(testPos.Y < 0)
5870 break;
5871 else if (testPos.Y >= maxY)
5872 break;
5845 } 5873 }
5846 return null; 5874 return null;
5847 } 5875 }