From c9415fd76378af35ff76037d46245f2b95e4264f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Wed, 5 Mar 2014 00:35:02 +0000 Subject: [PATCH] If an avatar is sitting, send out position updates to clients for any change, not just those outside the usual tolerances. This is to allow small adjustments of less than 0.05m in functions such as llSetPrimitiveLinkParams() to work This is another fix for http://opensimulator.org/mantis/view.php?id=7044 Extends regression test for this case. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- .../Region/Framework/Scenes/ScenePresence.cs | 16 ++++++++-- .../Shared/Tests/LSL_ApiAvatarTests.cs | 32 ++++++++++++++++++- OpenSim/Tests/Common/Mock/TestClient.cs | 3 ++ 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f7fd767b81..fa90ef4afa 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1495,7 +1495,7 @@ namespace OpenSim.Region.Framework.Scenes // Objects queue their updates onto all scene presences if (Frame % m_update_objects == 0) m_sceneGraph.UpdateObjectGroups(); - + // Run through all ScenePresences looking for updates // Presence updates and queued object updates for each presence are sent to clients if (Frame % m_update_presences == 0) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d4af9fc11f..c8971c4d47 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3084,9 +3084,19 @@ namespace OpenSim.Region.Framework.Scenes if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn) SendAvatarDataToAllAgents(); - if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + // Allow any updates for sitting avatars to that llSetPrimitiveLinkParams() can work for very + // small increments (e.g. sit position adjusters). An alternative may be to eliminate the tolerance + // checks on all updates but the ramifications of this would need careful consideration. + bool updateClients + = IsSatOnObject && (Rotation != m_lastRotation || Velocity != m_lastVelocity || m_pos != m_lastPosition); + + if (!updateClients) + updateClients + = !Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) + || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) + || !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE); + + if (updateClients) { SendTerseUpdateToAllClients(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs index 86381c40cc..14159251b9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiAvatarTests.cs @@ -77,14 +77,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests m_engine.AddRegion(m_scene); } + /// + /// Test llSetLinkPrimtiveParams for agents. + /// + /// + /// Also testing entity updates here as well. Possibly that's putting 2 different concerns into one test and + /// this should be separated. + /// [Test] public void TestllSetLinkPrimitiveParamsForAgent() { TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); - new SceneHelpers().SetupScene(); SceneObjectPart part = SceneHelpers.AddSceneObject(m_scene).RootPart; part.RotationOffset = new Quaternion(0.7071068f, 0, 0, 0.7071068f); @@ -99,12 +106,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests sp.HandleAgentRequestSit(sp.ControllingClient, sp.UUID, part.UUID, Vector3.Zero); + int entityUpdates = 0; + ((TestClient)sp.ControllingClient).OnReceivedEntityUpdate += (entity, flags) => { if (entity is ScenePresence) { entityUpdates++; }}; + // Test position { Vector3 newPos = new Vector3(1, 2, 3); apiGrp1.llSetLinkPrimitiveParams(2, new LSL_Types.list(ScriptBaseClass.PRIM_POSITION, newPos)); Assert.That(sp.OffsetPosition, Is.EqualTo(newPos)); + + m_scene.Update(1); + Assert.That(entityUpdates, Is.EqualTo(1)); + } + + // Test small reposition + { + Vector3 newPos = new Vector3(1.001f, 2, 3); + apiGrp1.llSetLinkPrimitiveParams(2, new LSL_Types.list(ScriptBaseClass.PRIM_POSITION, newPos)); + + Assert.That(sp.OffsetPosition, Is.EqualTo(newPos)); + + m_scene.Update(1); + Assert.That(entityUpdates, Is.EqualTo(2)); } // Test world rotation @@ -114,6 +138,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.That( sp.Rotation, new QuaternionToleranceConstraint(part.GetWorldRotation() * newRot, 0.000001)); + + m_scene.Update(1); + Assert.That(entityUpdates, Is.EqualTo(3)); } // Test local rotation @@ -123,6 +150,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests Assert.That( sp.Rotation, new QuaternionToleranceConstraint(newRot, 0.000001)); + + m_scene.Update(1); + Assert.That(entityUpdates, Is.EqualTo(4)); } } } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 09ff531934..c2b0935788 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -62,6 +62,7 @@ namespace OpenSim.Tests.Common.Mock public event Action OnReceivedMoveAgentIntoRegion; public event Action OnTestClientInformClientOfNeighbour; public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport; + public event Action OnReceivedEntityUpdate; public event Action OnReceivedInstantMessage; public event Action OnReceivedSendRebakeAvatarTextures; @@ -685,6 +686,8 @@ namespace OpenSim.Tests.Common.Mock public void SendEntityUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { + if (OnReceivedEntityUpdate != null) + OnReceivedEntityUpdate(entity, updateFlags); } public void ReprioritizeUpdates()