diff options
3 files changed, 110 insertions, 5 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fc8f8b9..95d06fe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1863,7 +1863,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1863 | 1863 | ||
1864 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is | 1864 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is |
1865 | // always slightly higher than the actual terrain height. | 1865 | // always slightly higher than the actual terrain height. |
1866 | // FIXME: This constrains NOC movements as well, so should be somewhere else. | 1866 | // FIXME: This constrains NPC movements as well, so should be somewhere else. |
1867 | if (pos.Z - terrainHeight < 0.2) | 1867 | if (pos.Z - terrainHeight < 0.2) |
1868 | pos.Z = terrainHeight; | 1868 | pos.Z = terrainHeight; |
1869 | 1869 | ||
@@ -1879,6 +1879,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1879 | MovingToTarget = true; | 1879 | MovingToTarget = true; |
1880 | MoveToPositionTarget = pos; | 1880 | MoveToPositionTarget = pos; |
1881 | 1881 | ||
1882 | // Rotate presence around the z-axis to point in same direction as movement. | ||
1883 | // Ignore z component of vector | ||
1884 | Vector3 localVectorToTarget3D = pos - AbsolutePosition; | ||
1885 | Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f); | ||
1886 | |||
1887 | // m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D); | ||
1888 | |||
1889 | // Calculate the yaw. | ||
1890 | Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X))); | ||
1891 | |||
1892 | // m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle); | ||
1893 | |||
1894 | Rotation = Quaternion.CreateFromEulers(angle); | ||
1895 | // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); | ||
1896 | |||
1882 | Vector3 agent_control_v3 = new Vector3(); | 1897 | Vector3 agent_control_v3 = new Vector3(); |
1883 | HandleMoveToTargetUpdate(ref agent_control_v3); | 1898 | HandleMoveToTargetUpdate(ref agent_control_v3); |
1884 | AddNewMovement(agent_control_v3); | 1899 | AddNewMovement(agent_control_v3); |
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs index 246bc34..1a0d0c7 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs | |||
@@ -182,18 +182,21 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
182 | scene.Update(); | 182 | scene.Update(); |
183 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | 183 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); |
184 | 184 | ||
185 | Vector3 targetPos = startPos + new Vector3(0, 0, 10); | 185 | Vector3 targetPos = startPos + new Vector3(0, 10, 0); |
186 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); | 186 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); |
187 | 187 | ||
188 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | 188 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); |
189 | //Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0.7071068f, 0.7071068f))); | ||
190 | Assert.That( | ||
191 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0.7071068f, 0.7071068f), 0.000001)); | ||
189 | 192 | ||
190 | scene.Update(); | 193 | scene.Update(); |
191 | 194 | ||
192 | // We should really check the exact figure. | 195 | // We should really check the exact figure. |
193 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); | 196 | Assert.That(npc.AbsolutePosition.X, Is.EqualTo(startPos.X)); |
194 | Assert.That(npc.AbsolutePosition.Y, Is.EqualTo(startPos.Y)); | 197 | Assert.That(npc.AbsolutePosition.Y, Is.GreaterThan(startPos.Y)); |
195 | Assert.That(npc.AbsolutePosition.Z, Is.GreaterThan(startPos.Z)); | 198 | Assert.That(npc.AbsolutePosition.Z, Is.EqualTo(startPos.Z)); |
196 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.Z)); | 199 | Assert.That(npc.AbsolutePosition.Z, Is.LessThan(targetPos.X)); |
197 | 200 | ||
198 | for (int i = 0; i < 10; i++) | 201 | for (int i = 0; i < 10; i++) |
199 | scene.Update(); | 202 | scene.Update(); |
@@ -208,6 +211,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests | |||
208 | targetPos = startPos + new Vector3(10, 0, 0); | 211 | targetPos = startPos + new Vector3(10, 0, 0); |
209 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); | 212 | npcModule.MoveToTarget(npc.UUID, scene, targetPos, false, false); |
210 | 213 | ||
214 | Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); | ||
215 | // Assert.That(npc.Rotation, Is.EqualTo(new Quaternion(0, 0, 0, 1))); | ||
216 | Assert.That( | ||
217 | npc.Rotation, new QuaternionToleranceConstraint(new Quaternion(0, 0, 0, 1), 0.000001)); | ||
218 | |||
211 | scene.Update(); | 219 | scene.Update(); |
212 | 220 | ||
213 | // We should really check the exact figure. | 221 | // We should really check the exact figure. |
diff --git a/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs b/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs new file mode 100644 index 0000000..b38c382 --- /dev/null +++ b/OpenSim/Tests/Common/QuaternionToleranceConstraint.cs | |||
@@ -0,0 +1,82 @@ | |||
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 | |||
28 | using System; | ||
29 | using OpenMetaverse; | ||
30 | using NUnit.Framework; | ||
31 | using NUnit.Framework.Constraints; | ||
32 | |||
33 | namespace OpenSim.Tests.Common | ||
34 | { | ||
35 | public class QuaternionToleranceConstraint : ANumericalToleranceConstraint | ||
36 | { | ||
37 | private Quaternion _baseValue; | ||
38 | private Quaternion _valueToBeTested; | ||
39 | |||
40 | public QuaternionToleranceConstraint(Quaternion baseValue, double tolerance) : base(tolerance) | ||
41 | { | ||
42 | _baseValue = baseValue; | ||
43 | } | ||
44 | |||
45 | /// <summary> | ||
46 | /// Test whether the constraint is satisfied by a given value | ||
47 | /// </summary> | ||
48 | /// <param name="valueToBeTested">The value to be tested</param> | ||
49 | /// <returns> | ||
50 | /// True for success, false for failure | ||
51 | /// </returns> | ||
52 | public override bool Matches(object valueToBeTested) | ||
53 | { | ||
54 | if (valueToBeTested == null) | ||
55 | { | ||
56 | throw new ArgumentException("Constraint cannot be used upon null values."); | ||
57 | } | ||
58 | if (valueToBeTested.GetType() != typeof (Quaternion)) | ||
59 | { | ||
60 | throw new ArgumentException("Constraint cannot be used upon non quaternion values."); | ||
61 | } | ||
62 | |||
63 | _valueToBeTested = (Quaternion)valueToBeTested; | ||
64 | |||
65 | return (IsWithinDoubleConstraint(_valueToBeTested.X, _baseValue.X) && | ||
66 | IsWithinDoubleConstraint(_valueToBeTested.Y, _baseValue.Y) && | ||
67 | IsWithinDoubleConstraint(_valueToBeTested.Z, _baseValue.Z) && | ||
68 | IsWithinDoubleConstraint(_valueToBeTested.W, _baseValue.W)); | ||
69 | } | ||
70 | |||
71 | public override void WriteDescriptionTo(MessageWriter writer) | ||
72 | { | ||
73 | writer.WriteExpectedValue( | ||
74 | string.Format("A value {0} within tolerance of plus or minus {1}", _baseValue, _tolerance)); | ||
75 | } | ||
76 | |||
77 | public override void WriteActualValueTo(MessageWriter writer) | ||
78 | { | ||
79 | writer.WriteActualValue(_valueToBeTested); | ||
80 | } | ||
81 | } | ||
82 | } \ No newline at end of file | ||