aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs56
1 files changed, 54 insertions, 2 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 76c79da..1469e7e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -722,6 +722,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
722 { 722 {
723 //A and B should both be normalized 723 //A and B should both be normalized
724 m_host.AddScriptLPS(1); 724 m_host.AddScriptLPS(1);
725 /* This method is more accurate than the SL one, and thus causes problems
726 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
727
725 double dotProduct = LSL_Vector.Dot(a, b); 728 double dotProduct = LSL_Vector.Dot(a, b);
726 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 729 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
727 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b); 730 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
@@ -738,8 +741,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
738 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 741 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
739 742
740 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w); 743 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
741 } 744 */
742 745
746 // This method mimics the 180 errors found in SL
747 // See www.euclideanspace.com... angleBetween
748 LSL_Vector vec_a = a;
749 LSL_Vector vec_b = b;
750
751 // Eliminate zero length
752 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
753 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
754 if (vec_a_mag < 0.00001 ||
755 vec_b_mag < 0.00001)
756 {
757 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
758 }
759
760 // Normalize
761 vec_a = llVecNorm(vec_a);
762 vec_b = llVecNorm(vec_b);
763
764 // Calculate axis and rotation angle
765 LSL_Vector axis = vec_a % vec_b;
766 LSL_Float cos_theta = vec_a * vec_b;
767
768 // Check if parallel
769 if (cos_theta > 0.99999)
770 {
771 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
772 }
773
774 // Check if anti-parallel
775 else if (cos_theta < -0.99999)
776 {
777 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
778 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
779 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
780 }
781 else // other rotation
782 {
783 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
784 axis = llVecNorm(axis);
785 double x, y, z, s, t;
786 s = Math.Cos(theta);
787 t = Math.Sin(theta);
788 x = axis.x * t;
789 y = axis.y * t;
790 z = axis.z * t;
791 return new LSL_Rotation(x,y,z,s);
792 }
793 }
794
743 public void llWhisper(int channelID, string text) 795 public void llWhisper(int channelID, string text)
744 { 796 {
745 m_host.AddScriptLPS(1); 797 m_host.AddScriptLPS(1);