aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorTom Grimshaw2010-06-17 04:15:07 -0700
committerTom Grimshaw2010-06-17 04:15:07 -0700
commitd1c8b083b8d44417d67fb401646eaa7215ff0851 (patch)
tree771ee0b1562f5ab92f67432cb25f11264182dab7
parentFix llAttachToAvatar. This addresses mantis 128 . (diff)
downloadopensim-SC-d1c8b083b8d44417d67fb401646eaa7215ff0851.zip
opensim-SC-d1c8b083b8d44417d67fb401646eaa7215ff0851.tar.gz
opensim-SC-d1c8b083b8d44417d67fb401646eaa7215ff0851.tar.bz2
opensim-SC-d1c8b083b8d44417d67fb401646eaa7215ff0851.tar.xz
Fix llRot2Euler with a mathematically sound implementation. The only difference between this an SL is that SL resolves a figure of negative PI into PI, and does the equivalent in the reverse (llEuler2Rot, -1.0 becomes 1.0);
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs46
1 files changed, 27 insertions, 19 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 877c3cb..fe8c70e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -502,25 +502,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
502 return remainder; 502 return remainder;
503 } 503 }
504 504
505 // Old implementation of llRot2Euler, now normalized 505 public LSL_Vector llRot2Euler(LSL_Rotation q1)
506 506 {
507 public LSL_Vector llRot2Euler(LSL_Rotation r) 507 m_host.AddScriptLPS(1);
508 { 508 LSL_Vector eul = new LSL_Vector();
509 m_host.AddScriptLPS(1); 509
510 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 510 double sqw = q1.s*q1.s;
511 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 511 double sqx = q1.x*q1.x;
512 double m = (t.x + t.y + t.z + t.s); 512 double sqy = q1.z*q1.z;
513 if (m == 0) return new LSL_Vector(); 513 double sqz = q1.y*q1.y;
514 double n = 2 * (r.y * r.s + r.x * r.z); 514 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
515 double p = m * m - n * n; 515 double test = q1.x*q1.z + q1.y*q1.s;
516 if (p > 0) 516 if (test > 0.4999*unit) { // singularity at north pole
517 return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))), 517 eul.z = 2 * Math.Atan2(q1.x,q1.s);
518 NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), 518 eul.y = Math.PI/2;
519 NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); 519 eul.x = 0;
520 else if (n > 0) 520 return eul;
521 return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); 521 }
522 else 522 if (test < -0.4999*unit) { // singularity at south pole
523 return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); 523 eul.z = -2 * Math.Atan2(q1.x,q1.s);
524 eul.y = -Math.PI/2;
525 eul.x = 0;
526 return eul;
527 }
528 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
529 eul.y = Math.Asin(2*test/unit);
530 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
531 return eul;
524 } 532 }
525 533
526 /* From wiki: 534 /* From wiki: