aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs34
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.