Thanks again to Alondria for adding: math support for

rot * rot, vec / rot, == and != overriders for Rotations and Vectors.
Also: llRotBetween(), llGetRegionTimeDilation(). And fixing:
Error in LSL2CSConverter that botched a variable with a type name in it (ex: rotationCenter)
Fixed: Error in LSL2CSConverter that parsed which() loops incorrectly.
Fixed: Changed definition of Quaternion to <x, y, z, r> from <x, y, z, t> (As per LSL)
Finished: llEuler2Rot()
afrisby
Charles Krinke 2007-12-15 16:26:32 +00:00
parent 653a41fa03
commit fd360406b9
3 changed files with 181 additions and 63 deletions

View File

@ -53,59 +53,53 @@ namespace OpenSim.Region.ScriptEngine.Common
y = Y; y = Y;
z = Z; z = Z;
} }
public string ToString()
#region Overriders
public override string ToString()
{ {
return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ">"; return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ">";
} }
public static Vector3 operator *(Vector3 v, float f) public static bool operator ==(Vector3 lhs, Vector3 rhs)
{ {
v.x = v.x * f; return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
v.y = v.y * f;
v.z = v.z * f;
return v;
} }
public static Vector3 operator /(Vector3 v, float f) public static bool operator !=(Vector3 lhs, Vector3 rhs)
{ {
v.x = v.x / f; return !(lhs == rhs);
v.y = v.y / f;
v.z = v.z / f;
return v;
} }
public static Vector3 operator /(float f, Vector3 v) public override int GetHashCode()
{ {
v.x = v.x / f; return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode());
v.y = v.y / f;
v.z = v.z / f;
return v;
} }
public static Vector3 operator *(float f, Vector3 v)
public override bool Equals(object o)
{ {
v.x = v.x * f; if (!(o is Vector3)) return false;
v.y = v.y * f;
v.z = v.z * f; Vector3 vector = (Vector3)o;
return v;
return (x == vector.x && x == vector.x && z == vector.z);
} }
public static Vector3 operator *(Vector3 v1, Vector3 v2)
#endregion
#region Vector & Vector Math
// Vector-Vector Math
public static Vector3 operator +(Vector3 lhs, Vector3 rhs)
{ {
v1.x = v1.x * v2.x; return new Vector3(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);
v1.y = v1.y * v2.y; }
v1.z = v1.z * v2.z; public static Vector3 operator -(Vector3 lhs, Vector3 rhs)
return v1;
}
public static Vector3 operator +(Vector3 v1, Vector3 v2)
{ {
v1.x = v1.x + v2.x; return new Vector3(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);
v1.y = v1.y + v2.y;
v1.z = v1.z + v2.z;
return v1;
} }
public static Vector3 operator -(Vector3 v1, Vector3 v2) public static Vector3 operator *(Vector3 lhs, Vector3 rhs)
{ {
v1.x = v1.x - v2.x; return new Vector3(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);
v1.y = v1.y - v2.y;
v1.z = v1.z - v2.z;
return v1;
} }
public static Vector3 operator %(Vector3 v1, Vector3 v2) public static Vector3 operator %(Vector3 v1, Vector3 v2)
{ {
//Cross product //Cross product
@ -115,6 +109,79 @@ namespace OpenSim.Region.ScriptEngine.Common
tv.z = (v1.x * v2.y) - (v1.y * v2.x); tv.z = (v1.x * v2.y) - (v1.y * v2.x);
return tv; return tv;
} }
#endregion
#region Vector & Float Math
// Vector-Float and Float-Vector Math
public static Vector3 operator *(Vector3 vec, float val)
{
return new Vector3(vec.x * val, vec.y * val, vec.z * val);
}
public static Vector3 operator *(float val, Vector3 vec)
{
return new Vector3(vec.x * val, vec.y * val, vec.z * val);
}
public static Vector3 operator /(Vector3 v, float f)
{
v.x = v.x / f;
v.y = v.y / f;
v.z = v.z / f;
return v;
}
#endregion
#region Vector & Rotation Math
// Vector-Rotation Math
public static Vector3 operator *(Vector3 v, Quaternion r)
{
Quaternion vq = new Quaternion(v.x, v.y, v.z, 0);
Quaternion nq = new Quaternion(-r.x, -r.y, -r.z, r.s);
Quaternion result = (r * vq) * nq;
return new Vector3(result.x, result.y, result.z);
}
// I *think* this is how it works....
public static Vector3 operator /(Vector3 vec, Quaternion quat)
{
quat.s = -quat.s;
Quaternion vq = new Quaternion(vec.x, vec.y, vec.z, 0);
Quaternion nq = new Quaternion(-quat.x, -quat.y, -quat.z, quat.s);
Quaternion result = (quat * vq) * nq;
return new Vector3(result.x, result.y, result.z);
}
#endregion
#region Static Helper Functions
public static double Dot(Vector3 v1, Vector3 v2)
{
return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
}
public static Vector3 Cross(Vector3 v1, Vector3 v2)
{
return new Vector3
(
v1.y * v2.z - v1.z * v2.y,
v1.z * v2.x - v1.x * v2.z,
v1.x * v2.y - v1.y * v2.x
);
}
public static float Mag(Vector3 v)
{
return (float)Math.Sqrt(v.x * v.y + v.y * v.y + v.z * v.z);
}
public static Vector3 Norm(Vector3 vector)
{
float mag = Mag(vector);
return new Vector3(vector.x / mag, vector.y / mag, vector.z / mag);
}
#endregion
} }
[Serializable] [Serializable]
@ -123,26 +190,66 @@ namespace OpenSim.Region.ScriptEngine.Common
public double x; public double x;
public double y; public double y;
public double z; public double z;
public double r; public double s;
public Quaternion(Quaternion Quat) public Quaternion(Quaternion Quat)
{ {
x = (float) Quat.x; x = (float) Quat.x;
y = (float) Quat.y; y = (float) Quat.y;
z = (float) Quat.z; z = (float) Quat.z;
r = (float) Quat.r; s = (float) Quat.s;
} }
public Quaternion(double X, double Y, double Z, double R) public Quaternion(double X, double Y, double Z, double S)
{ {
x = X; x = X;
y = Y; y = Y;
z = Z; z = Z;
r = R; s = S;
} }
public string ToString()
#region Overriders
public override int GetHashCode()
{ {
return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ", " + r.ToString() + ">"; return (x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode() ^ s.GetHashCode());
}
public override bool Equals(object o)
{
if (!(o is Quaternion)) return false;
Quaternion quaternion = (Quaternion)o;
return x == quaternion.x && y == quaternion.y && z == quaternion.z && s == quaternion.s;
}
public override string ToString()
{
return "<" + x.ToString() + ", " + y.ToString() + ", " + z.ToString() + ", " + s.ToString() + ">";
}
public static bool operator ==(Quaternion lhs, Quaternion rhs)
{
// Return true if the fields match:
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.s == rhs.s;
}
public static bool operator !=(Quaternion lhs, Quaternion rhs)
{
return !(lhs == rhs);
}
#endregion
public static Quaternion operator *(Quaternion a, Quaternion b)
{
Quaternion c;
c.x = a.s * b.x + a.x * b.s + a.y * b.z - a.z * b.y;
c.y = a.s * b.y + a.y * b.s + a.z * b.x - a.x * b.z;
c.z = a.s * b.z + a.z * b.s + a.x * b.y - a.y * b.x;
c.s = a.s * b.s - a.x * b.x - a.y * b.y - a.z * b.z;
return c;
} }
} }
} }

