aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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 fb191e6..1459778 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);
@@ -8627,130 +8627,105 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8627 8627
8628 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8628 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8629 { 8629 {
8630 int beginning = 0; 8630 int srclen = src.Length;
8631 int srclen = src.Length; 8631 int seplen = separators.Length;
8632 int seplen = separators.Length; 8632 object[] separray = separators.Data;
8633 object[] separray = separators.Data; 8633 int spclen = spacers.Length;
8634 int spclen = spacers.Length; 8634 object[] spcarray = spacers.Data;
8635 object[] spcarray = spacers.Data;
8636 int mlen = seplen+spclen;
8637 8635
8638 int[] offset = new int[mlen+1]; 8636 int outlen = 0;
8639 bool[] active = new bool[mlen]; 8637 LSL_String[] outarray = new LSL_String[srclen*2+1];
8640 8638
8641 int best; 8639 int i, j, lastUsed;
8642 int j;
8643
8644 // Initial capacity reduces resize cost
8645
8646 LSL_List tokens = new LSL_List();
8647 8640
8648 m_host.AddScriptLPS(1); 8641 m_host.AddScriptLPS(1);
8649 8642
8650 // All entries are initially valid 8643 /*
8651 8644 * Point to beginning of current non-delimeter string.
8652 for (int i = 0; i < mlen; i++) 8645 */
8653 active[i] = true; 8646 lastUsed = 0;
8654
8655 offset[mlen] = srclen;
8656
8657 while (beginning < srclen)
8658 {
8659
8660 best = mlen; // as bad as it gets
8661 8647
8662 // Scan for separators 8648 /*
8649 * Scan through source string from beginning to end.
8650 */
8651 for (i = 0; i < srclen;) {
8663 8652
8664 for (j = 0; j < seplen; j++) 8653 /*
8665 { 8654 * See if rest of string (starting at i) matches any separator.
8666 if (active[j]) 8655 */
8667 { 8656 string rest = src.Substring(i);
8668 // scan all of the markers 8657 for (j = 0; j < seplen; j ++) {
8669 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 8658 string sep = separray[j].ToString();
8670 { 8659 if ((sep.Length > 0) && rest.StartsWith(sep)) {
8671 // not present at all 8660
8672 active[j] = false; 8661 /*
8673 } 8662 * Separator matched, output string from end of last delimeter to beginning of this one.
8674 else 8663 */
8675 { 8664 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
8676 // present and correct 8665
8677 if (offset[j] < offset[best]) 8666 /*
8678 { 8667 * Remove separator from input string.
8679 // closest so far 8668 */
8680 best = j; 8669 i += sep.Length;
8681 if (offset[best] == beginning) 8670
8682 break; 8671 /*
8683 } 8672 * Next non-delimeter starts where this separator left off.
8684 } 8673 */
8674 lastUsed = i;
8675 goto nextsrc;
8685 } 8676 }
8686 } 8677 }
8687 8678
8688 // Scan for spacers 8679 /*
8689 8680 * See if rest of string (starting at i) matches any spacer.
8690 if (offset[best] != beginning) 8681 */
8691 { 8682 for (j = 0; j < spclen; j ++) {
8692 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8683 string spc = spcarray[j].ToString();
8693 { 8684 if ((spc.Length > 0) && rest.StartsWith(spc)) {
8694 if (active[j]) 8685
8695 { 8686 /*
8696 // scan all of the markers 8687 * Spacer matched, output string from end of last delimeter to beginning of this one.
8697 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8688 * Then output the spacer itself.
8698 { 8689 */
8699 // not present at all 8690 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
8700 active[j] = false; 8691 outarray[outlen++] = new LSL_String(spc);
8701 } 8692
8702 else 8693 /*
8703 { 8694 * Remove spacer from input string.
8704 // present and correct 8695 */
8705 if (offset[j] < offset[best]) 8696 i += spc.Length;
8706 { 8697
8707 // closest so far 8698 /*
8708 best = j; 8699 * Next non-delimeter starts where this spacer left off.
8709 } 8700 */
8710 } 8701 lastUsed = i;
8711 } 8702 goto nextsrc;
8712 } 8703 }
8713 } 8704 }
8714 8705
8715 // This is the normal exit from the scanning loop 8706 /*
8716 8707 * Didn't match any separator or spacer, skip over it and it
8717 if (best == mlen) 8708 * becomes part of the non-delimeter string starting with
8718 { 8709 * lastUsed.
8719 // no markers were found on this pass 8710 */
8720 // so we're pretty much done 8711 i ++;
8721 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); 8712 nextsrc:;
8722 break;
8723 }
8724
8725 // Otherwise we just add the newly delimited token
8726 // and recalculate where the search should continue.
8727
8728 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning)));
8729
8730 if (best < seplen)
8731 {
8732 beginning = offset[best] + (separray[best].ToString()).Length;
8733 }
8734 else
8735 {
8736 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8737 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8738 }
8739 } 8713 }
8740 8714
8741 // This an awkward an not very intuitive boundary case. If the 8715 /*
8742 // last substring is a tokenizer, then there is an implied trailing 8716 * Output last non-delimeter (including a possible null string if
8743 // null list entry. Hopefully the single comparison will not be too 8717 * delimeter ran to end of source string).
8744 // arduous. Alternatively the 'break' could be replced with a return 8718 */
8745 // but that's shabby programming. 8719 outarray[outlen++] = new LSL_String(src.Substring(lastUsed));
8746 8720
8747 if (beginning == srclen) 8721 /*
8748 { 8722 * Make up an exact-sized output array suitable for an LSL_List object.
8749 if (srclen != 0) 8723 */
8750 tokens.Add(new LSL_String("")); 8724 object[] outlist = new object[outlen];
8725 for (i = 0; i < outlen; i ++) {
8726 outlist[i] = outarray[i];
8751 } 8727 }
8752 8728 return new LSL_List(outlist);
8753 return tokens;
8754 } 8729 }
8755 8730
8756 public LSL_Integer llGetObjectPermMask(int mask) 8731 public LSL_Integer llGetObjectPermMask(int mask)