diff options
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-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 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) |