View File

@ -47,7 +47,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
dataTypes.Add("key", "string"); dataTypes.Add("key", "string");
dataTypes.Add("vector", "LSL_Types.Vector3"); dataTypes.Add("vector", "LSL_Types.Vector3");
dataTypes.Add("rotation", "LSL_Types.Quaternion"); dataTypes.Add("rotation", "LSL_Types.Quaternion");
dataTypes.Add("list", "List"); dataTypes.Add("list", "List<string>");
dataTypes.Add("null", "null"); dataTypes.Add("null", "null");
} }
@ -203,7 +203,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
//Console.WriteLine("Replacing using statename: " + current_statename); //Console.WriteLine("Replacing using statename: " + current_statename);
cache = cache =
Regex.Replace(cache, Regex.Replace(cache,
@"^(\s*)((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)", @"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
@"$1public " + current_statename + "_event_$2", @"$1public " + current_statename + "_event_$2",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline); RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
} }
@ -236,7 +236,10 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
RegexOptions.Compiled | RegexOptions.Multiline); RegexOptions.Compiled | RegexOptions.Multiline);
// Replace return types and function variables - integer a() and f(integer a, integer a) // Replace return types and function variables - integer a() and f(integer a, integer a)
Script = Script =
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)", @"$1$2" + val + "$3", Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
RegexOptions.Compiled | RegexOptions.Multiline);
Script =
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
RegexOptions.Compiled | RegexOptions.Multiline); RegexOptions.Compiled | RegexOptions.Multiline);
} }
@ -281,7 +284,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
// Add namespace, class name and inheritance // Add namespace, class name and inheritance
Return = "" + Return = "" +
"using OpenSim.Region.ScriptEngine.Common;"; "using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;";
//"using System; " + //"using System; " +
//"using System.Collections.Generic; " + //"using System.Collections.Generic; " +
//"using System.Text; " + //"using System.Text; " +

