From f6507b50b5053a7bb75a9175aab921590231200d Mon Sep 17 00:00:00 2001 From: Ricky C Date: Thu, 22 Nov 2018 23:28:32 -0800 Subject: [PATCH 1/3] fix!: Converts to SL-compatible sit targets An option is left to switch into the legacy mode for grids who wish to not break content. This means that this setting can be set per-region, which allows for a range of possibilities. The choice to default to SL-compat mode was made to facilitate new grids using this codebase: most scripts will be coming from SecondLife and it's really very annoying to have to fix them up - assuming the importer even knows how. BREAKING CHANGE: This changes an established behavior in the world, causing all Halcyon-specific sit script helpers to break, but allowing the ones coded for SL to work. --- .../Region/Framework/Scenes/ScenePresence.cs | 96 +++++++++++-------- bin/Halcyon.sample.ini | 7 ++ 2 files changed, 65 insertions(+), 38 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5860912b..1e1c7884 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -138,14 +138,11 @@ public class ScenePresence : EntityBase private Vector3 m_LastFinitePos; - // experimentally determined "fudge factor" to make sit-target positions - // the same as in SecondLife. Fudge factor was tested for 36 different - // test cases including prims of type box, sphere, cylinder, and torus, - // with varying parameters for sit target location, prim size, prim - // rotation, prim cut, prim twist, prim taper, and prim shear. See mantis - // issue #1716 - private bool ADJUST_SIT_TARGET = true; // do it the old OpenSim way for content compatibility - private static readonly Vector3 m_sitTargetCorrectionOffset = new Vector3(0.1f, 0.0f, 0.3f); + // Experimentally determined "fudge factor" to make sit-target positions the same as in SecondLife. + private Vector3 m_sitTargetCorrectionPrimSpaceOffset; + private Vector3 m_sitTargetCorrectionAgentSpaceOffset; + private readonly bool m_sitTargetCorrectionLegacyMath; + private float m_godlevel; private bool m_invulnerable = true; @@ -999,6 +996,31 @@ private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) if (m_connection != null) // can be null for bots which don't have a LLCV m_connection.ScenePresence = this; + var simulatorFeaturesConfig = world.Config.Configs["SimulatorFeatures"]; + var sitTargetSystem = simulatorFeaturesConfig.GetString("SitTargetCompatibilityMode", "SecondLife"); + switch (sitTargetSystem.Trim().Replace(" ", "").ToLower()) + { + case "legacy": + // experimentally determined "fudge factor" to make sit-target positions + // the same as in SecondLife. Fudge factor was tested for 36 different + // test cases including prims of type box, sphere, cylinder, and torus, + // with varying parameters for sit target location, prim size, prim + // rotation, prim cut, prim twist, prim taper, and prim shear. See mantis + // issue #1716 + + // Note from much farther in the future: the offsets from where this came from looked nothing like SL... + + m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.1f, 0.0f, 0.3f); + m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, 0.0f); + m_sitTargetCorrectionLegacyMath = true; + break; + case "secondlife": + m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.0f, 0.0f, 0.4f); + m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, -0.05f); + m_sitTargetCorrectionLegacyMath = false; + break; + } + // Prime (cache) the user's group list. m_scene.UserGroupsGet(this.UUID); } @@ -1318,7 +1340,7 @@ private void ContinueSitAsRootAgent(IClientAPI client, SceneObjectPart part, Vec if (m_avatarMovesWithPart) { Vector3 newPos = sitInfo.Offset; - newPos += m_sitTargetCorrectionOffset; + newPos += m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation; m_bodyRot = sitInfo.Rotation; //Rotation = sitTargetOrient; SetAgentPositionInfo(null, true, newPos, part, part.AbsolutePosition, Vector3.Zero); @@ -1564,7 +1586,7 @@ public void CompleteMovement() if (AvatarMovesWithPart && (m_requestedSitTargetID != 0)) { // now make it all consistent with updated parent ID while inside the lock - SetAgentPositionInfo(null, true, m_sitTargetCorrectionOffset, parent, pos, m_velocity); + SetAgentPositionInfo(null, true, m_sitTargetCorrectionPrimSpaceOffset, parent, pos, m_velocity); } } } @@ -2338,7 +2360,7 @@ public void StandUp(bool fromCrossing, bool recheckGroupForAutoreturn) { m_log.ErrorFormat("[SCENE PRESENCE]: StandUp for {0} with parentID={1} NOT FOUND in scene. Recovering position.", this.Name, (info.Parent == null) ? 0 : info.Parent.LocalId); // Recover, by emulating a default sit, for the code below. - info.Position = m_sitTargetCorrectionOffset + m_LastRegionPosition; + info.Position = m_sitTargetCorrectionPrimSpaceOffset + m_LastRegionPosition; } else { @@ -2446,7 +2468,7 @@ public void StandUp(bool fromCrossing, bool recheckGroupForAutoreturn) { // Can't find the prim they were on so put them back where they // were with the sit target on the poseball set with the offset. - newpos = partPos - (info.Position - m_sitTargetCorrectionOffset); + newpos = partPos - (info.Position - m_sitTargetCorrectionPrimSpaceOffset); } // And let's assume that the sit pos is roughly at vertical center of the avatar, and that when standing, @@ -2584,23 +2606,20 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off avSitRot *= part.RotationOffset; } - // Viewer seems to draw the avatar based on the hip position. - // If you don't include HipOffset (which is raising the avatar - // since it's normally negative), then the viewer will draw - // the avatar walking with toes underground/inside prim. - // Full updates were missing this, so a rebake would reproduce it. - // This adjustment gives the viewer the position it expects. - vPos.Z -= m_appearance.HipOffset; + if (m_sitTargetCorrectionLegacyMath) + { + // Viewer seems to draw the avatar based on the hip position. + // If you don't include HipOffset (which is raising the avatar + // since it's normally negative), then the viewer will draw + // the avatar walking with toes underground/inside prim. + // Full updates were missing this, so a rebake would reproduce it. + // This adjustment gives the viewer the position it expects. + vPos.Z -= m_appearance.HipOffset; + } if (sitInfo.IsActive) { - avSitPos += sitInfo.Offset; - if (ADJUST_SIT_TARGET) - { - // If we want to support previous IW sit target offsets, rather than SL-accurate sit targets, - // we need to apply the OpenSim sit target correction adjustment. - avSitPos += m_sitTargetCorrectionOffset; - } + avSitPos += sitInfo.Offset + m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation; avSitRot *= sitInfo.Rotation; vRot *= sitInfo.Rotation; } @@ -3338,13 +3357,16 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint return; } - // Viewer seems to draw the avatar based on the hip position. - // If you don't include HipOffset (which is raising the avatar - // since it's normally negative), then the viewer will draw - // the avatar walking with toes underground/inside prim. - // Full updates were missing this, so a rebake would reproduce it. - // This adjustment gives the viewer the position it expects. - vPos.Z -= m_appearance.HipOffset; + if (m_sitTargetCorrectionLegacyMath) + { + // Viewer seems to draw the avatar based on the hip position. + // If you don't include HipOffset (which is raising the avatar + // since it's normally negative), then the viewer will draw + // the avatar walking with toes underground/inside prim. + // Full updates were missing this, so a rebake would reproduce it. + // This adjustment gives the viewer the position it expects. + vPos.Z -= m_appearance.HipOffset; + } // Actual rotation is rootPart.RotationOffset * part.RotationOffset * part.SitTargetOrientation // but we need to specify it relative to the root prim. @@ -3357,13 +3379,11 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint if (sitInfo.Offset != Vector3.Zero) { vPos = sitInfo.Offset; // start with the sit target position - vPos.Z -= m_appearance.HipOffset; // reapply correction - if (ADJUST_SIT_TARGET) + if (m_sitTargetCorrectionLegacyMath) { - // If we want to support previous IW sit target offsets, rather than SL-accurate sit targets, - // we need to apply the OpenSim sit target correction adjustment. - vPos += m_sitTargetCorrectionOffset; + vPos.Z -= m_appearance.HipOffset; // reapply correction } + vPos += m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation; if (part != rootPart) // sitting on a child prim { diff --git a/bin/Halcyon.sample.ini b/bin/Halcyon.sample.ini index c3c9a4fc..20e99b54 100644 --- a/bin/Halcyon.sample.ini +++ b/bin/Halcyon.sample.ini @@ -541,6 +541,13 @@ ; Are mesh-based objects allowed on this region? ;MeshEnabled=true + ; Which sit target offset calculation to use. + ; "SecondLife" (Match SL as of Second Life Server 18.11.09.521593 and possibly much earlier.) + ; "Legacy" (Match the way Halcyon used it in InWorldz) + ; All other values cause the simulator to use no offsets at all. + ; Default is "SecondLife" + ;SitTargetCompatibilityMode="SecondLife" + [ChatLogModule] ; Enable or disable the serverside chat logging module as a whole. Unless a ; backend is set this doesn't do much. From 0d235d86f2ea18e95a38737002be4e7a825ac25d Mon Sep 17 00:00:00 2001 From: Ricky C Date: Sun, 25 Nov 2018 23:03:56 -0800 Subject: [PATCH 2/3] refactor: Differentiate three states in sit math Code currently handles three types of sit target math: SecondLife, Legacy, and None. This just makes that more obvious and allows me to do my next commit cleanly. --- .../Region/Framework/Scenes/ScenePresence.cs | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1e1c7884..63136bcf 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -141,7 +141,13 @@ public class ScenePresence : EntityBase // Experimentally determined "fudge factor" to make sit-target positions the same as in SecondLife. private Vector3 m_sitTargetCorrectionPrimSpaceOffset; private Vector3 m_sitTargetCorrectionAgentSpaceOffset; - private readonly bool m_sitTargetCorrectionLegacyMath; + private enum SitTargetCorrectionMode + { + None, + SecondLife, + Legacy, + } + private readonly SitTargetCorrectionMode m_sitTargetCorrectionMode; private float m_godlevel; @@ -1012,13 +1018,16 @@ private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.1f, 0.0f, 0.3f); m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, 0.0f); - m_sitTargetCorrectionLegacyMath = true; + m_sitTargetCorrectionMode = SitTargetCorrectionMode.Legacy; break; case "secondlife": m_sitTargetCorrectionPrimSpaceOffset = new Vector3(0.0f, 0.0f, 0.4f); m_sitTargetCorrectionAgentSpaceOffset = new Vector3(0.0f, 0.0f, -0.05f); - m_sitTargetCorrectionLegacyMath = false; + m_sitTargetCorrectionMode = SitTargetCorrectionMode.SecondLife; break; + default: + m_sitTargetCorrectionMode = SitTargetCorrectionMode.None; + break; } // Prime (cache) the user's group list. @@ -2606,7 +2615,7 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off avSitRot *= part.RotationOffset; } - if (m_sitTargetCorrectionLegacyMath) + if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy) { // Viewer seems to draw the avatar based on the hip position. // If you don't include HipOffset (which is raising the avatar @@ -3357,7 +3366,7 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint return; } - if (m_sitTargetCorrectionLegacyMath) + if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy) { // Viewer seems to draw the avatar based on the hip position. // If you don't include HipOffset (which is raising the avatar @@ -3379,7 +3388,7 @@ public void RecalcVisualPosition(out Vector3 vPos, out Quaternion vRot, out uint if (sitInfo.Offset != Vector3.Zero) { vPos = sitInfo.Offset; // start with the sit target position - if (m_sitTargetCorrectionLegacyMath) + if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.Legacy) { vPos.Z -= m_appearance.HipOffset; // reapply correction } From 4e598d9dcc86a72cd7d349f5bf433f29eaffd56c Mon Sep 17 00:00:00 2001 From: Ricky C Date: Sun, 25 Nov 2018 23:07:34 -0800 Subject: [PATCH 3/3] fix: Correct information sent in AvatarSitResponse This now matches SL's response to the same inputs as verified by reviewing the Alchemy Message Log response after setting up identical tests in both grids. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 63136bcf..829da5c4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2605,7 +2605,7 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off SceneObjectPart rootPart = part.ParentGroup.RootPart; vParentID = rootPart.UUID; // parentID to send to viewer, always the root prim vPos = Vector3.Zero; // viewer position of avatar relative to root prim - vRot = Quaternion.Identity; // viewer rotation of avatar relative to root prim + vRot = m_sitTargetCorrectionMode == SitTargetCorrectionMode.SecondLife ? rootPart.RotationOffset : Quaternion.Identity; // viewer rotation of avatar relative to root prim avSitPos = Vector3.Zero; avSitRot = rootPart.RotationOffset; @@ -2630,6 +2630,10 @@ private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 off { avSitPos += sitInfo.Offset + m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation; avSitRot *= sitInfo.Rotation; + if (m_sitTargetCorrectionMode == SitTargetCorrectionMode.SecondLife) + { + vPos += sitInfo.Offset + m_sitTargetCorrectionPrimSpaceOffset + m_sitTargetCorrectionAgentSpaceOffset * sitInfo.Rotation; + } vRot *= sitInfo.Rotation; } else