aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs31
1 files changed, 13 insertions, 18 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 443e7a5..d6316b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -468,26 +468,21 @@ 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 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 471 // Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 472 // to avoid issues with singularity and rounding with Y rotation of +/- PI/2
473
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 473 public LSL_Vector llRot2Euler(LSL_Rotation r)
475 { 474 {
476 m_host.AddScriptLPS(1); 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.
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 476 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later.
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 477 if (m == 0.0) return new LSL_Vector();
479 double m = (t.x + t.y + t.z + t.s); 478 double x = Math.Atan2(-v.y, v.z);
480 if (m == 0) return new LSL_Vector(); 479 double sin = v.x / m;
481 double n = 2 * (r.y * r.s + r.x * r.z); 480 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
482 double p = m * m - n * n; 481 double y = Math.Asin(sin);
483 if (p > 0) 482 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 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)));
485 Math.Atan2(n, Math.Sqrt(p)), 484 double z = Math.Atan2(v.y, v.x);
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 485 return new LSL_Vector(x, y, z);
487 else if (n > 0)
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
489 else
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
491 } 486 }
492 487
493 /* From wiki: 488 /* From wiki: