This file wants to be committed.

0.7-release
Diva Canto 2010-06-29 06:25:12 -07:00
parent fa3f448324
commit cf15558c9e
1 changed files with 70 additions and 70 deletions

View File

@ -703,76 +703,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b) public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
{ {
//A and B should both be normalized //A and B should both be normalized
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
LSL_Rotation rotBetween; LSL_Rotation rotBetween;
// Check for zero vectors. If either is zero, return zero rotation. Otherwise, // Check for zero vectors. If either is zero, return zero rotation. Otherwise,
// continue calculation. // continue calculation.
if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f))
{ {
rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
} }
else else
{ {
a = LSL_Vector.Norm(a); a = LSL_Vector.Norm(a);
b = LSL_Vector.Norm(b); b = LSL_Vector.Norm(b);
double dotProduct = LSL_Vector.Dot(a, b); double dotProduct = LSL_Vector.Dot(a, b);
// There are two degenerate cases possible. These are for vectors 180 or // There are two degenerate cases possible. These are for vectors 180 or
// 0 degrees apart. These have to be detected and handled individually. // 0 degrees apart. These have to be detected and handled individually.
// //
// Check for vectors 180 degrees apart. // Check for vectors 180 degrees apart.
// A dot product of -1 would mean the angle between vectors is 180 degrees. // A dot product of -1 would mean the angle between vectors is 180 degrees.
if (dotProduct < -0.9999999f) if (dotProduct < -0.9999999f)
{ {
// First assume X axis is orthogonal to the vectors. // First assume X axis is orthogonal to the vectors.
LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f);
orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a));
// Check for near zero vector. A very small non-zero number here will create // Check for near zero vector. A very small non-zero number here will create
// a rotation in an undesired direction. // a rotation in an undesired direction.
if (LSL_Vector.Mag(orthoVector) > 0.0001) if (LSL_Vector.Mag(orthoVector) > 0.0001)
{ {
rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f);
} }
// If the magnitude of the vector was near zero, then assume the X axis is not // If the magnitude of the vector was near zero, then assume the X axis is not
// orthogonal and use the Z axis instead. // orthogonal and use the Z axis instead.
else else
{ {
// Set 180 z rotation. // Set 180 z rotation.
rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
} }
} }
// Check for parallel vectors. // Check for parallel vectors.
// A dot product of 1 would mean the angle between vectors is 0 degrees. // A dot product of 1 would mean the angle between vectors is 0 degrees.
else if (dotProduct > 0.9999999f) else if (dotProduct > 0.9999999f)
{ {
// Set zero rotation. // Set zero rotation.
rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
} }
else else
{ {
// All special checks have been performed so get the axis of rotation. // All special checks have been performed so get the axis of rotation.
LSL_Vector crossProduct = LSL_Vector.Cross(a, b); LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
// Quarternion s value is the length of the unit vector + dot product. // Quarternion s value is the length of the unit vector + dot product.
double qs = 1.0 + dotProduct; double qs = 1.0 + dotProduct;
rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
// Normalize the rotation. // Normalize the rotation.
double mag = LSL_Rotation.Mag(rotBetween); double mag = LSL_Rotation.Mag(rotBetween);
// We shouldn't have to worry about a divide by zero here. The qs value will be // We shouldn't have to worry about a divide by zero here. The qs value will be
// non-zero because we already know if we're here, then the dotProduct is not -1 so // non-zero because we already know if we're here, then the dotProduct is not -1 so
// qs will not be zero. Also, we've already handled the input vectors being zero so the // qs will not be zero. Also, we've already handled the input vectors being zero so the
// crossProduct vector should also not be zero. // crossProduct vector should also not be zero.
rotBetween.x = rotBetween.x / mag; rotBetween.x = rotBetween.x / mag;
rotBetween.y = rotBetween.y / mag; rotBetween.y = rotBetween.y / mag;
rotBetween.z = rotBetween.z / mag; rotBetween.z = rotBetween.z / mag;
rotBetween.s = rotBetween.s / mag; rotBetween.s = rotBetween.s / mag;
// Check for undefined values and set zero rotation if any found. This code might not actually be required // Check for undefined values and set zero rotation if any found. This code might not actually be required
// any longer since zero vectors are checked for at the top. // any longer since zero vectors are checked for at the top.
if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
{ {
rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
} }
} }
} }
return rotBetween; return rotBetween;
} }