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.cs315
1 files changed, 145 insertions, 170 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f153504..b9b3318 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -562,23 +562,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
562 double sqx = q1.x*q1.x; 562 double sqx = q1.x*q1.x;
563 double sqy = q1.z*q1.z; 563 double sqy = q1.z*q1.z;
564 double sqz = q1.y*q1.y; 564 double sqz = q1.y*q1.y;
565 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor 565 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
566 double test = q1.x*q1.z + q1.y*q1.s; 566 double test = q1.x*q1.z + q1.y*q1.s;
567 if (test > 0.4999*unit) { // singularity at north pole 567 if (test > 0.4999*unit) { // singularity at north pole
568 eul.z = 2 * Math.Atan2(q1.x,q1.s); 568 eul.z = 2 * Math.Atan2(q1.x,q1.s);
569 eul.y = Math.PI/2; 569 eul.y = Math.PI/2;
570 eul.x = 0; 570 eul.x = 0;
571 return eul; 571 return eul;
572 } 572 }
573 if (test < -0.4999*unit) { // singularity at south pole 573 if (test < -0.4999*unit) { // singularity at south pole
574 eul.z = -2 * Math.Atan2(q1.x,q1.s); 574 eul.z = -2 * Math.Atan2(q1.x,q1.s);
575 eul.y = -Math.PI/2; 575 eul.y = -Math.PI/2;
576 eul.x = 0; 576 eul.x = 0;
577 return eul; 577 return eul;
578 } 578 }
579 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw); 579 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
580 eul.y = Math.Asin(2*test/unit); 580 eul.y = Math.Asin(2*test/unit);
581 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw); 581 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
582 return eul; 582 return eul;
583 } 583 }
584 584
@@ -804,53 +804,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
804 804
805 // This method mimics the 180 errors found in SL 805 // This method mimics the 180 errors found in SL
806 // See www.euclideanspace.com... angleBetween 806 // See www.euclideanspace.com... angleBetween
807 LSL_Vector vec_a = a; 807 LSL_Vector vec_a = a;
808 LSL_Vector vec_b = b; 808 LSL_Vector vec_b = b;
809 809
810 // Eliminate zero length 810 // Eliminate zero length
811 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); 811 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
812 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); 812 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
813 if (vec_a_mag < 0.00001 || 813 if (vec_a_mag < 0.00001 ||
814 vec_b_mag < 0.00001) 814 vec_b_mag < 0.00001)
815 { 815 {
816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
817 } 817 }
818 818
819 // Normalize 819 // Normalize
820 vec_a = llVecNorm(vec_a); 820 vec_a = llVecNorm(vec_a);
821 vec_b = llVecNorm(vec_b); 821 vec_b = llVecNorm(vec_b);
822 822
823 // Calculate axis and rotation angle 823 // Calculate axis and rotation angle
824 LSL_Vector axis = vec_a % vec_b; 824 LSL_Vector axis = vec_a % vec_b;
825 LSL_Float cos_theta = vec_a * vec_b; 825 LSL_Float cos_theta = vec_a * vec_b;
826 826
827 // Check if parallel 827 // Check if parallel
828 if (cos_theta > 0.99999) 828 if (cos_theta > 0.99999)
829 { 829 {
830 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 830 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
831 } 831 }
832 832
833 // Check if anti-parallel 833 // Check if anti-parallel
834 else if (cos_theta < -0.99999) 834 else if (cos_theta < -0.99999)
835 { 835 {
836 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); 836 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
837 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); 837 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
838 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); 838 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
839 } 839 }
840 else // other rotation 840 else // other rotation
841 { 841 {
842 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; 842 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
843 axis = llVecNorm(axis); 843 axis = llVecNorm(axis);
844 double x, y, z, s, t; 844 double x, y, z, s, t;
845 s = Math.Cos(theta); 845 s = Math.Cos(theta);
846 t = Math.Sin(theta); 846 t = Math.Sin(theta);
847 x = axis.x * t; 847 x = axis.x * t;
848 y = axis.y * t; 848 y = axis.y * t;
849 z = axis.z * t; 849 z = axis.z * t;
850 return new LSL_Rotation(x,y,z,s); 850 return new LSL_Rotation(x,y,z,s);
851 } 851 }
852 } 852 }
853 853
854 public void llWhisper(int channelID, string text) 854 public void llWhisper(int channelID, string text)
855 { 855 {
856 m_host.AddScriptLPS(1); 856 m_host.AddScriptLPS(1);
@@ -8647,130 +8647,105 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8647 8647
8648 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8648 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8649 { 8649 {
8650 int beginning = 0; 8650 int srclen = src.Length;
8651 int srclen = src.Length; 8651 int seplen = separators.Length;
8652 int seplen = separators.Length; 8652 object[] separray = separators.Data;
8653 object[] separray = separators.Data; 8653 int spclen = spacers.Length;
8654 int spclen = spacers.Length; 8654 object[] spcarray = spacers.Data;
8655 object[] spcarray = spacers.Data;
8656 int mlen = seplen+spclen;
8657 8655
8658 int[] offset = new int[mlen+1]; 8656 int outlen = 0;
8659 bool[] active = new bool[mlen]; 8657 LSL_String[] outarray = new LSL_String[srclen*2+1];
8660 8658
8661 int best; 8659 int i, j, lastUsed;
8662 int j;
8663
8664 // Initial capacity reduces resize cost
8665
8666 LSL_List tokens = new LSL_List();
8667 8660
8668 m_host.AddScriptLPS(1); 8661 m_host.AddScriptLPS(1);
8669 8662
8670 // All entries are initially valid 8663 /*
8671 8664 * Point to beginning of current non-delimeter string.
8672 for (int i = 0; i < mlen; i++) 8665 */
8673 active[i] = true; 8666 lastUsed = 0;
8674
8675 offset[mlen] = srclen;
8676
8677 while (beginning < srclen)
8678 {
8679
8680 best = mlen; // as bad as it gets
8681 8667
8682 // Scan for separators 8668 /*
8669 * Scan through source string from beginning to end.
8670 */
8671 for (i = 0; i < srclen;) {
8683 8672
8684 for (j = 0; j < seplen; j++) 8673 /*
8685 { 8674 * See if rest of string (starting at i) matches any separator.
8686 if (active[j]) 8675 */
8687 { 8676 string rest = src.Substring(i);
8688 // scan all of the markers 8677 for (j = 0; j < seplen; j ++) {
8689 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 8678 string sep = separray[j].ToString();
8690 { 8679 if ((sep.Length > 0) && rest.StartsWith(sep)) {
8691 // not present at all 8680
8692 active[j] = false; 8681 /*
8693 } 8682 * Separator matched, output string from end of last delimeter to beginning of this one.
8694 else 8683 */
8695 { 8684 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
8696 // present and correct 8685
8697 if (offset[j] < offset[best]) 8686 /*
8698 { 8687 * Remove separator from input string.
8699 // closest so far 8688 */
8700 best = j; 8689 i += sep.Length;
8701 if (offset[best] == beginning) 8690
8702 break; 8691 /*
8703 } 8692 * Next non-delimeter starts where this separator left off.
8704 } 8693 */
8694 lastUsed = i;
8695 goto nextsrc;
8705 } 8696 }
8706 } 8697 }
8707 8698
8708 // Scan for spacers 8699 /*
8709 8700 * See if rest of string (starting at i) matches any spacer.
8710 if (offset[best] != beginning) 8701 */
8711 { 8702 for (j = 0; j < spclen; j ++) {
8712 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8703 string spc = spcarray[j].ToString();
8713 { 8704 if ((spc.Length > 0) && rest.StartsWith(spc)) {
8714 if (active[j]) 8705
8715 { 8706 /*
8716 // scan all of the markers 8707 * Spacer matched, output string from end of last delimeter to beginning of this one.
8717 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8708 * Then output the spacer itself.
8718 { 8709 */
8719 // not present at all 8710 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
8720 active[j] = false; 8711 outarray[outlen++] = new LSL_String(spc);
8721 } 8712
8722 else 8713 /*
8723 { 8714 * Remove spacer from input string.
8724 // present and correct 8715 */
8725 if (offset[j] < offset[best]) 8716 i += spc.Length;
8726 { 8717
8727 // closest so far 8718 /*
8728 best = j; 8719 * Next non-delimeter starts where this spacer left off.
8729 } 8720 */
8730 } 8721 lastUsed = i;
8731 } 8722 goto nextsrc;
8732 } 8723 }
8733 } 8724 }
8734 8725
8735 // This is the normal exit from the scanning loop 8726 /*
8736 8727 * Didn't match any separator or spacer, skip over it and it
8737 if (best == mlen) 8728 * becomes part of the non-delimeter string starting with
8738 { 8729 * lastUsed.
8739 // no markers were found on this pass 8730 */
8740 // so we're pretty much done 8731 i ++;
8741 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); 8732 nextsrc:;
8742 break;
8743 }
8744
8745 // Otherwise we just add the newly delimited token
8746 // and recalculate where the search should continue.
8747
8748 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning)));
8749
8750 if (best < seplen)
8751 {
8752 beginning = offset[best] + (separray[best].ToString()).Length;
8753 }
8754 else
8755 {
8756 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8757 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8758 }
8759 } 8733 }
8760 8734
8761 // This an awkward an not very intuitive boundary case. If the 8735 /*
8762 // last substring is a tokenizer, then there is an implied trailing 8736 * Output last non-delimeter (including a possible null string if
8763 // null list entry. Hopefully the single comparison will not be too 8737 * delimeter ran to end of source string).
8764 // arduous. Alternatively the 'break' could be replced with a return 8738 */
8765 // but that's shabby programming. 8739 outarray[outlen++] = new LSL_String(src.Substring(lastUsed));
8766 8740
8767 if (beginning == srclen) 8741 /*
8768 { 8742 * Make up an exact-sized output array suitable for an LSL_List object.
8769 if (srclen != 0) 8743 */
8770 tokens.Add(new LSL_String("")); 8744 object[] outlist = new object[outlen];
8745 for (i = 0; i < outlen; i ++) {
8746 outlist[i] = outarray[i];
8771 } 8747 }
8772 8748 return new LSL_List(outlist);
8773 return tokens;
8774 } 8749 }
8775 8750
8776 public LSL_Integer llGetObjectPermMask(int mask) 8751 public LSL_Integer llGetObjectPermMask(int mask)