diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 315 |
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) |