some optimizations in quaternion normalization in llRot2Fwd, llRot2Left, and llRot2Up. llAxes2Rot now uses these functions for sign error correction instead of vector*quat products.

0.6.0-stable
Dahlia Trimble 2008-07-21 09:36:22 +00:00
parent 08f3d212ce
commit ce90e2ecce
2 changed files with 98 additions and 73 deletions

View File

@ -456,9 +456,7 @@ namespace OpenSim.Region.ScriptEngine.Common
LSL_Types.Quaternion result = new LSL_Types.Quaternion(x, y, z, s);
// a hack to correct a few questionable angles :(
LSL_Types.Vector3 fwdTest = new LSL_Types.Vector3(1, 0, 0);
LSL_Types.Vector3 leftTest = new LSL_Types.Vector3(0, 1, 0);
if (llVecDist(fwdTest * result, fwd) > 0.001 || llVecDist(leftTest * result, left) > 0.001)
if (llVecDist(llRot2Fwd(result), fwd) > 0.001 || llVecDist(llRot2Left(result), left) > 0.001)
result.s = -s;
return result;
@ -467,61 +465,75 @@ namespace OpenSim.Region.ScriptEngine.Common
public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = r.x*r.x-r.y*r.y-r.z*r.z+r.s*r.s;
y = 2*(r.x*r.y+r.z*r.s);
z = 2*(r.x*r.z-r.y*r.s);
return (new LSL_Types.Vector3(x,y,z));
x = r.x * r.x - r.y * r.y - r.z * r.z + r.s * r.s;
y = 2 * (r.x * r.y + r.z * r.s);
z = 2 * (r.x * r.z - r.y * r.s);
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = 2*(r.x*r.y-r.z*r.s);
y = -r.x*r.x+r.y*r.y-r.z*r.z+r.s*r.s;
z = 2*(r.x*r.s+r.y*r.z);
return (new LSL_Types.Vector3(x,y,z));
x = 2 * (r.x * r.y - r.z * r.s);
y = -r.x * r.x + r.y * r.y - r.z * r.z + r.s * r.s;
z = 2 * (r.x * r.s + r.y * r.z);
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = 2*(r.x*r.z+r.y*r.s);
y = 2*(-r.x*r.s+r.y*r.z);
z = -r.x*r.x-r.y*r.y+r.z*r.z+r.s*r.s;
return (new LSL_Types.Vector3(x,y,z));
x = 2 * (r.x * r.z + r.y * r.s);
y = 2*(-r.x * r.s + r.y * r.z);
z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 a, LSL_Types.Vector3 b)
@ -537,6 +549,7 @@ namespace OpenSim.Region.ScriptEngine.Common
return new LSL_Types.Quaternion(axis.x * s, axis.y * s, axis.z * s, (float)Math.Cos(angle / 2));
}
public void llWhisper(int channelID, string text)
{
m_host.AddScriptLPS(1);

View File

@ -443,9 +443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
LSL_Types.Quaternion result = new LSL_Types.Quaternion(x, y, z, s);
// a hack to correct a few questionable angles :(
LSL_Types.Vector3 fwdTest = new LSL_Types.Vector3(1, 0, 0);
LSL_Types.Vector3 leftTest = new LSL_Types.Vector3(0, 1, 0);
if (llVecDist(fwdTest * result, fwd) > 0.001 || llVecDist(leftTest * result, left) > 0.001)
if (llVecDist(llRot2Fwd(result), fwd) > 0.001 || llVecDist(llRot2Left(result), left) > 0.001)
result.s = -s;
return result;
@ -454,61 +452,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = r.x*r.x-r.y*r.y-r.z*r.z+r.s*r.s;
y = 2*(r.x*r.y+r.z*r.s);
z = 2*(r.x*r.z-r.y*r.s);
return (new LSL_Types.Vector3(x,y,z));
x = r.x * r.x - r.y * r.y - r.z * r.z + r.s * r.s;
y = 2 * (r.x * r.y + r.z * r.s);
z = 2 * (r.x * r.z - r.y * r.s);
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Vector3 llRot2Left(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = 2*(r.x*r.y-r.z*r.s);
y = -r.x*r.x+r.y*r.y-r.z*r.z+r.s*r.s;
z = 2*(r.x*r.s+r.y*r.z);
return (new LSL_Types.Vector3(x,y,z));
x = 2 * (r.x * r.y - r.z * r.s);
y = -r.x * r.x + r.y * r.y - r.z * r.z + r.s * r.s;
z = 2 * (r.x * r.s + r.y * r.z);
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Vector3 llRot2Up(LSL_Types.Quaternion r)
{
m_host.AddScriptLPS(1);
double x,y,z,m;
m = Math.Sqrt(r.x*r.x+r.y*r.y+r.z*r.z+r.s*r.s);
double x, y, z, m;
m = r.x * r.x + r.y * r.y + r.z * r.z + r.s * r.s;
// m is always greater than zero
if (m!=1) // if m is not equal to 1 then Rotation needs to be normalized
// if m is not equal to 1 then Rotation needs to be normalized
if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
{
r.x/=m;
r.y/=m;
r.z/=m;
r.s/=m;
m = 1.0 / Math.Sqrt(m);
r.x *= m;
r.y *= m;
r.z *= m;
r.s *= m;
}
// Fast Algebric Calculations instead of Vectors & Quaternions Product
x = 2*(r.x*r.z+r.y*r.s);
y = 2*(-r.x*r.s+r.y*r.z);
z = -r.x*r.x-r.y*r.y+r.z*r.z+r.s*r.s;
return (new LSL_Types.Vector3(x,y,z));
x = 2 * (r.x * r.z + r.y * r.s);
y = 2 * (-r.x * r.s + r.y * r.z);
z = -r.x * r.x - r.y * r.y + r.z * r.z + r.s * r.s;
return (new LSL_Types.Vector3(x, y, z));
}
public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 a, LSL_Types.Vector3 b)