From de543002aa4d2b05c21db386b5a11628e272f353 Mon Sep 17 00:00:00 2001 From: "Teravus Ovares (Dan Olivares)" Date: Wed, 19 Aug 2009 14:43:03 -0400 Subject: [PATCH] Add Border (a virtual border management class) Move Cardinals to it's own file. --- OpenSim/Region/Framework/Scenes/Border.cs | 131 ++++++++ OpenSim/Region/Framework/Scenes/Cardinals.cs | 11 + .../Region/Framework/Scenes/ScenePresence.cs | 5 +- .../Framework/Scenes/Tests/BorderTests.cs | 312 ++++++++++++++++++ 4 files changed, 455 insertions(+), 4 deletions(-) create mode 100644 OpenSim/Region/Framework/Scenes/Border.cs create mode 100644 OpenSim/Region/Framework/Scenes/Cardinals.cs create mode 100644 OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs diff --git a/OpenSim/Region/Framework/Scenes/Border.cs b/OpenSim/Region/Framework/Scenes/Border.cs new file mode 100644 index 0000000000..19ecb4f180 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Border.cs @@ -0,0 +1,131 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Scenes +{ + public class Border + { + + /// + /// Line perpendicular to the Direction Cardinal. Z value is the + /// + public Vector3 BorderLine = Vector3.Zero; + + /// + /// Direction cardinal of the border, think, 'which side of the region this is'. EX South border: Cardinal.S + /// + public Cardinals CrossDirection = Cardinals.N; + public uint TriggerRegionX = 0; + public uint TriggerRegionY = 0; + + public Border() + { + } + + /// + /// Creates a Border. The line is perpendicular to the direction cardinal. + /// IE: if the direction cardinal is South, the line is West->East + /// + /// The starting point for the line of the border. + /// The position of an object must be greater then this for this border to trigger. + /// Perpendicular to the direction cardinal + /// The ending point for the line of the border. + /// The position of an object must be less then this for this border to trigger. + /// Perpendicular to the direction cardinal + /// The position that triggers border the border + /// cross parallel to the direction cardinal. On the North cardinal, this + /// normally 256. On the South cardinal, it's normally 0. Any position past this + /// point on the cartesian coordinate will trigger the border cross as long as it + /// falls within the line start and the line end. + /// When this border triggers, teleport to this regionX + /// in the grid + /// When this border triggers, teleport to this regionY + /// in the grid + /// Cardinal for border direction. Think, 'which side of the + /// region is this' + public Border(float lineStart, float lineEnd, float triggerCoordinate, uint triggerRegionX, + uint triggerRegionY, Cardinals direction) + { + BorderLine = new Vector3(lineStart,lineEnd,triggerCoordinate); + CrossDirection = direction; + TriggerRegionX = triggerRegionX; + TriggerRegionY = triggerRegionY; + } + + public bool TestCross(Vector3 position) + { + bool result = false; + switch (CrossDirection) + { + case Cardinals.N: // x+0, y+1 + if (position.X >= BorderLine.X && position.X <=BorderLine.Y && position.Y > BorderLine.Z ) + { + return true; + } + break; + case Cardinals.NE: // x+1, y+1 + break; + case Cardinals.E: // x+1, y+0 + if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X > BorderLine.Z) + { + return true; + } + break; + case Cardinals.SE: // x+1, y-1 + break; + case Cardinals.S: // x+0, y-1 + if (position.X >= BorderLine.X && position.X <= BorderLine.Y && position.Y < BorderLine.Z) + { + return true; + } + break; + case Cardinals.SW: // x-1, y-1 + break; + case Cardinals.W: // x-1, y+0 + if (position.Y >= BorderLine.X && position.Y <= BorderLine.Y && position.X < BorderLine.Z) + { + return true; + } + break; + case Cardinals.NW: // x-1, y+1 + break; + + + } + + return result; + } + + } + + +} diff --git a/OpenSim/Region/Framework/Scenes/Cardinals.cs b/OpenSim/Region/Framework/Scenes/Cardinals.cs new file mode 100644 index 0000000000..692389a7f2 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Cardinals.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenSim.Region.Framework.Scenes +{ + public enum Cardinals + { + N = 1, NE, E, SE, S, SW, W, NW + } +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ff97183ff9..5281c4f475 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -222,10 +222,7 @@ namespace OpenSim.Region.Framework.Scenes DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG } - protected enum Cardinals - { - N=1,NE,E,SE,S,SW,W,NW - } + /// /// Position at which a significant movement was made /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs new file mode 100644 index 0000000000..6f77062242 --- /dev/null +++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs @@ -0,0 +1,312 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenMetaverse; +using OpenSim.Region.Framework.Scenes; + +using NUnit.Framework; + +namespace OpenSim.Region.Framework.Tests +{ + [TestFixture] + public class BorderTests + { + + [Test] + public void TestCross() + { + List testborders = new List(); + + Border NorthBorder = new Border(); + NorthBorder.BorderLine = new Vector3(0, 256, 256); //<--- + NorthBorder.CrossDirection = Cardinals.N; + testborders.Add(NorthBorder); + + Border SouthBorder = new Border(); + SouthBorder.BorderLine = new Vector3(0, 256, 0); //---> + SouthBorder.CrossDirection = Cardinals.S; + testborders.Add(SouthBorder); + + Border EastBorder = new Border(); + EastBorder.BorderLine = new Vector3(0, 256, 256); //<--- + EastBorder.CrossDirection = Cardinals.E; + testborders.Add(EastBorder); + + Border WestBorder = new Border(); + WestBorder.BorderLine = new Vector3(0, 256, 0); //---> + WestBorder.CrossDirection = Cardinals.W; + testborders.Add(WestBorder); + + Vector3 position = new Vector3(200,200,21); + + foreach (Border b in testborders) + { + Assert.That(!b.TestCross(position)); + + } + + position = new Vector3(200,280,21); + Assert.That(NorthBorder.TestCross(position)); + + + + // Test automatic border crossing + // by setting the border crossing aabb to be the whole region + position = new Vector3(25,25,21); // safely within one 256m region + + // The Z value of the BorderLine is reversed, making all positions within the region + // trigger bordercross + + SouthBorder.BorderLine = new Vector3(0,256,256); // automatic border cross in the region + Assert.That(SouthBorder.TestCross(position)); + + NorthBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region + Assert.That(NorthBorder.TestCross(position)); + + EastBorder.BorderLine = new Vector3(0, 256, 0); // automatic border cross in the region + Assert.That(EastBorder.TestCross(position)); + + WestBorder.BorderLine = new Vector3(0, 256, 255); // automatic border cross in the region + Assert.That(WestBorder.TestCross(position)); + + } + + [Test] + public void TestCrossSquare512() + { + List testborders = new List(); + + Border NorthBorder = new Border(); + NorthBorder.BorderLine = new Vector3(0, 512, 512); + NorthBorder.CrossDirection = Cardinals.N; + testborders.Add(NorthBorder); + + Border SouthBorder = new Border(); + SouthBorder.BorderLine = new Vector3(0, 512, 0); + SouthBorder.CrossDirection = Cardinals.S; + testborders.Add(SouthBorder); + + Border EastBorder = new Border(); + EastBorder.BorderLine = new Vector3(0, 512, 512); + EastBorder.CrossDirection = Cardinals.E; + testborders.Add(EastBorder); + + Border WestBorder = new Border(); + WestBorder.BorderLine = new Vector3(0, 512, 0); + WestBorder.CrossDirection = Cardinals.W; + testborders.Add(WestBorder); + + Vector3 position = new Vector3(450,220,21); + + foreach (Border b in testborders) + { + Assert.That(!b.TestCross(position)); + + } + + //Trigger east border + position = new Vector3(513,220,21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.E) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger west border + position = new Vector3(-1, 220, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.W) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger north border + position = new Vector3(220, 513, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.N) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger south border + position = new Vector3(220, -1, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.S) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + } + + [Test] + public void TestCrossRectangle512x256() + { + List testborders = new List(); + + Border NorthBorder = new Border(); + NorthBorder.BorderLine = new Vector3(0, 512, 256); + NorthBorder.CrossDirection = Cardinals.N; + testborders.Add(NorthBorder); + + Border SouthBorder = new Border(); + SouthBorder.BorderLine = new Vector3(0, 512, 0); + SouthBorder.CrossDirection = Cardinals.S; + testborders.Add(SouthBorder); + + Border EastBorder = new Border(); + EastBorder.BorderLine = new Vector3(0, 256, 512); + EastBorder.CrossDirection = Cardinals.E; + testborders.Add(EastBorder); + + Border WestBorder = new Border(); + WestBorder.BorderLine = new Vector3(0, 256, 0); + WestBorder.CrossDirection = Cardinals.W; + testborders.Add(WestBorder); + + Vector3 position = new Vector3(450, 220, 21); + + foreach (Border b in testborders) + { + Assert.That(!b.TestCross(position)); + + } + + //Trigger east border + position = new Vector3(513, 220, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.E) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger west border + position = new Vector3(-1, 220, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.W) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger north border + position = new Vector3(220, 257, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.N) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + + //Trigger south border + position = new Vector3(220, -1, 21); + foreach (Border b in testborders) + { + if (b.CrossDirection == Cardinals.S) + Assert.That(b.TestCross(position)); + else + Assert.That(!b.TestCross(position)); + + } + } + + [Test] + public void TestCrossOdd512x512w256hole() + { + List testborders = new List(); + // 512____ + // | | + // 256__| |___ + // | | + // |______| + // 0 | 512 + // 256 + + // Compound North border since the hole is at the top + Border NorthBorder1 = new Border(); + NorthBorder1.BorderLine = new Vector3(0, 256, 512); + NorthBorder1.CrossDirection = Cardinals.N; + testborders.Add(NorthBorder1); + + Border NorthBorder2 = new Border(); + NorthBorder2.BorderLine = new Vector3(256, 512, 256); + NorthBorder2.CrossDirection = Cardinals.N; + testborders.Add(NorthBorder2); + + Border SouthBorder = new Border(); + SouthBorder.BorderLine = new Vector3(0, 512, 0); + SouthBorder.CrossDirection = Cardinals.S; + testborders.Add(SouthBorder); + + //Compound East border + Border EastBorder1 = new Border(); + EastBorder1.BorderLine = new Vector3(0, 256, 512); + EastBorder1.CrossDirection = Cardinals.E; + testborders.Add(EastBorder1); + + Border EastBorder2 = new Border(); + EastBorder2.BorderLine = new Vector3(257, 512, 256); + EastBorder2.CrossDirection = Cardinals.E; + testborders.Add(EastBorder2); + + + + Border WestBorder = new Border(); + WestBorder.BorderLine = new Vector3(0, 512, 0); + WestBorder.CrossDirection = Cardinals.W; + testborders.Add(WestBorder); + + Vector3 position = new Vector3(450, 220, 21); + + foreach (Border b in testborders) + { + Assert.That(!b.TestCross(position)); + + } + + position = new Vector3(220, 450, 21); + + foreach (Border b in testborders) + { + Assert.That(!b.TestCross(position)); + + } + + bool result = false; + int bordersTriggered = 0; + + position = new Vector3(450, 450, 21); + + foreach (Border b in testborders) + { + if (b.TestCross(position)) + { + bordersTriggered++; + result = true; + } + } + + Assert.That(result); + Assert.That(bordersTriggered == 2); + + } + } +}