rewrote hanging llParseStringKeepNulls()
parent
6c6c7b0927
commit
90c5555d6d
|
@ -562,23 +562,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
double sqx = q1.x*q1.x;
|
double sqx = q1.x*q1.x;
|
||||||
double sqy = q1.z*q1.z;
|
double sqy = q1.z*q1.z;
|
||||||
double sqz = q1.y*q1.y;
|
double sqz = q1.y*q1.y;
|
||||||
double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
|
double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
|
||||||
double test = q1.x*q1.z + q1.y*q1.s;
|
double test = q1.x*q1.z + q1.y*q1.s;
|
||||||
if (test > 0.4999*unit) { // singularity at north pole
|
if (test > 0.4999*unit) { // singularity at north pole
|
||||||
eul.z = 2 * Math.Atan2(q1.x,q1.s);
|
eul.z = 2 * Math.Atan2(q1.x,q1.s);
|
||||||
eul.y = Math.PI/2;
|
eul.y = Math.PI/2;
|
||||||
eul.x = 0;
|
eul.x = 0;
|
||||||
return eul;
|
return eul;
|
||||||
}
|
}
|
||||||
if (test < -0.4999*unit) { // singularity at south pole
|
if (test < -0.4999*unit) { // singularity at south pole
|
||||||
eul.z = -2 * Math.Atan2(q1.x,q1.s);
|
eul.z = -2 * Math.Atan2(q1.x,q1.s);
|
||||||
eul.y = -Math.PI/2;
|
eul.y = -Math.PI/2;
|
||||||
eul.x = 0;
|
eul.x = 0;
|
||||||
return eul;
|
return eul;
|
||||||
}
|
}
|
||||||
eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
|
eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
|
||||||
eul.y = Math.Asin(2*test/unit);
|
eul.y = Math.Asin(2*test/unit);
|
||||||
eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
|
eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
|
||||||
return eul;
|
return eul;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,53 +804,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
// This method mimics the 180 errors found in SL
|
// This method mimics the 180 errors found in SL
|
||||||
// See www.euclideanspace.com... angleBetween
|
// See www.euclideanspace.com... angleBetween
|
||||||
LSL_Vector vec_a = a;
|
LSL_Vector vec_a = a;
|
||||||
LSL_Vector vec_b = b;
|
LSL_Vector vec_b = b;
|
||||||
|
|
||||||
// Eliminate zero length
|
// Eliminate zero length
|
||||||
LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
|
LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
|
||||||
LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
|
LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
|
||||||
if (vec_a_mag < 0.00001 ||
|
if (vec_a_mag < 0.00001 ||
|
||||||
vec_b_mag < 0.00001)
|
vec_b_mag < 0.00001)
|
||||||
{
|
{
|
||||||
return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
|
return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize
|
// Normalize
|
||||||
vec_a = llVecNorm(vec_a);
|
vec_a = llVecNorm(vec_a);
|
||||||
vec_b = llVecNorm(vec_b);
|
vec_b = llVecNorm(vec_b);
|
||||||
|
|
||||||
// Calculate axis and rotation angle
|
// Calculate axis and rotation angle
|
||||||
LSL_Vector axis = vec_a % vec_b;
|
LSL_Vector axis = vec_a % vec_b;
|
||||||
LSL_Float cos_theta = vec_a * vec_b;
|
LSL_Float cos_theta = vec_a * vec_b;
|
||||||
|
|
||||||
// Check if parallel
|
// Check if parallel
|
||||||
if (cos_theta > 0.99999)
|
if (cos_theta > 0.99999)
|
||||||
{
|
{
|
||||||
return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
|
return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if anti-parallel
|
// Check if anti-parallel
|
||||||
else if (cos_theta < -0.99999)
|
else if (cos_theta < -0.99999)
|
||||||
{
|
{
|
||||||
LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
|
LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
|
||||||
if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
|
if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
|
||||||
return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
|
return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
|
||||||
}
|
}
|
||||||
else // other rotation
|
else // other rotation
|
||||||
{
|
{
|
||||||
LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
|
LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
|
||||||
axis = llVecNorm(axis);
|
axis = llVecNorm(axis);
|
||||||
double x, y, z, s, t;
|
double x, y, z, s, t;
|
||||||
s = Math.Cos(theta);
|
s = Math.Cos(theta);
|
||||||
t = Math.Sin(theta);
|
t = Math.Sin(theta);
|
||||||
x = axis.x * t;
|
x = axis.x * t;
|
||||||
y = axis.y * t;
|
y = axis.y * t;
|
||||||
z = axis.z * t;
|
z = axis.z * t;
|
||||||
return new LSL_Rotation(x,y,z,s);
|
return new LSL_Rotation(x,y,z,s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llWhisper(int channelID, string text)
|
public void llWhisper(int channelID, string text)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
@ -8627,130 +8627,105 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
|
public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
|
||||||
{
|
{
|
||||||
int beginning = 0;
|
int srclen = src.Length;
|
||||||
int srclen = src.Length;
|
int seplen = separators.Length;
|
||||||
int seplen = separators.Length;
|
object[] separray = separators.Data;
|
||||||
object[] separray = separators.Data;
|
int spclen = spacers.Length;
|
||||||
int spclen = spacers.Length;
|
object[] spcarray = spacers.Data;
|
||||||
object[] spcarray = spacers.Data;
|
|
||||||
int mlen = seplen+spclen;
|
|
||||||
|
|
||||||
int[] offset = new int[mlen+1];
|
int outlen = 0;
|
||||||
bool[] active = new bool[mlen];
|
LSL_String[] outarray = new LSL_String[srclen*2+1];
|
||||||
|
|
||||||
int best;
|
int i, j, lastUsed;
|
||||||
int j;
|
|
||||||
|
|
||||||
// Initial capacity reduces resize cost
|
|
||||||
|
|
||||||
LSL_List tokens = new LSL_List();
|
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
// All entries are initially valid
|
/*
|
||||||
|
* Point to beginning of current non-delimeter string.
|
||||||
|
*/
|
||||||
|
lastUsed = 0;
|
||||||
|
|
||||||
for (int i = 0; i < mlen; i++)
|
/*
|
||||||
active[i] = true;
|
* Scan through source string from beginning to end.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < srclen;) {
|
||||||
|
|
||||||
offset[mlen] = srclen;
|
/*
|
||||||
|
* See if rest of string (starting at i) matches any separator.
|
||||||
|
*/
|
||||||
|
string rest = src.Substring(i);
|
||||||
|
for (j = 0; j < seplen; j ++) {
|
||||||
|
string sep = separray[j].ToString();
|
||||||
|
if ((sep.Length > 0) && rest.StartsWith(sep)) {
|
||||||
|
|
||||||
while (beginning < srclen)
|
/*
|
||||||
{
|
* Separator matched, output string from end of last delimeter to beginning of this one.
|
||||||
|
*/
|
||||||
|
outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
|
||||||
|
|
||||||
best = mlen; // as bad as it gets
|
/*
|
||||||
|
* Remove separator from input string.
|
||||||
|
*/
|
||||||
|
i += sep.Length;
|
||||||
|
|
||||||
// Scan for separators
|
/*
|
||||||
|
* Next non-delimeter starts where this separator left off.
|
||||||
for (j = 0; j < seplen; j++)
|
*/
|
||||||
{
|
lastUsed = i;
|
||||||
if (active[j])
|
goto nextsrc;
|
||||||
{
|
|
||||||
// scan all of the markers
|
|
||||||
if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
|
|
||||||
{
|
|
||||||
// not present at all
|
|
||||||
active[j] = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// present and correct
|
|
||||||
if (offset[j] < offset[best])
|
|
||||||
{
|
|
||||||
// closest so far
|
|
||||||
best = j;
|
|
||||||
if (offset[best] == beginning)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan for spacers
|
/*
|
||||||
|
* See if rest of string (starting at i) matches any spacer.
|
||||||
|
*/
|
||||||
|
for (j = 0; j < spclen; j ++) {
|
||||||
|
string spc = spcarray[j].ToString();
|
||||||
|
if ((spc.Length > 0) && rest.StartsWith(spc)) {
|
||||||
|
|
||||||
if (offset[best] != beginning)
|
/*
|
||||||
{
|
* Spacer matched, output string from end of last delimeter to beginning of this one.
|
||||||
for (j = seplen; (j < mlen) && (offset[best] > beginning); j++)
|
* Then output the spacer itself.
|
||||||
{
|
*/
|
||||||
if (active[j])
|
outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
|
||||||
{
|
outarray[outlen++] = new LSL_String(spc);
|
||||||
// scan all of the markers
|
|
||||||
if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
|
/*
|
||||||
{
|
* Remove spacer from input string.
|
||||||
// not present at all
|
*/
|
||||||
active[j] = false;
|
i += spc.Length;
|
||||||
}
|
|
||||||
else
|
/*
|
||||||
{
|
* Next non-delimeter starts where this spacer left off.
|
||||||
// present and correct
|
*/
|
||||||
if (offset[j] < offset[best])
|
lastUsed = i;
|
||||||
{
|
goto nextsrc;
|
||||||
// closest so far
|
|
||||||
best = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the normal exit from the scanning loop
|
/*
|
||||||
|
* Didn't match any separator or spacer, skip over it and it
|
||||||
if (best == mlen)
|
* becomes part of the non-delimeter string starting with
|
||||||
{
|
* lastUsed.
|
||||||
// no markers were found on this pass
|
*/
|
||||||
// so we're pretty much done
|
i ++;
|
||||||
tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
|
nextsrc:;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise we just add the newly delimited token
|
|
||||||
// and recalculate where the search should continue.
|
|
||||||
|
|
||||||
tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning)));
|
|
||||||
|
|
||||||
if (best < seplen)
|
|
||||||
{
|
|
||||||
beginning = offset[best] + (separray[best].ToString()).Length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
|
|
||||||
tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This an awkward an not very intuitive boundary case. If the
|
/*
|
||||||
// last substring is a tokenizer, then there is an implied trailing
|
* Output last non-delimeter (including a possible null string if
|
||||||
// null list entry. Hopefully the single comparison will not be too
|
* delimeter ran to end of source string).
|
||||||
// arduous. Alternatively the 'break' could be replced with a return
|
*/
|
||||||
// but that's shabby programming.
|
outarray[outlen++] = new LSL_String(src.Substring(lastUsed));
|
||||||
|
|
||||||
if (beginning == srclen)
|
/*
|
||||||
{
|
* Make up an exact-sized output array suitable for an LSL_List object.
|
||||||
if (srclen != 0)
|
*/
|
||||||
tokens.Add(new LSL_String(""));
|
object[] outlist = new object[outlen];
|
||||||
|
for (i = 0; i < outlen; i ++) {
|
||||||
|
outlist[i] = outarray[i];
|
||||||
}
|
}
|
||||||
|
return new LSL_List(outlist);
|
||||||
return tokens;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Integer llGetObjectPermMask(int mask)
|
public LSL_Integer llGetObjectPermMask(int mask)
|
||||||
|
|
Loading…
Reference in New Issue