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
0.8.0.3
Justin Clark-Casey (justincc) 2014-04-03 23:20:37 +01:00
parent 6b1d09813e
commit aec723b955
2 changed files with 64 additions and 4 deletions

View File

@ -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;

View File

@ -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<ScenePresence> sittingAvatars = part.GetSittingAvatars();
@ -128,6 +135,36 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(m_sp.PhysicsActor, Is.Not.Null);
}
[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()
{
@ -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));