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()