diff options
3 files changed, 115 insertions, 6 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9358a4a..cd3cb60 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -585,7 +585,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
585 | public Quaternion Rotation | 585 | public Quaternion Rotation |
586 | { | 586 | { |
587 | get { return m_bodyRot; } | 587 | get { return m_bodyRot; } |
588 | set { m_bodyRot = value; } | 588 | set |
589 | { | ||
590 | m_bodyRot = value; | ||
591 | m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, m_bodyRot); | ||
592 | } | ||
589 | } | 593 | } |
590 | 594 | ||
591 | public Quaternion PreviousRotation | 595 | public Quaternion PreviousRotation |
@@ -1711,7 +1715,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1711 | 1715 | ||
1712 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is | 1716 | // Fudge factor. It appears that if one clicks "go here" on a piece of ground, the go here request is |
1713 | // always slightly higher than the actual terrain height. | 1717 | // always slightly higher than the actual terrain height. |
1714 | // FIXME: This constrains NOC movements as well, so should be somewhere else. | 1718 | // FIXME: This constrains NPC movements as well, so should be somewhere else. |
1715 | if (pos.Z - terrainHeight < 0.2) | 1719 | if (pos.Z - terrainHeight < 0.2) |
1716 | pos.Z = terrainHeight; | 1720 | pos.Z = terrainHeight; |
1717 | 1721 | ||
@@ -1727,6 +1731,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1727 | MovingToTarget = true; | 1731 | MovingToTarget = true; |
1728 | MoveToPositionTarget = pos; | 1732 | MoveToPositionTarget = pos; |
1729 | 1733 | ||
1734 | // Rotate presence around the z-axis to point in same direction as movement. | ||
1735 | // Ignore z component of vector | ||
1736 | Vector3 localVectorToTarget3D = pos - AbsolutePosition; | ||
1737 | Vector3 localVectorToTarget2D = new Vector3((float)(localVectorToTarget3D.X), (float)(localVectorToTarget3D.Y), 0f); | ||
1738 | |||
1739 | // m_log.DebugFormat("[SCENE PRESENCE]: Local vector to target is {0}", localVectorToTarget2D); | ||
1740 | |||
1741 | // Calculate the yaw. | ||
1742 | Vector3 angle = new Vector3(0, 0, (float)(Math.Atan2(localVectorToTarget2D.Y, localVectorToTarget2D.X))); | ||
1743 | |||
1744 | // m_log.DebugFormat("[SCENE PRESENCE]: Angle is {0}", angle); | ||
1745 | |||
1746 | Rotation = Quaternion.CreateFromEulers(angle); | ||
1747 | // m_log.DebugFormat("[SCENE PRESENCE]: Body rot for {0} set to {1}", Name, Rotation); | ||
1748 | |||
1730 | Vector3 agent_control_v3 = new Vector3(); | 1749 | Vector3 agent_control_v3 = new Vector3(); |
1731 | HandleMoveToTargetUpdate(ref agent_control_v3); | 1750 | HandleMoveToTargetUpdate(ref agent_control_v3); |
1732 | AddNewMovement(agent_control_v3); | 1751 | 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 | ||