From da5aad87bff6c42dc5dc2f8408dbc5a30f6d1abb Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Tue, 17 Nov 2015 17:41:09 +0000 Subject: [PATCH] start adding LegacySitOffsets option. TRUE will prevent the use of new math for the compensation of SL sittarget bug, and so not break content. (this is the main code change) --- OpenSim/Region/Framework/Scenes/Scene.cs | 9 +- .../Region/Framework/Scenes/ScenePresence.cs | 82 ++++++++++++++----- 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 837a9946b2..55c4fda45f 100755 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -228,7 +228,12 @@ namespace OpenSim.Region.Framework.Scenes public bool m_allowScriptCrossings = true; /// - + /// use legacy sittarget offsets to avoid contents breaks + /// to compensate for SL bug + /// + public bool LegacySitOffsets = true; + + /// /// Can avatars cross from and to this region? /// public bool AllowAvatarCrossing { get; set; } @@ -960,6 +965,8 @@ namespace OpenSim.Region.Framework.Scenes m_defaultDrawDistance = startupConfig.GetFloat("DefaultDrawDistance", m_defaultDrawDistance); m_maxDrawDistance = startupConfig.GetFloat("MaxDrawDistance", m_maxDrawDistance); + LegacySitOffsets = startupConfig.GetBoolean("LegacyOpenSimSitOffsets", LegacySitOffsets); + if (m_defaultDrawDistance > m_maxDrawDistance) m_defaultDrawDistance = m_maxDrawDistance; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c3deeaf37f..fd647e17e9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -144,6 +144,7 @@ namespace OpenSim.Region.Framework.Scenes /// issue #1716 /// public static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.4f); + public bool LegacySitOffsets = true; /// /// Movement updates for agents in neighboring regions are sent directly to clients. @@ -1003,6 +1004,7 @@ namespace OpenSim.Region.Framework.Scenes m_name = String.Format("{0} {1}", Firstname, Lastname); m_uuid = client.AgentId; LocalId = m_scene.AllocateLocalId(); + LegacySitOffsets = m_scene.LegacySitOffsets; UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); if (account != null) @@ -3211,30 +3213,72 @@ namespace OpenSim.Region.Framework.Scenes // "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", // Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); - //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); - //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); - - //Quaternion result = (sitTargetOrient * vq) * nq; - double x, y, z, m; - + Vector3 sitOffset; Quaternion r = sitTargetOrient; - 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) + if(LegacySitOffsets) { - m = 1.0 / Math.Sqrt(m); - r.X *= (float)m; - r.Y *= (float)m; - r.Z *= (float)m; - r.W *= (float)m; - } + double m1,m2; - 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 * Appearance.AvatarHeight * 0.02638f; + m1 = r.X * r.X + r.Y * r.Y; + m2 = r.Z * r.Z + r.W * r.W; + + // Rotate the vector <0, 0, 1> + x = 2 * (r.X * r.Z + r.Y * r.W); + y = 2 * (-r.X * r.W + r.Y * r.Z); + z = m2 - m1; + + // Set m to be the square of the norm of r. + m = m1 + m2; + + // This constant is emperically determined to be what is used in SL. + // See also http://opensimulator.org/mantis/view.php?id=7096 + double offset = 0.05; + + // Normally m will be ~ 1, but if someone passed a handcrafted quaternion + // to llSitTarget with values so small that squaring them is rounded off + // to zero, then m could be zero. The result of this floating point + // round off error (causing us to skip this impossible normalization) + // is only 5 cm. + if (m > 0.000001) + { + offset /= m; + } + + Vector3 up = new Vector3((float)x, (float)y, (float)z); + sitOffset = up * (float)offset; + } + else + { + 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) + { + if(m != 0) + { + m = 1.0 / Math.Sqrt(m); + r.X *= (float)m; + r.Y *= (float)m; + r.Z *= (float)m; + r.W *= (float)m; + } + else + { + r.X = 0.0f; + r.Y = 0.0f; + r.Z = 0.0f; + r.W = 1.0f; + m = 1.0f; + } + } + + 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); + sitOffset = up * Appearance.AvatarHeight * 0.02638f; + } Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT; Quaternion newRot;