aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs176
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs3
3 files changed, 174 insertions, 9 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
index eb2bcb0..95acd23 100644
--- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
@@ -1044,9 +1044,9 @@ namespace OpenSim.Region.ScriptEngine.Common
1044 return m_LSL_Functions.llRot2Axis(rot); 1044 return m_LSL_Functions.llRot2Axis(rot);
1045 } 1045 }
1046 1046
1047 public void llRot2Angle() 1047 public double llRot2Angle(LSL_Types.Quaternion rot)
1048 { 1048 {
1049 m_LSL_Functions.llRot2Angle(); 1049 return m_LSL_Functions.llRot2Angle(rot);
1050 } 1050 }
1051 1051
1052 public double llAcos(double val) 1052 public double llAcos(double val)
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index 4e7d5ef..e29ee5a 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -283,6 +283,41 @@ namespace OpenSim.Region.ScriptEngine.Common
283 } 283 }
284 284
285 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 285 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
286
287 // Xantor's new llRot2Euler
288 public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r)
289 {
290 m_host.AddScriptLPS(1);
291 double x, y, z;
292 double sqw = r.s*r.s;
293 double sqx = r.x*r.x;
294 double sqy = r.y*r.y;
295 double sqz = r.z*r.z;
296 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
297 double test = r.x*r.y + r.z*r.s;
298 if (test > 0.499 * unit) // singularity at north pole
299 {
300 x = 0;
301 y = 2 * Math.Atan2(r.x, r.s);
302 z = Math.PI/2;
303 return new LSL_Types.Vector3(x, y, z);
304 }
305 if (test < -0.499 * unit) // singularity at south pole
306 {
307 x = 0;
308 y = -2 * Math.Atan2(r.x,r.s);
309 z = -Math.PI/2;
310 return new LSL_Types.Vector3(x, y, z);
311 }
312 x = Math.Atan2(2 * r.x * r.s - 2 * r.y * r.z, -sqx + sqy - sqz + sqw);
313 y = Math.Atan2(2*r.y*r.s-2*r.x*r.z , sqx - sqy - sqz + sqw);
314 z = Math.Asin(2*test/unit);
315 return new LSL_Types.Vector3(x, y, z);
316 }
317
318
319 // Old implementation of llRot2Euler
320 /*
286 public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r) 321 public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r)
287 { 322 {
288 m_host.AddScriptLPS(1); 323 m_host.AddScriptLPS(1);
@@ -301,7 +336,42 @@ namespace OpenSim.Region.ScriptEngine.Common
301 else 336 else
302 return new LSL_Types.Vector3(0.0, -Math.PI / 2, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 337 return new LSL_Types.Vector3(0.0, -Math.PI / 2, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
303 } 338 }
339 */
340
341 // Xantor's new llEuler2Rot()
342 /* From wiki:
343 The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes
344 in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation,
345 a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting
346 vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis.
347 */
348 public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v)
349 {
350 m_host.AddScriptLPS(1);
351
352 double x,y,z,s;
353
354 double c1 = Math.Cos(v.y / 2);
355 double s1 = Math.Sin(v.y / 2 );
356 double c2 = Math.Cos(v.z / 2 );
357 double s2 = Math.Sin(v.z / 2 );
358 double c3 = Math.Cos(v.x / 2 );
359 double s3 = Math.Sin(v.x / 2 );
360
361 double c1c2 = c1 * c2;
362 double s1s2 = s1 * s2;
363
364 s = c1c2 * c3 - s1s2 * s3;
365 x = c1c2 * s3 + s1s2 * c3;
366 y = s1 * c2 * c3 + c1 * s2 * s3;
367 z = c1 * s2 * c3 - s1 * c2 * s3;
304 368
369 return new LSL_Types.Quaternion(x, y, z, s);
370 }
371
372
373 /*
374 // Old implementation
305 public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v) 375 public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v)
306 { 376 {
307 m_host.AddScriptLPS(1); 377 m_host.AddScriptLPS(1);
@@ -337,6 +407,9 @@ namespace OpenSim.Region.ScriptEngine.Common
337 } 407 }
338 return a; 408 return a;
339 } 409 }
410
411 */
412
340 413
341 public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) 414 public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up)
342 { 415 {
@@ -2721,24 +2794,115 @@ namespace OpenSim.Region.ScriptEngine.Common
2721 return 0; 2794 return 0;
2722 } 2795 }
2723 2796
2797
2798 /* The new / changed functions were tested with the following LSL script:
2799
2800 default
2801 {
2802 state_entry()
2803 {
2804 rotation rot = llEuler2Rot(<0,70,0> * DEG_TO_RAD);
2805
2806 llOwnerSay("to get here, we rotate over: "+ (string) llRot2Axis(rot) );
2807 llOwnerSay("and we rotate for: "+ (llRot2Angle(rot) * RAD_TO_DEG));
2808
2809 // convert back and forth between quaternion <-> vector and angle
2810
2811 rotation newrot = llAxisAngle2Rot(llRot2Axis(rot),llRot2Angle(rot));
2812
2813 llOwnerSay("Old rotation was: "+(string) rot);
2814 llOwnerSay("re-converted rotation is: "+(string) newrot);
2815
2816 llSetRot(rot); // to check the parameters in the prim
2817 }
2818 }
2819 */
2820
2821
2822
2823 // Xantor 29/apr/2008
2824 // Returns rotation described by rotating angle radians about axis.
2825 // q = cos(a/2) + i ( x * sin(a/2)) + j (y * sin(a/2)) + k ( z * sin(a/2))
2724 public LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle) 2826 public LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle)
2725 { 2827 {
2726 m_host.AddScriptLPS(1); 2828 m_host.AddScriptLPS(1);
2727 NotImplemented("llAxisAngle2Rot"); 2829
2728 return new LSL_Types.Quaternion(); 2830 double x, y, z, s, t;
2831
2832 s = Math.Cos(angle / 2);
2833 t = Math.Sin(angle / 2); // temp value to avoid 2 more sin() calcs
2834 x = axis.x * t;
2835 y = axis.y * t;
2836 z = axis.z * t;
2837
2838 return new LSL_Types.Quaternion(x,y,z,s);
2839 // NotImplemented("llAxisAngle2Rot");
2729 } 2840 }
2730 2841
2842
2843 // Xantor 29/apr/2008
2844 // converts a Quaternion to X,Y,Z axis rotations
2731 public LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot) 2845 public LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot)
2732 { 2846 {
2733 m_host.AddScriptLPS(1); 2847 m_host.AddScriptLPS(1);
2734 NotImplemented("llRot2Axis"); 2848 double x,y,z;
2735 return new LSL_Types.Vector3(); 2849
2850 if (rot.s > 1) // normalization needed
2851 {
2852 double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
2853 rot.z * rot.z + rot.s * rot.s);
2854
2855 rot.x /= length;
2856 rot.y /= length;
2857 rot.z /= length;
2858 rot.s /= length;
2859
2860 }
2861
2862 double angle = 2 * Math.Acos(rot.s);
2863 double s = Math.Sqrt(1 - rot.s * rot.s);
2864 if (s < 0.001)
2865 {
2866 x = 1;
2867 y = z = 0;
2868 }
2869 else
2870 {
2871 x = rot.x / s; // normalise axis
2872 y = rot.y / s;
2873 z = rot.z / s;
2874 }
2875
2876
2877 return new LSL_Types.Vector3(x,y,z);
2878
2879
2880// NotImplemented("llRot2Axis");
2736 } 2881 }
2737 2882
2738 public void llRot2Angle() 2883
2884 // Returns the angle of a quaternion (see llRot2Axis for the axis)
2885 public double llRot2Angle(LSL_Types.Quaternion rot)
2739 { 2886 {
2740 m_host.AddScriptLPS(1); 2887 m_host.AddScriptLPS(1);
2741 NotImplemented("llRot2Angle"); 2888
2889 if (rot.s > 1) // normalization needed
2890 {
2891 double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
2892 rot.z * rot.z + rot.s * rot.s);
2893
2894 rot.x /= length;
2895 rot.y /= length;
2896 rot.z /= length;
2897 rot.s /= length;
2898
2899 }
2900
2901 double angle = 2 * Math.Acos(rot.s);
2902
2903 return angle;
2904
2905// NotImplemented("llRot2Angle");
2742 } 2906 }
2743 2907
2744 public double llAcos(double val) 2908 public double llAcos(double val)
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs
index 2f58437..ab9f463 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs
@@ -323,7 +323,8 @@ namespace OpenSim.Region.ScriptEngine.Common
323 LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle); 323 LSL_Types.Quaternion llAxisAngle2Rot(LSL_Types.Vector3 axis, double angle);
324 //wiki: vector llRot2Axis(rotation rot) 324 //wiki: vector llRot2Axis(rotation rot)
325 LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot); 325 LSL_Types.Vector3 llRot2Axis(LSL_Types.Quaternion rot);
326 void llRot2Angle(); 326 //wiki: double llRot2Angle(rotation rot);
327 double llRot2Angle(LSL_Types.Quaternion rot);
327 //wiki: double llAcos(double val) 328 //wiki: double llAcos(double val)
328 double llAcos(double val); 329 double llAcos(double val);
329 //wiki: double llAsin(double val) 330 //wiki: double llAsin(double val)