diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index e722fa5..772b613 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -2941,28 +2941,40 @@ namespace OpenSim.Region.Framework.Scenes | |||
2941 | 2941 | ||
2942 | //Quaternion result = (sitTargetOrient * vq) * nq; | 2942 | //Quaternion result = (sitTargetOrient * vq) * nq; |
2943 | 2943 | ||
2944 | double x, y, z, m; | 2944 | double x, y, z, m1, m2; |
2945 | 2945 | ||
2946 | Quaternion r = sitTargetOrient; | 2946 | Quaternion r = sitTargetOrient; |
2947 | m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W; | 2947 | m1 = r.X * r.X + r.Y * r.Y; |
2948 | 2948 | m2 = r.Z * r.Z + r.W * r.W; | |
2949 | if (Math.Abs(1.0 - m) > 0.000001) | ||
2950 | { | ||
2951 | m = 1.0 / Math.Sqrt(m); | ||
2952 | r.X *= (float)m; | ||
2953 | r.Y *= (float)m; | ||
2954 | r.Z *= (float)m; | ||
2955 | r.W *= (float)m; | ||
2956 | } | ||
2957 | 2949 | ||
2950 | // Rotate the vector <0, 0, 1> | ||
2958 | x = 2 * (r.X * r.Z + r.Y * r.W); | 2951 | x = 2 * (r.X * r.Z + r.Y * r.W); |
2959 | y = 2 * (-r.X * r.W + r.Y * r.Z); | 2952 | y = 2 * (-r.X * r.W + r.Y * r.Z); |
2960 | z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W; | 2953 | z = m2 - m1; |
2954 | |||
2955 | // Set m to be the square of the norm of r. | ||
2956 | double m = m1 + m2; | ||
2957 | |||
2958 | // This constant is emperically determined to be what is used in SL. | ||
2959 | // See also http://opensimulator.org/mantis/view.php?id=7096 | ||
2960 | double offset = 0.05; | ||
2961 | |||
2962 | // Normally m will be ~ 1, but if someone passed a handcrafted quaternion | ||
2963 | // to llSitTarget with values so small that squaring them is rounded off | ||
2964 | // to zero, then m could be zero. The result of this floating point | ||
2965 | // round off error (causing us to skip this impossible normalization) | ||
2966 | // is only 5 cm. | ||
2967 | if (m > 0.000001) | ||
2968 | { | ||
2969 | offset /= m; | ||
2970 | } | ||
2961 | 2971 | ||
2962 | Vector3 up = new Vector3((float)x, (float)y, (float)z); | 2972 | Vector3 up = new Vector3((float)x, (float)y, (float)z); |
2963 | Vector3 sitOffset = up * Appearance.AvatarHeight * 0.02638f; | 2973 | Vector3 sitOffset = up * (float)offset; |
2964 | 2974 | ||
2965 | Vector3 newPos = sitTargetPos + sitOffset + SIT_TARGET_ADJUSTMENT; | 2975 | // sitOffset is in Avatar Center coordinates: from origin to 'sitTargetPos + SIT_TARGET_ADJUSTMENT'. |
2976 | // So, we need to _substract_ it to get to the origin of the Avatar Center. | ||
2977 | Vector3 newPos = sitTargetPos + SIT_TARGET_ADJUSTMENT - sitOffset; | ||
2966 | Quaternion newRot; | 2978 | Quaternion newRot; |
2967 | 2979 | ||
2968 | if (part.IsRoot) | 2980 | if (part.IsRoot) |