aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs85
1 files changed, 49 insertions, 36 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index a005b01..1d7dcee 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -535,43 +535,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
535 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up) 535 public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
536 { 536 {
537 m_host.AddScriptLPS(1); 537 m_host.AddScriptLPS(1);
538 double x, y, z, s; 538 double s;
539 int f = 0; 539 double tr = fwd.x + left.y + up.z + 1.0;
540 // Important Note: q1=<x,y,z,s> is equal to q2=<-x,-y,-z,-s>
541 // Computing quaternion x,y,z,s values
542 x = ((fwd.x - left.y - up.z + 1) / 4);
543 x *= x;
544 x = Math.Sqrt(Math.Sqrt(x));
545 y = ((1 - up.z) / 2 - x * x);
546 y *= y;
547 y = Math.Sqrt(Math.Sqrt(y));
548 z = ((1 - left.y) / 2 - x * x);
549 z *= z;
550 z = Math.Sqrt(Math.Sqrt(z));
551 s = (1 - x * x - y * y - z * z);
552 s *= s;
553 s = Math.Sqrt(Math.Sqrt(s));
554
555 // Set f for signs detection
556 if (fwd.y + left.x >= 0) { f += 1; }
557 if (fwd.z + up.x >= 0) { f += 2; }
558 if (left.z - up.y >= 0) { f += 4; }
559 // Set correct quaternion signs based on f value
560 if (f == 0) { x = -x; }
561 if (f == 1) { x = -x; y = -y; }
562 if (f == 2) { x = -x; z = -z; }
563 if (f == 3) { s = -s; }
564 if (f == 4) { x = -x; s = -s; }
565 if (f == 5) { z = -z; }
566 if (f == 6) { y = -y; }
567
568 LSL_Rotation result = new LSL_Rotation(x, y, z, s);
569
570 // a hack to correct a few questionable angles :(
571 if (llVecDist(llRot2Fwd(result), fwd) > 0.001 || llVecDist(llRot2Left(result), left) > 0.001)
572 result.s = -s;
573 540
574 return result; 541 if (tr >= 1.0)
542 {
543 s = 0.5 / Math.Sqrt(tr);
544 return new LSL_Rotation(
545 (left.z - up.y) * s,
546 (up.x - fwd.z) * s,
547 (fwd.y - left.x) * s,
548 0.25 / s);
549 }
550 else
551 {
552 double max = (left.y > up.z) ? left.y : up.z;
553
554 if (max < fwd.x)
555 {
556 s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0);
557 double x = s * 0.5;
558 s = 0.5 / s;
559 return new LSL_Rotation(
560 x,
561 (fwd.y + left.x) * s,
562 (up.x + fwd.z) * s,
563 (left.z - up.y) * s);
564 }
565 else if (max == left.y)
566 {
567 s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0);
568 double y = s * 0.5;
569 s = 0.5 / s;
570 return new LSL_Rotation(
571 (fwd.y + left.x) * s,
572 y,
573 (left.z + up.y) * s,
574 (up.x - fwd.z) * s);
575 }
576 else
577 {
578 s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0);
579 double z = s * 0.5;
580 s = 0.5 / s;
581 return new LSL_Rotation(
582 (up.x + fwd.z) * s,
583 (left.z + up.y) * s,
584 z,
585 (fwd.y - left.x) * s);
586 }
587 }
575 } 588 }
576 589
577 public LSL_Vector llRot2Fwd(LSL_Rotation r) 590 public LSL_Vector llRot2Fwd(LSL_Rotation r)