diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | 34 |
2 files changed, 32 insertions, 16 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d6316b2..a35e75f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -468,10 +468,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
468 | 468 | ||
469 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke | 469 | //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke |
470 | 470 | ||
471 | // Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf | 471 | /// <summary> |
472 | // to avoid issues with singularity and rounding with Y rotation of +/- PI/2 | 472 | /// Convert an LSL rotation to a Euler vector. |
473 | /// </summary> | ||
474 | /// <remarks> | ||
475 | /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf | ||
476 | /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2 | ||
477 | /// </remarks> | ||
478 | /// <param name="r"></param> | ||
479 | /// <returns></returns> | ||
473 | public LSL_Vector llRot2Euler(LSL_Rotation r) | 480 | public LSL_Vector llRot2Euler(LSL_Rotation r) |
474 | { | 481 | { |
482 | m_host.AddScriptLPS(1); | ||
483 | |||
475 | LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. | 484 | LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. |
476 | double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. | 485 | double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. |
477 | if (m == 0.0) return new LSL_Vector(); | 486 | if (m == 0.0) return new LSL_Vector(); |
@@ -482,6 +491,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
482 | // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation | 491 | // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation |
483 | v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0))); | 492 | v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0))); |
484 | double z = Math.Atan2(v.y, v.x); | 493 | double z = Math.Atan2(v.y, v.x); |
494 | |||
485 | return new LSL_Vector(x, y, z); | 495 | return new LSL_Vector(x, y, z); |
486 | } | 496 | } |
487 | 497 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs index 7594691..99c1cf4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs | |||
@@ -201,20 +201,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests | |||
201 | CheckllRot2Euler(new LSL_Types.Quaternion(-0.092302, -0.701059, -0.092302, -0.701059)); | 201 | CheckllRot2Euler(new LSL_Types.Quaternion(-0.092302, -0.701059, -0.092302, -0.701059)); |
202 | } | 202 | } |
203 | 203 | ||
204 | // Testing Rot2Euler this way instead of comparing against expected angles because | 204 | /// <summary> |
205 | // 1. There are several ways to get to the original Quaternion. For example a rotation | 205 | /// Check an llRot2Euler conversion. |
206 | // of PI and -PI will give the same result. But PI and -PI aren't equal. | 206 | /// </summary> |
207 | // 2. This method checks to see if the calculated angles from a quaternion can be used | 207 | /// <remarks> |
208 | // to create a new quaternion to produce the same rotation. | 208 | /// Testing Rot2Euler this way instead of comparing against expected angles because |
209 | // However, can't compare the newly calculated quaternion against the original because | 209 | /// 1. There are several ways to get to the original Quaternion. For example a rotation |
210 | // once again, there are multiple quaternions that give the same result. For instance | 210 | /// of PI and -PI will give the same result. But PI and -PI aren't equal. |
211 | // <X, Y, Z, S> == <-X, -Y, -Z, -S>. Additionally, the magnitude of S can be changed | 211 | /// 2. This method checks to see if the calculated angles from a quaternion can be used |
212 | // and will still result in the same rotation if the values for X, Y, Z are also changed | 212 | /// to create a new quaternion to produce the same rotation. |
213 | // to compensate. | 213 | /// However, can't compare the newly calculated quaternion against the original because |
214 | // However, if two quaternions represent the same rotation, then multiplying the first | 214 | /// once again, there are multiple quaternions that give the same result. For instance |
215 | // quaternion by the conjugate of the second, will give a third quaternion representing | 215 | /// <X, Y, Z, S> == <-X, -Y, -Z, -S>. Additionally, the magnitude of S can be changed |
216 | // a zero rotation. This can be tested for by looking at the X, Y, Z values which should | 216 | /// and will still result in the same rotation if the values for X, Y, Z are also changed |
217 | // be zero. | 217 | /// to compensate. |
218 | /// However, if two quaternions represent the same rotation, then multiplying the first | ||
219 | /// quaternion by the conjugate of the second, will give a third quaternion representing | ||
220 | /// a zero rotation. This can be tested for by looking at the X, Y, Z values which should | ||
221 | /// be zero. | ||
222 | /// </remarks> | ||
223 | /// <param name="rot"></param> | ||
218 | private void CheckllRot2Euler(LSL_Types.Quaternion rot) | 224 | private void CheckllRot2Euler(LSL_Types.Quaternion rot) |
219 | { | 225 | { |
220 | // Call LSL function to convert quaternion rotaion to euler radians. | 226 | // Call LSL function to convert quaternion rotaion to euler radians. |