diff options
author | Tom Grimshaw | 2010-06-17 04:15:07 -0700 |
---|---|---|
committer | Tom Grimshaw | 2010-06-17 04:15:07 -0700 |
commit | d1c8b083b8d44417d67fb401646eaa7215ff0851 (patch) | |
tree | 771ee0b1562f5ab92f67432cb25f11264182dab7 | |
parent | Fix llAttachToAvatar. This addresses mantis 128 . (diff) | |
download | opensim-SC_OLD-d1c8b083b8d44417d67fb401646eaa7215ff0851.zip opensim-SC_OLD-d1c8b083b8d44417d67fb401646eaa7215ff0851.tar.gz opensim-SC_OLD-d1c8b083b8d44417d67fb401646eaa7215ff0851.tar.bz2 opensim-SC_OLD-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.cs | 46 |
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: |