From aec723b9552322fd29413086be223e38298df92f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 3 Apr 2014 23:20:37 +0100 Subject: Fix sp.AbsolutePosition when agent is sitting on a child prim, which in turns fixes llDetectedPos(), llGetLinkPrimitiveParams() and similar functions. Add regression test for this case. In relation to http://opensimulator.org/mantis/view.php?id=7043 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../Scenes/Tests/ScenePresenceSitTests.cs | 66 +++++++++++++++++++++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a0b4019..6e613a7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -538,7 +538,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart sitPart = ParentPart; if (sitPart != null) - return sitPart.AbsolutePosition + (m_pos * sitPart.GetWorldRotation()); + return sitPart.ParentGroup.AbsolutePosition + (m_pos * sitPart.GetWorldRotation()); } return m_pos; diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index dcdec5c..03ea969 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs @@ -73,6 +73,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); Assert.That(part.GetSittingAvatars(), Is.Null); Assert.That(m_sp.ParentID, Is.EqualTo(0)); + Assert.AreEqual(startPos, m_sp.AbsolutePosition); } [Test] @@ -87,10 +88,16 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; + // We need to preserve this here because phys actor is removed by the sit. + Vector3 spPhysActorSize = m_sp.PhysicsActor.Size; m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); Assert.That(m_sp.PhysicsActor, Is.Null); + Assert.That( + m_sp.AbsolutePosition, + Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, spPhysActorSize.Z / 2))); + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); HashSet sittingAvatars = part.GetSittingAvatars(); @@ -129,6 +136,36 @@ namespace OpenSim.Region.Framework.Scenes.Tests } [Test] + public void TestSitAndStandWithNoSitTargetChildPrim() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + // Make sure we're within range to sit + Vector3 startPos = new Vector3(1, 1, 1); + m_sp.AbsolutePosition = startPos; + + SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene, 2, m_sp.UUID, "part", 0x10).Parts[1]; + part.OffsetPosition = new Vector3(2, 3, 4); + + // We need to preserve this here because phys actor is removed by the sit. + Vector3 spPhysActorSize = m_sp.PhysicsActor.Size; + m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); + + Assert.That( + m_sp.AbsolutePosition, + Is.EqualTo(part.AbsolutePosition + new Vector3(0, 0, spPhysActorSize.Z / 2))); + + m_sp.StandUp(); + + Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); + Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); + Assert.That(part.GetSittingAvatars(), Is.Null); + Assert.That(m_sp.ParentID, Is.EqualTo(0)); + Assert.That(m_sp.PhysicsActor, Is.Not.Null); + } + + [Test] public void TestSitAndStandWithSitTarget() { TestHelpers.InMethod(); @@ -145,9 +182,32 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(part.SitTargetAvatar, Is.EqualTo(m_sp.UUID)); Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); -// Assert.That( -// m_sp.AbsolutePosition, -// Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); + + // This section is copied from ScenePresence.HandleAgentSit(). Correctness is not guaranteed. + Quaternion r = part.SitTargetOrientation; + double x, y, z, m; + m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W; + + if (Math.Abs(1.0 - m) > 0.000001) + { + m = 1.0 / Math.Sqrt(m); + r.X *= (float)m; + r.Y *= (float)m; + r.Z *= (float)m; + r.W *= (float)m; + } + + x = 2 * (r.X * r.Z + r.Y * r.W); + y = 2 * (-r.X * r.W + r.Y * r.Z); + z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W; + + Vector3 up = new Vector3((float)x, (float)y, (float)z); + Vector3 sitOffset = up * m_sp.Appearance.AvatarHeight * 0.02638f; + // End of copied section. + + Assert.That( + m_sp.AbsolutePosition, + Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + sitOffset + ScenePresence.SIT_TARGET_ADJUSTMENT)); Assert.That(m_sp.PhysicsActor, Is.Null); Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); -- cgit v1.1