diff --git a/libsecondlife/Types.cs b/libsecondlife/Types.cs
index be1bc419..b0e44652 100644
--- a/libsecondlife/Types.cs
+++ b/libsecondlife/Types.cs
@@ -653,28 +653,22 @@ namespace libsecondlife
this = LLVector3.Zero;
}
+ //FIXME: Need comprehensive testing for this
///
/// Assumes this vector represents euler rotations along the X, Y, and
/// Z axis and creates a quaternion representation of the rotations
///
/// A quaternion representation of the euler rotations
- public LLQuaternion ToRotation()
- {
- LLVector3 vec = this;
+ //public LLQuaternion ToQuaternion()
+ //{
+ // LLMatrix3 rotMat = new LLMatrix3(X, Y, Z);
+ // rotMat = LLMatrix3.Orthogonalize(rotMat);
- if (vec.X > Helpers.PI) vec.X -= Helpers.TWO_PI;
- if (vec.Y > Helpers.PI) vec.Y -= Helpers.TWO_PI;
- if (vec.Z > Helpers.PI) vec.Z -= Helpers.TWO_PI;
+ // LLQuaternion quat = rotMat.ToQuaternion();
+ // quat = LLQuaternion.Norm(quat);
- if (vec.X < -Helpers.PI) vec.X += Helpers.TWO_PI;
- if (vec.Y < -Helpers.PI) vec.Y += Helpers.TWO_PI;
- if (vec.Z < -Helpers.PI) vec.Z += Helpers.TWO_PI;
-
- LLQuaternion rot = new LLQuaternion(X, Y, Z, 1f);
- if (vec.Z > Helpers.PI) rot.W = 0f;
-
- return rot;
- }
+ // return quat;
+ //}
#endregion Public Methods
@@ -777,6 +771,16 @@ namespace libsecondlife
(float)Math.Cos(angle / 2));
}
+ public static LLVector3 Transform(LLVector3 vector, LLMatrix3 matrix)
+ {
+ // Operates "from the right" on row vector
+ return new LLVector3(
+ vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31,
+ vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32,
+ vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33
+ );
+ }
+
///
/// Generate an LLVector3 from a string
///
@@ -896,6 +900,11 @@ namespace libsecondlife
return new LLVector3(nx, ny, nz);
}
+ public static LLVector3 operator *(LLVector3 vector, LLMatrix3 matrix)
+ {
+ return LLVector3.Transform(vector, matrix);
+ }
+
#endregion Operators
/// An LLVector3 with a value of 0,0,0
@@ -1827,13 +1836,15 @@ namespace libsecondlife
this = LLQuaternion.Identity;
}
- public void GetEulerAngles(out float roll, out float pitch, out float yaw)
- {
- LLMatrix3 rotMat = new LLMatrix3(this);
- rotMat = LLMatrix3.Orthogonalize(rotMat);
- rotMat.GetEulerAngles(out roll, out pitch, out yaw);
- }
+ //FIXME: Need comprehensive testing for this
+ //public void GetEulerAngles(out float roll, out float pitch, out float yaw)
+ //{
+ // LLMatrix3 rotMat = new LLMatrix3(this);
+ // rotMat = LLMatrix3.Orthogonalize(rotMat);
+ // rotMat.GetEulerAngles(out roll, out pitch, out yaw);
+ //}
+ //FIXME: Need comprehensive testing for this
///
/// Returns the inverse matrix from a quaternion, or the correct
/// matrix if the quaternion is inverse
@@ -2082,10 +2093,44 @@ namespace libsecondlife
this = q.ToMatrix();
}
+ //FIXME:
+ //public LLMatrix3(float roll, float pitch, float yaw)
+ //{
+ // M11 = M12 = M13 = M21 = M22 = M23 = M31 = M32 = M33 = 0f;
+ // FromEulers(roll, pitch, yaw);
+ //}
+
#endregion Constructors
#region Public Methods
+ // FIXME: Need comprehensive testing for this
+ //public void FromEulers(float roll, float pitch, float yaw)
+ //{
+ // float cx, sx, cy, sy, cz, sz;
+ // float cxsy, sxsy;
+
+ // cx = (float)Math.Cos(roll);
+ // sx = (float)Math.Sin(roll);
+ // cy = (float)Math.Cos(pitch);
+ // sy = (float)Math.Sin(pitch);
+ // cz = (float)Math.Cos(yaw);
+ // sz = (float)Math.Sin(yaw);
+
+ // cxsy = cx * sy;
+ // sxsy = sx * sy;
+
+ // M11 = cy * cz;
+ // M21 = -cy * sz;
+ // M31 = sy;
+ // M12 = sxsy * cz + cx * sz;
+ // M22 = -sxsy * sz + cx * cz;
+ // M32 = -sx * cy;
+ // M13 = -cxsy * cz + sx * sz;
+ // M23 = cxsy * sz + sx * cz;
+ // M33 = cx * cy;
+ //}
+
public void GetEulerAngles(out float roll, out float pitch, out float yaw)
{
// From the Matrix and Quaternion FAQ: http://www.j3d.org/matrix_faq/matrfaq_latest.html
@@ -2126,6 +2171,58 @@ namespace libsecondlife
yaw = (float)angleZ;
}
+ public LLQuaternion ToQuaternion()
+ {
+ LLQuaternion quat = new LLQuaternion();
+ float tr, s;
+ float[] q = new float[4];
+ int i, j, k;
+ int[] nxt = new int[] { 1, 2, 0 };
+
+ tr = this[0, 0] + this[1, 1] + this[2, 2];
+
+ // Check the diagonal
+ if (tr > 0f)
+ {
+ s = (float)Math.Sqrt(tr + 1f);
+ quat.W = s / 2f;
+
+ s = 0.5f / s;
+ quat.X = (this[1, 2] - this[2, 1]) * s;
+ quat.Y = (this[2, 0] - this[0, 2]) * s;
+ quat.Z = (this[0, 1] - this[1, 0]) * s;
+ }
+ else
+ {
+ // Diagonal is negative
+ i = 0;
+ if (this[1, 1] > this[0, 0])
+ i = 1;
+ if (this[2, 2] > this[i, i])
+ i = 2;
+
+ j = nxt[i];
+ k = nxt[j];
+
+ s = (float)Math.Sqrt((this[i, i] - (this[j, j] + this[k, k])) + 1f);
+ q[i] = s * 0.5f;
+
+ if (s != 0f)
+ s = 0.5f / s;
+
+ q[3] = (this[j, k] - this[k, j]) * s;
+ q[j] = (this[i, j] + this[j, i]) * s;
+ q[k] = (this[i, k] + this[k, i]) * s;
+
+ quat.X = q[0];
+ quat.Y = q[1];
+ quat.Z = q[2];
+ quat.W = q[3];
+ }
+
+ return quat;
+ }
+
#endregion Public Methods
#region Static Methods
@@ -2183,16 +2280,6 @@ namespace libsecondlife
);
}
- public static LLVector3 Transform(LLVector3 vector, LLMatrix3 matrix)
- {
- // Operates "from the right" on row vector
- return new LLVector3(
- vector.X * matrix.M11 + vector.Y * matrix.M21 + vector.Z * matrix.M31,
- vector.X * matrix.M12 + vector.Y * matrix.M22 + vector.Z * matrix.M32,
- vector.X * matrix.M13 + vector.Y * matrix.M23 + vector.Z * matrix.M33
- );
- }
-
///
/// Transposes a matrix
///
@@ -2300,11 +2387,6 @@ namespace libsecondlife
return LLMatrix3.Multiply(left, right); ;
}
- public static LLVector3 operator *(LLVector3 vector, LLMatrix3 matrix)
- {
- return LLMatrix3.Transform(vector, matrix);
- }
-
public LLVector3 this[int row]
{
get
diff --git a/libsecondlife/libsecondlife.Tests/PrimObjectTests.cs b/libsecondlife/libsecondlife.Tests/PrimObjectTests.cs
index 1c8c12c2..afdc4278 100644
--- a/libsecondlife/libsecondlife.Tests/PrimObjectTests.cs
+++ b/libsecondlife/libsecondlife.Tests/PrimObjectTests.cs
@@ -15,11 +15,11 @@ namespace libsecondlife.Tests
{
for (byte i = 0; i < byte.MaxValue; i++)
{
- float floatValue = LLObject.PathBeginFloat(i);
- ushort result = LLObject.PathBeginUInt16(floatValue);
+ float floatValue = LLObject.UnpackBeginCut(i);
+ ushort result = LLObject.PackBeginCut(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
+ ", and ended up with " + result);
}
}
@@ -28,24 +28,11 @@ namespace libsecondlife.Tests
{
for (byte i = 0; i < byte.MaxValue; i++)
{
- float floatValue = LLObject.PathEndFloat(i);
- ushort result = LLObject.PathEndUInt16(floatValue);
+ float floatValue = LLObject.UnpackEndCut(i);
+ ushort result = LLObject.PackEndCut(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
- }
- }
-
- [Test]
- public void PathRadiusOffset()
- {
- for (sbyte i = sbyte.MinValue; i < sbyte.MaxValue; i++)
- {
- float floatValue = LLObject.PathRadiusOffsetFloat(i);
- sbyte result = LLObject.PathRadiusOffsetByte(floatValue);
-
- Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
+ ", and ended up with " + result);
}
}
@@ -54,11 +41,11 @@ namespace libsecondlife.Tests
{
for (byte i = 0; i < byte.MaxValue; i++)
{
- float floatValue = LLObject.PathRevolutionsFloat(i);
- byte result = LLObject.PathRevolutionsByte(floatValue);
+ float floatValue = LLObject.UnpackPathRevolutions(i);
+ byte result = LLObject.PackPathRevolutions(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
+ ", and ended up with " + result);
}
}
@@ -67,11 +54,11 @@ namespace libsecondlife.Tests
{
for (byte i = 0; i < byte.MaxValue; i++)
{
- float floatValue = LLObject.PathScaleFloat(i);
- byte result = LLObject.PathScaleByte(floatValue);
+ float floatValue = LLObject.UnpackPathScale(i);
+ byte result = LLObject.PackPathScale(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
+ ", and ended up with " + result);
}
}
@@ -80,21 +67,8 @@ namespace libsecondlife.Tests
{
for (byte i = 0; i < byte.MaxValue; i++)
{
- float floatValue = LLObject.PathShearFloat(i);
- byte result = LLObject.PathShearByte(floatValue);
-
- Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
- }
- }
-
- [Test]
- public void PathSkew()
- {
- for (sbyte i = sbyte.MinValue; i < sbyte.MaxValue; i++)
- {
- float floatValue = LLObject.PathSkewFloat(i);
- sbyte result = LLObject.PathSkewByte(floatValue);
+ float floatValue = LLObject.UnpackPathShear(i);
+ byte result = LLObject.PackPathShear(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
", and ended up with " + result);
@@ -106,34 +80,8 @@ namespace libsecondlife.Tests
{
for (sbyte i = sbyte.MinValue; i < sbyte.MaxValue; i++)
{
- float floatValue = LLObject.PathTaperFloat(i);
- sbyte result = LLObject.PathTaperByte(floatValue);
-
- Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
- }
- }
-
- [Test]
- public void ProfileBegin()
- {
- for (byte i = 0; i < byte.MaxValue; i++)
- {
- float floatValue = LLObject.ProfileBeginFloat(i);
- ushort result = LLObject.ProfileBeginUInt16(floatValue);
-
- Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
- ", and ended up with " + result);
- }
- }
-
- [Test]
- public void ProfileEnd()
- {
- for (byte i = 0; i < byte.MaxValue; i++)
- {
- float floatValue = LLObject.ProfileEndFloat(i);
- ushort result = LLObject.ProfileEndUInt16(floatValue);
+ float floatValue = LLObject.UnpackPathTaper(i);
+ sbyte result = LLObject.PackPathTaper(floatValue);
Assert.IsTrue(result == i, "Started with " + i + ", float value was " + floatValue +
", and ended up with " + result);
@@ -155,12 +103,6 @@ namespace libsecondlife.Tests
}
}
- //[Test]
- //public void TextureEntryRotations()
- //{
- // ;
- //}
-
[Test]
public void TextureEntry()
{
diff --git a/libsecondlife/libsecondlife.Tests/TypeTests.cs b/libsecondlife/libsecondlife.Tests/TypeTests.cs
index e721fe9c..c82ee75a 100644
--- a/libsecondlife/libsecondlife.Tests/TypeTests.cs
+++ b/libsecondlife/libsecondlife.Tests/TypeTests.cs
@@ -84,7 +84,13 @@ namespace libsecondlife.Tests
[Test]
public void VectorQuaternionMath()
{
- ;
+ // Convert a vector to a quaternion and back
+ LLVector3 a = new LLVector3(1f, 0.5f, 0.75f);
+ LLQuaternion b = a.ToQuaternion();
+ LLVector3 c;
+ b.GetEulerAngles(out c.X, out c.Y, out c.Z);
+
+ Assert.IsTrue(a == c, c.ToString() + " does not equal " + a.ToString());
}
[Test]