aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Border.cs150
-rw-r--r--OpenSim/Region/Framework/Scenes/Cardinals.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs354
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs101
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs23
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs312
8 files changed, 914 insertions, 44 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Border.cs b/OpenSim/Region/Framework/Scenes/Border.cs
new file mode 100644
index 0000000..8f02a9c
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Border.cs
@@ -0,0 +1,150 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenMetaverse;
32
33namespace OpenSim.Region.Framework.Scenes
34{
35 public class Border
36 {
37
38 /// <summary>
39 /// Line perpendicular to the Direction Cardinal. Z value is the
40 /// </summary>
41 public Vector3 BorderLine = Vector3.Zero;
42
43 /// <summary>
44 /// Direction cardinal of the border, think, 'which side of the region this is'. EX South border: Cardinal.S
45 /// </summary>
46 public Cardinals CrossDirection = Cardinals.N;
47 public uint TriggerRegionX = 0;
48 public uint TriggerRegionY = 0;
49
50 public Border()
51 {
52 }
53
54 /// <summary>
55 /// Creates a Border. The line is perpendicular to the direction cardinal.
56 /// IE: if the direction cardinal is South, the line is West->East
57 /// </summary>
58 /// <param name="lineStart">The starting point for the line of the border.
59 /// The position of an object must be greater then this for this border to trigger.
60 /// Perpendicular to the direction cardinal</param>
61 /// <param name="lineEnd">The ending point for the line of the border.
62 /// The position of an object must be less then this for this border to trigger.
63 /// Perpendicular to the direction cardinal</param>
64 /// <param name="triggerCoordinate">The position that triggers border the border
65 /// cross parallel to the direction cardinal. On the North cardinal, this
66 /// normally 256. On the South cardinal, it's normally 0. Any position past this
67 /// point on the cartesian coordinate will trigger the border cross as long as it
68 /// falls within the line start and the line end.</param>
69 /// <param name="triggerRegionX">When this border triggers, teleport to this regionX
70 /// in the grid</param>
71 /// <param name="triggerRegionY">When this border triggers, teleport to this regionY
72 /// in the grid</param>
73 /// <param name="direction">Cardinal for border direction. Think, 'which side of the
74 /// region is this'</param>
75 public Border(float lineStart, float lineEnd, float triggerCoordinate, uint triggerRegionX,
76 uint triggerRegionY, Cardinals direction)
77 {
78 BorderLine = new Vector3(lineStart,lineEnd,triggerCoordinate);
79 CrossDirection = direction;
80 TriggerRegionX = triggerRegionX;
81 TriggerRegionY = triggerRegionY;
82 }
83
84 public bool TestCross(Vector3 position)
85 {
86 bool result = false;
87 switch (CrossDirection)
88 {
89 case Cardinals.N: // x+0, y+1
90 if (position.X >= BorderLine.X && position.X <=BorderLine.Y && position.Y > BorderLine.Z )
91 {
92 return true;
93 }
94 break;
95 case Cardinals.NE: // x+1, y+1
96 break;
97 case Cardinals.E: // x+1, y+0
98 if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X > BorderLine.Z)
99 {
100 return true;
101 }
102 break;
103 case Cardinals.SE: // x+1, y-1
104 break;
105 case Cardinals.S: // x+0, y-1
106 if (position.X >= BorderLine.X && position.X <= BorderLine.Y && position.Y-1 < BorderLine.Z)
107 {
108 return true;
109 }
110 break;
111 case Cardinals.SW: // x-1, y-1
112 break;
113 case Cardinals.W: // x-1, y+0
114 if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X-1 < BorderLine.Z)
115 {
116 return true;
117 }
118 break;
119 case Cardinals.NW: // x-1, y+1
120 break;
121
122
123 }
124
125 return result;
126 }
127
128 public float Extent
129 {
130 get
131 {
132 switch (CrossDirection)
133 {
134 case Cardinals.N:
135 break;
136 case Cardinals.S:
137 break;
138 case Cardinals.W:
139 break;
140 case Cardinals.E:
141 break;
142 }
143 return 0;
144 }
145 }
146
147 }
148
149
150}
diff --git a/OpenSim/Region/Framework/Scenes/Cardinals.cs b/OpenSim/Region/Framework/Scenes/Cardinals.cs
new file mode 100644
index 0000000..692389a
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Cardinals.cs
@@ -0,0 +1,11 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace OpenSim.Region.Framework.Scenes
6{
7 public enum Cardinals
8 {
9 N = 1, NE, E, SE, S, SW, W, NW
10 }
11}
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 6118a70..3e573cf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -81,6 +81,13 @@ namespace OpenSim.Region.Framework.Scenes
81 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); 81 protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>();
82 protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); 82 protected List<RegionInfo> m_neighbours = new List<RegionInfo>();
83 83
84 public volatile bool BordersLocked = false;
85
86 public List<Border> NorthBorders = new List<Border>();
87 public List<Border> EastBorders = new List<Border>();
88 public List<Border> SouthBorders = new List<Border>();
89 public List<Border> WestBorders = new List<Border>();
90
84 /// <value> 91 /// <value>
85 /// The scene graph for this scene 92 /// The scene graph for this scene
86 /// </value> 93 /// </value>
@@ -326,6 +333,31 @@ namespace OpenSim.Region.Framework.Scenes
326 m_config = config; 333 m_config = config;
327 334
328 Random random = new Random(); 335 Random random = new Random();
336
337 BordersLocked = true;
338
339 Border northBorder = new Border();
340 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
341 northBorder.CrossDirection = Cardinals.N;
342 NorthBorders.Add(northBorder);
343
344 Border southBorder = new Border();
345 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
346 southBorder.CrossDirection = Cardinals.S;
347 SouthBorders.Add(southBorder);
348
349 Border eastBorder = new Border();
350 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
351 eastBorder.CrossDirection = Cardinals.E;
352 EastBorders.Add(eastBorder);
353
354 Border westBorder = new Border();
355 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
356 westBorder.CrossDirection = Cardinals.W;
357 WestBorders.Add(westBorder);
358
359 BordersLocked = false;
360
329 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4); 361 m_lastAllocatedLocalId = (uint)(random.NextDouble() * (double)(uint.MaxValue/2))+(uint)(uint.MaxValue/4);
330 m_moduleLoader = moduleLoader; 362 m_moduleLoader = moduleLoader;
331 m_authenticateHandler = authen; 363 m_authenticateHandler = authen;
@@ -455,6 +487,28 @@ namespace OpenSim.Region.Framework.Scenes
455 /// <param name="regInfo"></param> 487 /// <param name="regInfo"></param>
456 public Scene(RegionInfo regInfo) 488 public Scene(RegionInfo regInfo)
457 { 489 {
490 BordersLocked = true;
491 Border northBorder = new Border();
492 northBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
493 northBorder.CrossDirection = Cardinals.N;
494 NorthBorders.Add(northBorder);
495
496 Border southBorder = new Border();
497 southBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
498 southBorder.CrossDirection = Cardinals.S;
499 SouthBorders.Add(southBorder);
500
501 Border eastBorder = new Border();
502 eastBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, (int)Constants.RegionSize); //<---
503 eastBorder.CrossDirection = Cardinals.E;
504 EastBorders.Add(eastBorder);
505
506 Border westBorder = new Border();
507 westBorder.BorderLine = new Vector3(0, (int)Constants.RegionSize, 0); //--->
508 westBorder.CrossDirection = Cardinals.W;
509 WestBorders.Add(westBorder);
510 BordersLocked = false;
511
458 m_regInfo = regInfo; 512 m_regInfo = regInfo;
459 m_eventManager = new EventManager(); 513 m_eventManager = new EventManager();
460 } 514 }
@@ -1659,35 +1713,86 @@ namespace OpenSim.Region.Framework.Scenes
1659 ulong newRegionHandle = 0; 1713 ulong newRegionHandle = 0;
1660 Vector3 pos = attemptedPosition; 1714 Vector3 pos = attemptedPosition;
1661 1715
1662 if (attemptedPosition.X > Constants.RegionSize + 0.1f) 1716 if (TestBorderCross(attemptedPosition, Cardinals.W))
1663 { 1717 {
1664 pos.X = ((pos.X - Constants.RegionSize)); 1718 if (TestBorderCross(attemptedPosition, Cardinals.S))
1665 newRegionHandle 1719 {
1666 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize)); 1720 //Border crossedBorderx = GetCrossedBorder(attemptedPosition,Cardinals.W);
1667 // x + 1 1721 //Border crossedBordery = GetCrossedBorder(attemptedPosition, Cardinals.S);
1722 //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize)
1723 pos.X = ((pos.X + Constants.RegionSize));
1724 pos.Y = ((pos.Y + Constants.RegionSize));
1725 newRegionHandle
1726 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize),
1727 (uint)((thisy - 1) * Constants.RegionSize));
1728 // x - 1
1729 // y - 1
1730 }
1731 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1732 {
1733 pos.X = ((pos.X + Constants.RegionSize));
1734 pos.Y = ((pos.Y - Constants.RegionSize));
1735 newRegionHandle
1736 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize),
1737 (uint)((thisy + 1) * Constants.RegionSize));
1738 // x - 1
1739 // y + 1
1740 }
1741 else
1742 {
1743 pos.X = ((pos.X + Constants.RegionSize));
1744 newRegionHandle
1745 = Util.UIntsToLong((uint) ((thisx - 1)*Constants.RegionSize),
1746 (uint) (thisy*Constants.RegionSize));
1747 // x - 1
1748 }
1668 } 1749 }
1669 else if (attemptedPosition.X < -0.1f) 1750 else if (TestBorderCross(attemptedPosition, Cardinals.E))
1751 {
1752 if (TestBorderCross(attemptedPosition, Cardinals.S))
1753 {
1754 pos.X = ((pos.X - Constants.RegionSize));
1755 pos.Y = ((pos.Y + Constants.RegionSize));
1756 newRegionHandle
1757 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize),
1758 (uint)((thisy - 1) * Constants.RegionSize));
1759 // x + 1
1760 // y - 1
1761 }
1762 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1763 {
1764 pos.X = ((pos.X - Constants.RegionSize));
1765 pos.Y = ((pos.Y - Constants.RegionSize));
1766 newRegionHandle
1767 = Util.UIntsToLong((uint)((thisx + 1) * Constants.RegionSize),
1768 (uint)((thisy + 1) * Constants.RegionSize));
1769 // x + 1
1770 // y + 1
1771 }
1772 else
1773 {
1774 pos.X = ((pos.X - Constants.RegionSize));
1775 newRegionHandle
1776 = Util.UIntsToLong((uint) ((thisx + 1)*Constants.RegionSize),
1777 (uint) (thisy*Constants.RegionSize));
1778 // x + 1
1779 }
1780 }
1781 else if (TestBorderCross(attemptedPosition, Cardinals.S))
1670 { 1782 {
1671 pos.X = ((pos.X + Constants.RegionSize)); 1783 pos.Y = ((pos.Y + Constants.RegionSize));
1672 newRegionHandle 1784 newRegionHandle
1673 = Util.UIntsToLong((uint)((thisx - 1) * Constants.RegionSize), (uint)(thisy * Constants.RegionSize)); 1785 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
1674 // x - 1 1786 // y - 1
1675 } 1787 }
1676 1788 else if (TestBorderCross(attemptedPosition, Cardinals.N))
1677 if (attemptedPosition.Y > Constants.RegionSize + 0.1f)
1678 { 1789 {
1790
1679 pos.Y = ((pos.Y - Constants.RegionSize)); 1791 pos.Y = ((pos.Y - Constants.RegionSize));
1680 newRegionHandle 1792 newRegionHandle
1681 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize)); 1793 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + 1) * Constants.RegionSize));
1682 // y + 1 1794 // y + 1
1683 } 1795 }
1684 else if (attemptedPosition.Y < -0.1f)
1685 {
1686 pos.Y = ((pos.Y + Constants.RegionSize));
1687 newRegionHandle
1688 = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - 1) * Constants.RegionSize));
1689 // y - 1
1690 }
1691 1796
1692 // Offset the positions for the new region across the border 1797 // Offset the positions for the new region across the border
1693 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 1798 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
@@ -1701,6 +1806,186 @@ namespace OpenSim.Region.Framework.Scenes
1701 } 1806 }
1702 } 1807 }
1703 1808
1809 public Border GetCrossedBorder(Vector3 position, Cardinals gridline)
1810 {
1811 if (BordersLocked)
1812 {
1813 switch (gridline)
1814 {
1815 case Cardinals.N:
1816 lock (NorthBorders)
1817 {
1818 foreach (Border b in NorthBorders)
1819 {
1820 if (b.TestCross(position))
1821 return b;
1822 }
1823 }
1824 break;
1825 case Cardinals.S:
1826 lock (SouthBorders)
1827 {
1828 foreach (Border b in SouthBorders)
1829 {
1830 if (b.TestCross(position))
1831 return b;
1832 }
1833 }
1834
1835 break;
1836 case Cardinals.E:
1837 lock (EastBorders)
1838 {
1839 foreach (Border b in EastBorders)
1840 {
1841 if (b.TestCross(position))
1842 return b;
1843 }
1844 }
1845
1846 break;
1847 case Cardinals.W:
1848
1849 lock (WestBorders)
1850 {
1851 foreach (Border b in WestBorders)
1852 {
1853 if (b.TestCross(position))
1854 return b;
1855 }
1856 }
1857 break;
1858
1859 }
1860 }
1861 else
1862 {
1863 switch (gridline)
1864 {
1865 case Cardinals.N:
1866 foreach (Border b in NorthBorders)
1867 {
1868 if (b.TestCross(position))
1869 return b;
1870 }
1871
1872 break;
1873 case Cardinals.S:
1874 foreach (Border b in SouthBorders)
1875 {
1876 if (b.TestCross(position))
1877 return b;
1878 }
1879 break;
1880 case Cardinals.E:
1881 foreach (Border b in EastBorders)
1882 {
1883 if (b.TestCross(position))
1884 return b;
1885 }
1886
1887 break;
1888 case Cardinals.W:
1889 foreach (Border b in WestBorders)
1890 {
1891 if (b.TestCross(position))
1892 return b;
1893 }
1894 break;
1895
1896 }
1897 }
1898
1899
1900 return null;
1901 }
1902
1903 public bool TestBorderCross(Vector3 position, Cardinals border)
1904 {
1905 if (BordersLocked)
1906 {
1907 switch (border)
1908 {
1909 case Cardinals.N:
1910 lock (NorthBorders)
1911 {
1912 foreach (Border b in NorthBorders)
1913 {
1914 if (b.TestCross(position))
1915 return true;
1916 }
1917 }
1918 break;
1919 case Cardinals.E:
1920 lock (EastBorders)
1921 {
1922 foreach (Border b in EastBorders)
1923 {
1924 if (b.TestCross(position))
1925 return true;
1926 }
1927 }
1928 break;
1929 case Cardinals.S:
1930 lock (SouthBorders)
1931 {
1932 foreach (Border b in SouthBorders)
1933 {
1934 if (b.TestCross(position))
1935 return true;
1936 }
1937 }
1938 break;
1939 case Cardinals.W:
1940 lock (WestBorders)
1941 {
1942 foreach (Border b in WestBorders)
1943 {
1944 if (b.TestCross(position))
1945 return true;
1946 }
1947 }
1948 break;
1949 }
1950 }
1951 else
1952 {
1953 switch (border)
1954 {
1955 case Cardinals.N:
1956 foreach (Border b in NorthBorders)
1957 {
1958 if (b.TestCross(position))
1959 return true;
1960 }
1961 break;
1962 case Cardinals.E:
1963 foreach (Border b in EastBorders)
1964 {
1965 if (b.TestCross(position))
1966 return true;
1967 }
1968 break;
1969 case Cardinals.S:
1970 foreach (Border b in SouthBorders)
1971 {
1972 if (b.TestCross(position))
1973 return true;
1974 }
1975 break;
1976 case Cardinals.W:
1977 foreach (Border b in WestBorders)
1978 {
1979 if (b.TestCross(position))
1980 return true;
1981 }
1982 break;
1983 }
1984 }
1985 return false;
1986 }
1987
1988
1704 /// <summary> 1989 /// <summary>
1705 /// Move the given scene object into a new region 1990 /// Move the given scene object into a new region
1706 /// </summary> 1991 /// </summary>
@@ -3063,16 +3348,47 @@ namespace OpenSim.Region.Framework.Scenes
3063 3348
3064 if (sp != null) 3349 if (sp != null)
3065 { 3350 {
3351 uint regionX = m_regInfo.RegionLocX;
3352 uint regionY = m_regInfo.RegionLocY;
3353
3354 Utils.LongToUInts(regionHandle, out regionX, out regionY);
3355
3356 int shiftx = (int) regionX - (int) m_regInfo.RegionLocX * (int)Constants.RegionSize;
3357 int shifty = (int)regionY - (int)m_regInfo.RegionLocY * (int)Constants.RegionSize;
3358
3359 position.X += shiftx;
3360 position.Y += shifty;
3361
3362 bool result = false;
3363
3364 if (TestBorderCross(position,Cardinals.N))
3365 result = true;
3366
3367 if (TestBorderCross(position, Cardinals.S))
3368 result = true;
3369
3370 if (TestBorderCross(position, Cardinals.E))
3371 result = true;
3372
3373 if (TestBorderCross(position, Cardinals.W))
3374 result = true;
3375
3376 // bordercross if position is outside of region
3377
3378 if (!result)
3379 regionHandle = m_regInfo.RegionHandle;
3380
3066 if (m_teleportModule != null) 3381 if (m_teleportModule != null)
3067 { 3382 {
3068 m_teleportModule.RequestTeleportToLocation(sp, regionHandle, 3383 m_teleportModule.RequestTeleportToLocation(sp, regionHandle,
3069 position, lookAt, teleportFlags); 3384 position, lookAt, teleportFlags);
3070 } 3385 }
3071 else 3386 else
3072 { 3387 {
3073 m_sceneGridService.RequestTeleportToLocation(sp, regionHandle, 3388 m_sceneGridService.RequestTeleportToLocation(sp, regionHandle,
3074 position, lookAt, teleportFlags); 3389 position, lookAt, teleportFlags);
3075 } 3390 }
3391
3076 } 3392 }
3077 } 3393 }
3078 3394
diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
index 65c97e8..1673a22 100644
--- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
@@ -803,11 +803,11 @@ namespace OpenSim.Region.Framework.Scenes
803 if (regionHandle == m_regionInfo.RegionHandle) 803 if (regionHandle == m_regionInfo.RegionHandle)
804 { 804 {
805 m_log.DebugFormat( 805 m_log.DebugFormat(
806 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", 806 "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}",
807 position, m_regionInfo.RegionName); 807 position, m_regionInfo.RegionName);
808 808
809 // Teleport within the same region 809 // Teleport within the same region
810 if (position.X < 0 || position.X > Constants.RegionSize || position.Y < 0 || position.Y > Constants.RegionSize || position.Z < 0) 810 if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0)
811 { 811 {
812 Vector3 emergencyPos = new Vector3(128, 128, 128); 812 Vector3 emergencyPos = new Vector3(128, 128, 128);
813 813
@@ -816,10 +816,17 @@ namespace OpenSim.Region.Framework.Scenes
816 position, avatar.Name, avatar.UUID, emergencyPos); 816 position, avatar.Name, avatar.UUID, emergencyPos);
817 position = emergencyPos; 817 position = emergencyPos;
818 } 818 }
819 819
820 // TODO: Get proper AVG Height 820 // TODO: Get proper AVG Height
821 float localAVHeight = 1.56f; 821 float localAVHeight = 1.56f;
822 float posZLimit = (float)avatar.Scene.Heightmap[(int)position.X, (int)position.Y]; 822 float posZLimit = 22;
823
824 // TODO: Check other Scene HeightField
825 if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <=(int)Constants.RegionSize)
826 {
827 posZLimit = (float) avatar.Scene.Heightmap[(int) position.X, (int) position.Y];
828 }
829
823 float newPosZ = posZLimit + localAVHeight; 830 float newPosZ = posZLimit + localAVHeight;
824 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 831 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
825 { 832 {
@@ -1084,6 +1091,21 @@ namespace OpenSim.Region.Framework.Scenes
1084 } 1091 }
1085 } 1092 }
1086 1093
1094 private bool IsOutsideRegion(Scene s, Vector3 pos)
1095 {
1096
1097 if (s.TestBorderCross(pos,Cardinals.N))
1098 return true;
1099 if (s.TestBorderCross(pos, Cardinals.S))
1100 return true;
1101 if (s.TestBorderCross(pos, Cardinals.E))
1102 return true;
1103 if (s.TestBorderCross(pos, Cardinals.W))
1104 return true;
1105
1106 return false;
1107 }
1108
1087 public bool WaitForCallback(UUID id) 1109 public bool WaitForCallback(UUID id)
1088 { 1110 {
1089 int count = 200; 1111 int count = 200;
@@ -1158,34 +1180,91 @@ namespace OpenSim.Region.Framework.Scenes
1158 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1180 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
1159 uint neighbourx = m_regionInfo.RegionLocX; 1181 uint neighbourx = m_regionInfo.RegionLocX;
1160 uint neighboury = m_regionInfo.RegionLocY; 1182 uint neighboury = m_regionInfo.RegionLocY;
1183 const float boundaryDistance = 1.7f;
1184 Vector3 northCross = new Vector3(0, boundaryDistance, 0);
1185 Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0);
1186 Vector3 eastCross = new Vector3(boundaryDistance, 0, 0);
1187 Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0);
1161 1188
1162 // distance to edge that will trigger crossing 1189 // distance to edge that will trigger crossing
1163 const float boundaryDistance = 1.7f; 1190
1164 1191
1165 // distance into new region to place avatar 1192 // distance into new region to place avatar
1166 const float enterDistance = 0.1f; 1193 const float enterDistance = 0.5f;
1194
1195 if (scene.TestBorderCross(pos + westCross, Cardinals.W))
1196 {
1197 if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1198 {
1199 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1200 neighboury += (uint)(int)(b.BorderLine.Z/(int)Constants.RegionSize);
1201 }
1202 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1203 {
1204 neighboury--;
1205 newpos.Y = Constants.RegionSize - enterDistance;
1206 }
1207
1208 neighbourx--;
1209 newpos.X = Constants.RegionSize - enterDistance;
1210
1211 }
1212 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
1213 {
1214 Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E);
1215 neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1216 newpos.X = enterDistance;
1217
1218 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1219 {
1220 neighboury--;
1221 newpos.Y = Constants.RegionSize - enterDistance;
1222 }
1223 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1224 {
1225 Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1226 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
1227 newpos.Y = enterDistance;
1228 }
1229
1230
1231 }
1232 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
1233 {
1234 neighboury--;
1235 newpos.Y = Constants.RegionSize - enterDistance;
1236 }
1237 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
1238 {
1239 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
1240 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
1241 newpos.Y = enterDistance;
1242 }
1243
1244 /*
1167 1245
1168 if (pos.X < boundaryDistance) 1246 if (pos.X < boundaryDistance) //West
1169 { 1247 {
1170 neighbourx--; 1248 neighbourx--;
1171 newpos.X = Constants.RegionSize - enterDistance; 1249 newpos.X = Constants.RegionSize - enterDistance;
1172 } 1250 }
1173 else if (pos.X > Constants.RegionSize - boundaryDistance) 1251 else if (pos.X > Constants.RegionSize - boundaryDistance) // East
1174 { 1252 {
1175 neighbourx++; 1253 neighbourx++;
1176 newpos.X = enterDistance; 1254 newpos.X = enterDistance;
1177 } 1255 }
1178 1256
1179 if (pos.Y < boundaryDistance) 1257 if (pos.Y < boundaryDistance) // South
1180 { 1258 {
1181 neighboury--; 1259 neighboury--;
1182 newpos.Y = Constants.RegionSize - enterDistance; 1260 newpos.Y = Constants.RegionSize - enterDistance;
1183 } 1261 }
1184 else if (pos.Y > Constants.RegionSize - boundaryDistance) 1262 else if (pos.Y > Constants.RegionSize - boundaryDistance) // North
1185 { 1263 {
1186 neighboury++; 1264 neighboury++;
1187 newpos.Y = enterDistance; 1265 newpos.Y = enterDistance;
1188 } 1266 }
1267 */
1189 1268
1190 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1269 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
1191 d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d); 1270 d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d);
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 1b541c4..e5c6bf1 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -264,7 +264,9 @@ namespace OpenSim.Region.Framework.Scenes
264 { 264 {
265 Vector3 val = value; 265 Vector3 val = value;
266 266
267 if ((val.X > 257f || val.X < -1f || val.Y > 257f || val.Y < -1f) && !IsAttachment) 267 if ((m_scene.TestBorderCross(val,Cardinals.E) || m_scene.TestBorderCross(val,Cardinals.W)
268 || m_scene.TestBorderCross(val, Cardinals.N) || m_scene.TestBorderCross(val, Cardinals.S))
269 && !IsAttachment)
268 { 270 {
269 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 271 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
270 } 272 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index cf716e8..40e7471 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -2097,7 +2097,8 @@ if (m_shape != null) {
2097 if (PhysActor != null) 2097 if (PhysActor != null)
2098 { 2098 {
2099 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0); 2099 Vector3 newpos = new Vector3(PhysActor.Position.GetBytes(), 0);
2100 if (newpos.X > 257f || newpos.X < -1f || newpos.Y > 257f || newpos.Y < -1f) 2100
2101 if (m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.N) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.S) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.E) | m_parentGroup.Scene.TestBorderCross(newpos, Cardinals.W))
2101 { 2102 {
2102 m_parentGroup.AbsolutePosition = newpos; 2103 m_parentGroup.AbsolutePosition = newpos;
2103 return; 2104 return;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ff97183..46e3289 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -222,10 +222,7 @@ namespace OpenSim.Region.Framework.Scenes
222 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG 222 DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
223 } 223 }
224 224
225 protected enum Cardinals 225
226 {
227 N=1,NE,E,SE,S,SW,W,NW
228 }
229 /// <summary> 226 /// <summary>
230 /// Position at which a significant movement was made 227 /// Position at which a significant movement was made
231 /// </summary> 228 /// </summary>
@@ -2833,29 +2830,31 @@ namespace OpenSim.Region.Framework.Scenes
2833 if (!IsInTransit) 2830 if (!IsInTransit)
2834 { 2831 {
2835 // Checks if where it's headed exists a region 2832 // Checks if where it's headed exists a region
2836 if (pos2.X < 0) 2833
2834 if (m_scene.TestBorderCross(pos2, Cardinals.W))
2837 { 2835 {
2838 if (pos2.Y < 0) 2836 if (m_scene.TestBorderCross(pos2, Cardinals.S))
2839 neighbor = HaveNeighbor(Cardinals.SW, ref fix); 2837 neighbor = HaveNeighbor(Cardinals.SW, ref fix);
2840 else if (pos2.Y > Constants.RegionSize) 2838 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2841 neighbor = HaveNeighbor(Cardinals.NW, ref fix); 2839 neighbor = HaveNeighbor(Cardinals.NW, ref fix);
2842 else 2840 else
2843 neighbor = HaveNeighbor(Cardinals.W, ref fix); 2841 neighbor = HaveNeighbor(Cardinals.W, ref fix);
2844 } 2842 }
2845 else if (pos2.X > Constants.RegionSize) 2843 else if (m_scene.TestBorderCross(pos2, Cardinals.E))
2846 { 2844 {
2847 if (pos2.Y < 0) 2845 if (m_scene.TestBorderCross(pos2, Cardinals.S))
2848 neighbor = HaveNeighbor(Cardinals.SE, ref fix); 2846 neighbor = HaveNeighbor(Cardinals.SE, ref fix);
2849 else if (pos2.Y > Constants.RegionSize) 2847 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2850 neighbor = HaveNeighbor(Cardinals.NE, ref fix); 2848 neighbor = HaveNeighbor(Cardinals.NE, ref fix);
2851 else 2849 else
2852 neighbor = HaveNeighbor(Cardinals.E, ref fix); 2850 neighbor = HaveNeighbor(Cardinals.E, ref fix);
2853 } 2851 }
2854 else if (pos2.Y < 0) 2852 else if (m_scene.TestBorderCross(pos2, Cardinals.S))
2855 neighbor = HaveNeighbor(Cardinals.S, ref fix); 2853 neighbor = HaveNeighbor(Cardinals.S, ref fix);
2856 else if (pos2.Y > Constants.RegionSize) 2854 else if (m_scene.TestBorderCross(pos2, Cardinals.N))
2857 neighbor = HaveNeighbor(Cardinals.N, ref fix); 2855 neighbor = HaveNeighbor(Cardinals.N, ref fix);
2858 2856
2857
2859 // Makes sure avatar does not end up outside region 2858 // Makes sure avatar does not end up outside region
2860 if (neighbor < 0) 2859 if (neighbor < 0)
2861 AbsolutePosition = new Vector3( 2860 AbsolutePosition = new Vector3(
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
new file mode 100644
index 0000000..272c96e
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -0,0 +1,312 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenMetaverse;
5using OpenSim.Region.Framework.Scenes;
6
7using NUnit.Framework;
8
9namespace OpenSim.Region.Framework.Scenes.Tests
10{
11 [TestFixture]
12 public class BorderTests
13 {
14
15 [Test]
16 public void TestCross()
17 {
18 List<Border> testborders = new List<Border>();
19
20 Border NorthBorder = new Border();
21 NorthBorder.BorderLine = new Vector3(0, 256, 256); //<---
22 NorthBorder.CrossDirection = Cardinals.N;
23 testborders.Add(NorthBorder);
24
25 Border SouthBorder = new Border();
26 SouthBorder.BorderLine = new Vector3(0, 256, 0); //--->
27 SouthBorder.CrossDirection = Cardinals.S;
28 testborders.Add(SouthBorder);
29
30 Border EastBorder = new Border();
31 EastBorder.BorderLine = new Vector3(0, 256, 256); //<---
32 EastBorder.CrossDirection = Cardinals.E;
33 testborders.Add(EastBorder);
34
35 Border WestBorder = new Border();
36 WestBorder.BorderLine = new Vector3(0, 256, 0); //--->
37 WestBorder.CrossDirection = Cardinals.W;
38 testborders.Add(WestBorder);
39
40 Vector3 position = new Vector3(200,200,21);
41
42 foreach (Border b in testborders)
43 {
44 Assert.That(!b.TestCross(position));
45
46 }
47
48 position = new Vector3(200,280,21);
49 Assert.That(NorthBorder.TestCross(position));
50
51
52
53 // Test automatic border crossing
54 // by setting the border crossing aabb to be the whole region
55 position = new Vector3(25,25,21); // safely within one 256m region
56
57 // The Z value of the BorderLine is reversed, making all positions within the region
58 // trigger bordercross
59
60 SouthBorder.BorderLine = new Vector3(0,256,256); // automatic border cross in the region
61 Assert.That(SouthBorder.TestCross(position));
62
63 NorthBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region
64 Assert.That(NorthBorder.TestCross(position));
65
66 EastBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region
67 Assert.That(EastBorder.TestCross(position));
68
69 WestBorder.BorderLine = new Vector3(0, 256, 255); // automatic border cross in the region
70 Assert.That(WestBorder.TestCross(position));
71
72 }
73
74 [Test]
75 public void TestCrossSquare512()
76 {
77 List<Border> testborders = new List<Border>();
78
79 Border NorthBorder = new Border();
80 NorthBorder.BorderLine = new Vector3(0, 512, 512);
81 NorthBorder.CrossDirection = Cardinals.N;
82 testborders.Add(NorthBorder);
83
84 Border SouthBorder = new Border();
85 SouthBorder.BorderLine = new Vector3(0, 512, 0);
86 SouthBorder.CrossDirection = Cardinals.S;
87 testborders.Add(SouthBorder);
88
89 Border EastBorder = new Border();
90 EastBorder.BorderLine = new Vector3(0, 512, 512);
91 EastBorder.CrossDirection = Cardinals.E;
92 testborders.Add(EastBorder);
93
94 Border WestBorder = new Border();
95 WestBorder.BorderLine = new Vector3(0, 512, 0);
96 WestBorder.CrossDirection = Cardinals.W;
97 testborders.Add(WestBorder);
98
99 Vector3 position = new Vector3(450,220,21);
100
101 foreach (Border b in testborders)
102 {
103 Assert.That(!b.TestCross(position));
104
105 }
106
107 //Trigger east border
108 position = new Vector3(513,220,21);
109 foreach (Border b in testborders)
110 {
111 if (b.CrossDirection == Cardinals.E)
112 Assert.That(b.TestCross(position));
113 else
114 Assert.That(!b.TestCross(position));
115
116 }
117
118 //Trigger west border
119 position = new Vector3(-1, 220, 21);
120 foreach (Border b in testborders)
121 {
122 if (b.CrossDirection == Cardinals.W)
123 Assert.That(b.TestCross(position));
124 else
125 Assert.That(!b.TestCross(position));
126
127 }
128
129 //Trigger north border
130 position = new Vector3(220, 513, 21);
131 foreach (Border b in testborders)
132 {
133 if (b.CrossDirection == Cardinals.N)
134 Assert.That(b.TestCross(position));
135 else
136 Assert.That(!b.TestCross(position));
137
138 }
139
140 //Trigger south border
141 position = new Vector3(220, -1, 21);
142 foreach (Border b in testborders)
143 {
144 if (b.CrossDirection == Cardinals.S)
145 Assert.That(b.TestCross(position));
146 else
147 Assert.That(!b.TestCross(position));
148
149 }
150
151 }
152
153 [Test]
154 public void TestCrossRectangle512x256()
155 {
156 List<Border> testborders = new List<Border>();
157
158 Border NorthBorder = new Border();
159 NorthBorder.BorderLine = new Vector3(0, 512, 256);
160 NorthBorder.CrossDirection = Cardinals.N;
161 testborders.Add(NorthBorder);
162
163 Border SouthBorder = new Border();
164 SouthBorder.BorderLine = new Vector3(0, 512, 0);
165 SouthBorder.CrossDirection = Cardinals.S;
166 testborders.Add(SouthBorder);
167
168 Border EastBorder = new Border();
169 EastBorder.BorderLine = new Vector3(0, 256, 512);
170 EastBorder.CrossDirection = Cardinals.E;
171 testborders.Add(EastBorder);
172
173 Border WestBorder = new Border();
174 WestBorder.BorderLine = new Vector3(0, 256, 0);
175 WestBorder.CrossDirection = Cardinals.W;
176 testborders.Add(WestBorder);
177
178 Vector3 position = new Vector3(450, 220, 21);
179
180 foreach (Border b in testborders)
181 {
182 Assert.That(!b.TestCross(position));
183
184 }
185
186 //Trigger east border
187 position = new Vector3(513, 220, 21);
188 foreach (Border b in testborders)
189 {
190 if (b.CrossDirection == Cardinals.E)
191 Assert.That(b.TestCross(position));
192 else
193 Assert.That(!b.TestCross(position));
194
195 }
196
197 //Trigger west border
198 position = new Vector3(-1, 220, 21);
199 foreach (Border b in testborders)
200 {
201 if (b.CrossDirection == Cardinals.W)
202 Assert.That(b.TestCross(position));
203 else
204 Assert.That(!b.TestCross(position));
205
206 }
207
208 //Trigger north border
209 position = new Vector3(220, 257, 21);
210 foreach (Border b in testborders)
211 {
212 if (b.CrossDirection == Cardinals.N)
213 Assert.That(b.TestCross(position));
214 else
215 Assert.That(!b.TestCross(position));
216
217 }
218
219 //Trigger south border
220 position = new Vector3(220, -1, 21);
221 foreach (Border b in testborders)
222 {
223 if (b.CrossDirection == Cardinals.S)
224 Assert.That(b.TestCross(position));
225 else
226 Assert.That(!b.TestCross(position));
227
228 }
229 }
230
231 [Test]
232 public void TestCrossOdd512x512w256hole()
233 {
234 List<Border> testborders = new List<Border>();
235 // 512____
236 // | |
237 // 256__| |___
238 // | |
239 // |______|
240 // 0 | 512
241 // 256
242
243 // Compound North border since the hole is at the top
244 Border NorthBorder1 = new Border();
245 NorthBorder1.BorderLine = new Vector3(0, 256, 512);
246 NorthBorder1.CrossDirection = Cardinals.N;
247 testborders.Add(NorthBorder1);
248
249 Border NorthBorder2 = new Border();
250 NorthBorder2.BorderLine = new Vector3(256, 512, 256);
251 NorthBorder2.CrossDirection = Cardinals.N;
252 testborders.Add(NorthBorder2);
253
254 Border SouthBorder = new Border();
255 SouthBorder.BorderLine = new Vector3(0, 512, 0);
256 SouthBorder.CrossDirection = Cardinals.S;
257 testborders.Add(SouthBorder);
258
259 //Compound East border
260 Border EastBorder1 = new Border();
261 EastBorder1.BorderLine = new Vector3(0, 256, 512);
262 EastBorder1.CrossDirection = Cardinals.E;
263 testborders.Add(EastBorder1);
264
265 Border EastBorder2 = new Border();
266 EastBorder2.BorderLine = new Vector3(257, 512, 256);
267 EastBorder2.CrossDirection = Cardinals.E;
268 testborders.Add(EastBorder2);
269
270
271
272 Border WestBorder = new Border();
273 WestBorder.BorderLine = new Vector3(0, 512, 0);
274 WestBorder.CrossDirection = Cardinals.W;
275 testborders.Add(WestBorder);
276
277 Vector3 position = new Vector3(450, 220, 21);
278
279 foreach (Border b in testborders)
280 {
281 Assert.That(!b.TestCross(position));
282
283 }
284
285 position = new Vector3(220, 450, 21);
286
287 foreach (Border b in testborders)
288 {
289 Assert.That(!b.TestCross(position));
290
291 }
292
293 bool result = false;
294 int bordersTriggered = 0;
295
296 position = new Vector3(450, 450, 21);
297
298 foreach (Border b in testborders)
299 {
300 if (b.TestCross(position))
301 {
302 bordersTriggered++;
303 result = true;
304 }
305 }
306
307 Assert.That(result);
308 Assert.That(bordersTriggered == 2);
309
310 }
311 }
312}