View File

@ -191,19 +191,19 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r) public LSL_Types.Vector3 llRot2Euler(LSL_Types.Quaternion r)
{ {
//This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke
LSL_Types.Quaternion t = new LSL_Types.Quaternion(r.x*r.x, r.y*r.y, r.z*r.z, r.r*r.r); LSL_Types.Quaternion t = new LSL_Types.Quaternion(r.x*r.x, r.y*r.y, r.z*r.z, r.s*r.s);
double m = (t.x + t.y + t.z + t.r); double m = (t.x + t.y + t.z + t.s);
if (m == 0) return new LSL_Types.Vector3(); if (m == 0) return new LSL_Types.Vector3();
double n = 2*(r.y*r.r + r.x*r.z); double n = 2*(r.y*r.s + r.x*r.z);
double p = m*m - n*n; double p = m*m - n*n;
if (p > 0) if (p > 0)
return new LSL_Types.Vector3(Math.Atan2(2.0*(r.x*r.r - r.y*r.z), (-t.x - t.y + t.z + t.r)), return new LSL_Types.Vector3(Math.Atan2(2.0*(r.x*r.s - r.y*r.z), (-t.x - t.y + t.z + t.s)),
Math.Atan2(n, Math.Sqrt(p)), Math.Atan2(n, Math.Sqrt(p)),
Math.Atan2(2.0*(r.z*r.r - r.x*r.y), (t.x - t.y - t.z + t.r))); Math.Atan2(2.0*(r.z*r.s - r.x*r.y), (t.x - t.y - t.z + t.s)));
else if (n > 0) else if (n > 0)
return new LSL_Types.Vector3(0.0, Math.PI/2, Math.Atan2((r.z*r.r + r.x*r.y), 0.5 - t.x - t.z)); return new LSL_Types.Vector3(0.0, Math.PI/2, Math.Atan2((r.z*r.s + r.x*r.y), 0.5 - t.x - t.z));
else else
return new LSL_Types.Vector3(0.0, -Math.PI/2, Math.Atan2((r.z*r.r + r.x*r.y), 0.5 - t.x - t.z)); return new LSL_Types.Vector3(0.0, -Math.PI/2, Math.Atan2((r.z*r.s + r.x*r.y), 0.5 - t.x - t.z));
} }
public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v) public LSL_Types.Quaternion llEuler2Rot(LSL_Types.Vector3 v)
@ -219,6 +219,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
LSL_Types.Quaternion a1 = new LSL_Types.Quaternion(0.0, 0.0, cz, cw); LSL_Types.Quaternion a1 = new LSL_Types.Quaternion(0.0, 0.0, cz, cw);
LSL_Types.Quaternion a2 = new LSL_Types.Quaternion(0.0, by, 0.0, bw); LSL_Types.Quaternion a2 = new LSL_Types.Quaternion(0.0, by, 0.0, bw);
LSL_Types.Quaternion a3 = new LSL_Types.Quaternion(ax, 0.0, 0.0, aw); LSL_Types.Quaternion a3 = new LSL_Types.Quaternion(ax, 0.0, 0.0, aw);
LSL_Types.Quaternion a = (a1 * a2) * a3;
//This multiplication doesnt compile, yet. a = a1 * a2 * a3; //This multiplication doesnt compile, yet. a = a1 * a2 * a3;
LSL_Types.Quaternion b = new LSL_Types.Quaternion(ax*bw*cw + aw*by*cz, LSL_Types.Quaternion b = new LSL_Types.Quaternion(ax*bw*cw + aw*by*cz,
aw*by*cw - ax*bw*cz, aw*bw*cz + ax*by*cw, aw*by*cw - ax*bw*cz, aw*bw*cz + ax*by*cw,
@ -230,13 +231,14 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
if ((Math.Abs(c.x) > err && Math.Abs(d.x) > err) || if ((Math.Abs(c.x) > err && Math.Abs(d.x) > err) ||
(Math.Abs(c.y) > err && Math.Abs(d.y) > err) || (Math.Abs(c.y) > err && Math.Abs(d.y) > err) ||
(Math.Abs(c.z) > err && Math.Abs(d.z) > err) || (Math.Abs(c.z) > err && Math.Abs(d.z) > err) ||
(Math.Abs(c.r) > err && Math.Abs(d.r) > err)) (Math.Abs(c.s) > err && Math.Abs(d.s) > err))
{ {
return b;
//return a new Quaternion that is null until I figure this out //return a new Quaternion that is null until I figure this out
// return b; // return b;
// return a; // return a;
} }
return new LSL_Types.Quaternion(); return a;
} }
public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up)
@ -258,12 +260,19 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
{ {
return new LSL_Types.Vector3(); return new LSL_Types.Vector3();
} }
public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 a, LSL_Types.Vector3 b)
public LSL_Types.Quaternion llRotBetween(LSL_Types.Vector3 start, LSL_Types.Vector3 end)
{ {
return new LSL_Types.Quaternion(); //A and B should both be normalized
}
double dotProduct = LSL_Types.Vector3.Dot(a, b);
LSL_Types.Vector3 crossProduct = LSL_Types.Vector3.Cross(a, b);
double magProduct = LSL_Types.Vector3.Mag(a) * LSL_Types.Vector3.Mag(b);
double angle = Math.Acos(dotProduct / magProduct);
LSL_Types.Vector3 axis = LSL_Types.Vector3.Norm(crossProduct);
double s = Math.Sin(angle / 2);
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) public void llWhisper(int channelID, string text)
{ {
World.SimChat(Helpers.StringToField(text), World.SimChat(Helpers.StringToField(text),
@ -629,7 +638,6 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
} }
if (face == -1) if (face == -1)
{ {
LLObject.TextureEntryFace texface;
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
if (tex.FaceTextures[i] != null) if (tex.FaceTextures[i] != null)
@ -729,7 +737,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
public void llSetRot(LSL_Types.Quaternion rot) public void llSetRot(LSL_Types.Quaternion rot)
{ {
m_host.UpdateRotation(new LLQuaternion((float) rot.x, (float) rot.y, (float) rot.z, (float) rot.r)); m_host.UpdateRotation(new LLQuaternion((float) rot.x, (float) rot.y, (float) rot.z, (float) rot.s));
} }
public LSL_Types.Quaternion llGetRot() public LSL_Types.Quaternion llGetRot()
@ -1778,7 +1786,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
public double llGetRegionTimeDilation() public double llGetRegionTimeDilation()
{ {
return 1.0f; return (double)World.TimeDilation;
} }
public double llGetRegionFPS() public double llGetRegionFPS()