aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2011-09-21 23:56:11 +0100
committerJustin Clark-Casey (justincc)2011-09-21 23:56:11 +0100
commit241e07d006fad1b54e088d8a9ddede0b98a1e800 (patch)
tree828c62846bdd47d6eea0a47b02d366dd1728b9ea /OpenSim/Region/Framework/Scenes
parentRemove unused and never set SP.PreviousRotation (diff)
downloadopensim-SC-241e07d006fad1b54e088d8a9ddede0b98a1e800.zip
opensim-SC-241e07d006fad1b54e088d8a9ddede0b98a1e800.tar.gz
opensim-SC-241e07d006fad1b54e088d8a9ddede0b98a1e800.tar.bz2
opensim-SC-241e07d006fad1b54e088d8a9ddede0b98a1e800.tar.xz
Move code which handles NPC movement into Scene so that this can also be used by Autopilot coming from the client side.
I thought that I had implemented this but must have accidentally removed it. Adds a regression test to detect if this happens again. Temporarily disables automatic landing of NPC at a target. Will be fixed presently.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs67
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs135
2 files changed, 202 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 976e001..000a6ed 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -870,6 +870,8 @@ namespace OpenSim.Region.Framework.Scenes
870 870
871 if (dm != null) 871 if (dm != null)
872 m_eventManager.OnPermissionError += dm.SendAlertToUser; 872 m_eventManager.OnPermissionError += dm.SendAlertToUser;
873
874 m_eventManager.OnSignificantClientMovement += HandleOnSignificantClientMovement;
873 } 875 }
874 876
875 public override string GetSimulatorVersion() 877 public override string GetSimulatorVersion()
@@ -5138,5 +5140,70 @@ namespace OpenSim.Region.Framework.Scenes
5138 reason = String.Empty; 5140 reason = String.Empty;
5139 return true; 5141 return true;
5140 } 5142 }
5143
5144 /// <summary>
5145 /// This method deals with movement when an avatar is automatically moving (but this is distinct from the
5146 /// autopilot that moves an avatar to a sit target!.
5147 /// </summary>
5148 /// <remarks>
5149 /// This is not intended as a permament location for this method.
5150 /// </remarks>
5151 /// <param name="presence"></param>
5152 private void HandleOnSignificantClientMovement(ScenePresence presence)
5153 {
5154 if (presence.MovingToTarget)
5155 {
5156 double distanceToTarget = Util.GetDistanceTo(presence.AbsolutePosition, presence.MoveToPositionTarget);
5157// m_log.DebugFormat(
5158// "[SCENE]: Abs pos of {0} is {1}, target {2}, distance {3}",
5159// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget, distanceToTarget);
5160
5161 // Check the error term of the current position in relation to the target position
5162 if (distanceToTarget <= ScenePresence.SIGNIFICANT_MOVEMENT)
5163 {
5164 // We are close enough to the target
5165// m_log.DebugFormat("[SCENEE]: Stopping autopilot of {0}", presence.Name);
5166
5167 presence.Velocity = Vector3.Zero;
5168 presence.AbsolutePosition = presence.MoveToPositionTarget;
5169 presence.ResetMoveToTarget();
5170
5171 if (presence.PhysicsActor.Flying)
5172 {
5173 // A horrible hack to stop the avatar dead in its tracks rather than having them overshoot
5174 // the target if flying.
5175 // We really need to be more subtle (slow the avatar as it approaches the target) or at
5176 // least be able to set collision status once, rather than 5 times to give it enough
5177 // weighting so that that PhysicsActor thinks it really is colliding.
5178 for (int i = 0; i < 5; i++)
5179 presence.PhysicsActor.IsColliding = true;
5180
5181// Vector3 targetPos = presence.MoveToPositionTarget;
5182// if (m_avatars[presence.UUID].LandAtTarget)
5183// presence.PhysicsActor.Flying = false;
5184
5185// float terrainHeight = (float)presence.Scene.Heightmap[(int)targetPos.X, (int)targetPos.Y];
5186// if (targetPos.Z - terrainHeight < 0.2)
5187// {
5188// presence.PhysicsActor.Flying = false;
5189// }
5190 }
5191
5192// m_log.DebugFormat(
5193// "[SCENE]: AgentControlFlags {0}, MovementFlag {1} for {2}",
5194// presence.AgentControlFlags, presence.MovementFlag, presence.Name);
5195 }
5196 else
5197 {
5198// m_log.DebugFormat(
5199// "[SCENE]: Updating npc {0} at {1} for next movement to {2}",
5200// presence.Name, presence.AbsolutePosition, presence.MoveToPositionTarget);
5201
5202 Vector3 agent_control_v3 = new Vector3();
5203 presence.HandleMoveToTargetUpdate(ref agent_control_v3);
5204 presence.AddNewMovement(agent_control_v3);
5205 }
5206 }
5207 }
5141 } 5208 }
5142} 5209}
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
new file mode 100644
index 0000000..5a85d7f
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAutopilotTests.cs
@@ -0,0 +1,135 @@
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.Reflection;
31using log4net;
32using Nini.Config;
33using NUnit.Framework;
34using OpenMetaverse;
35using OpenSim.Framework;
36using OpenSim.Framework.Communications;
37using OpenSim.Region.Framework.Interfaces;
38using OpenSim.Region.Framework.Scenes;
39using OpenSim.Tests.Common;
40using OpenSim.Tests.Common.Mock;
41
42namespace OpenSim.Region.Framework.Scenes.Tests
43{
44 [TestFixture]
45 public class ScenePresenceAutopilotTests
46 {
47 private TestScene m_scene;
48
49 [TestFixtureSetUp]
50 public void FixtureInit()
51 {
52 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
53 Util.FireAndForgetMethod = FireAndForgetMethod.None;
54 }
55
56 [TestFixtureTearDown]
57 public void TearDown()
58 {
59 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
60 // threads. Possibly, later tests should be rewritten not to worry about such things.
61 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
62 }
63
64 [SetUp]
65 public void Init()
66 {
67 m_scene = SceneHelpers.SetupScene();
68 }
69
70 [Test]
71 public void TestMove()
72 {
73 TestHelpers.InMethod();
74// log4net.Config.XmlConfigurator.Configure();
75
76 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1));
77
78 Vector3 startPos = sp.AbsolutePosition;
79// Vector3 startPos = new Vector3(128, 128, 30);
80
81 // For now, we'll make the scene presence fly to simplify this test, but this needs to change.
82 sp.PhysicsActor.Flying = true;
83
84 m_scene.Update();
85 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
86
87 Vector3 targetPos = startPos + new Vector3(0, 10, 0);
88 sp.MoveToTarget(targetPos, false);
89
90 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
91 Assert.That(
92 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001));
93
94 m_scene.Update();
95
96 // We should really check the exact figure.
97 Assert.That(sp.AbsolutePosition.X, Is.EqualTo(startPos.X));
98 Assert.That(sp.AbsolutePosition.Y, Is.GreaterThan(startPos.Y));
99 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
100 Assert.That(sp.AbsolutePosition.Z, Is.LessThan(targetPos.X));
101
102 for (int i = 0; i < 10; i++)
103 m_scene.Update();
104
105 double distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
106 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on first move");
107 Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
108 Assert.That(sp.AgentControlFlags, Is.EqualTo((uint)AgentManager.ControlFlags.NONE));
109
110 // Try a second movement
111 startPos = sp.AbsolutePosition;
112 targetPos = startPos + new Vector3(10, 0, 0);
113 sp.MoveToTarget(targetPos, false);
114
115 Assert.That(sp.AbsolutePosition, Is.EqualTo(startPos));
116 Assert.That(
117 sp.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001));
118
119 m_scene.Update();
120
121 // We should really check the exact figure.
122 Assert.That(sp.AbsolutePosition.X, Is.GreaterThan(startPos.X));
123 Assert.That(sp.AbsolutePosition.X, Is.LessThan(targetPos.X));
124 Assert.That(sp.AbsolutePosition.Y, Is.EqualTo(startPos.Y));
125 Assert.That(sp.AbsolutePosition.Z, Is.EqualTo(startPos.Z));
126
127 for (int i = 0; i < 10; i++)
128 m_scene.Update();
129
130 distanceToTarget = Util.GetDistanceTo(sp.AbsolutePosition, targetPos);
131 Assert.That(distanceToTarget, Is.LessThan(1), "Avatar not within 1 unit of target position on second move");
132 Assert.That(sp.AbsolutePosition, Is.EqualTo(targetPos));
133 }
134 }
135} \ No newline at end of file