diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c305f864ea..717cc07d05 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -426,14 +426,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return key; } - // convert a LSL_Rotation to a Quaternion - public static Quaternion Rot2Quaternion(LSL_Rotation r) - { - Quaternion q = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); - q.Normalize(); - return q; - } - //These are the implementations of the various ll-functions used by the LSL scripts. public LSL_Float llSin(double f) { @@ -2331,7 +2323,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // using it would cause attachments and HUDs to rotate // to the wrong positions. - SetRot(m_host, Rot2Quaternion(rot)); + SetRot(m_host, rot); } else { @@ -2341,7 +2333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { rootPart = m_host.ParentGroup.RootPart; if (rootPart != null) - SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); + SetRot(m_host, rootPart.RotationOffset * (Quaternion)rot); } } @@ -2351,8 +2343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLocalRot(LSL_Rotation rot) { m_host.AddScriptLPS(1); - - SetRot(m_host, Rot2Quaternion(rot)); + SetRot(m_host, rot); ScriptSleep(200); } @@ -2498,8 +2489,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llRotTarget(LSL_Rotation rot, double error) { m_host.AddScriptLPS(1); - return m_host.ParentGroup.registerRotTargetWaypoint( - new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), (float)error); + return m_host.ParentGroup.registerRotTargetWaypoint(rot, (float)error); } public void llRotTargetRemove(int number) @@ -3111,7 +3101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // need the magnitude later // float velmag = (float)Util.GetMagnitude(llvel); - SceneObjectGroup new_group = World.RezObject(m_host, item, pos, Rot2Quaternion(rot), vel, param); + SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param); // If either of these are null, then there was an unknown error. if (new_group == null) @@ -3193,7 +3183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; } - m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); + m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping); } } @@ -3619,7 +3609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); + m_host.RotLookAt(target, (float)strength, (float)damping); } } @@ -6970,7 +6960,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_host.ParentGroup.IsDeleted) { - m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, Rot2Quaternion(rot)); + m_host.ParentGroup.RootPart.SetVehicleRotationParam(param, rot); } } @@ -7001,7 +6991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api rot.s = 1; // ZERO_ROTATION = 0,0,0,1 part.SitTargetPosition = offset; - part.SitTargetOrientation = Rot2Quaternion(rot); + part.SitTargetOrientation = rot; part.ParentGroup.HasGroupChanged = true; } @@ -8066,13 +8056,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (rootPart == part) { // special case: If we are root, rotate complete SOG to new rotation - SetRot(part, Rot2Quaternion(q)); + SetRot(part, q); } else { // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. // sounds like sl bug that we need to replicate - SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); + SetRot(part, rootPart.RotationOffset * (Quaternion)q); } break; @@ -8414,8 +8404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.PRIM_ROT_LOCAL: if (remain < 1) return null; - LSL_Rotation lr = rules.GetQuaternionItem(idx++); - SetRot(part, Rot2Quaternion(lr)); + SetRot(part, rules.GetQuaternionItem(idx++)); break; case (int)ScriptBaseClass.PRIM_OMEGA: if (remain < 3) @@ -11878,13 +11867,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else rot = obj.GetWorldRotation(); - LSL_Rotation objrot = new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W); + LSL_Rotation objrot = new LSL_Rotation(rot); ret.Add(objrot); } break; case ScriptBaseClass.OBJECT_VELOCITY: - Vector3 ovel = obj.Velocity; - ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z)); + ret.Add(new LSL_Vector(obj.Velocity)); break; case ScriptBaseClass.OBJECT_OWNER: ret.Add(new LSL_String(obj.OwnerID.ToString())); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs index 929948b3e1..84cf6cab65 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs @@ -333,8 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (type == typeof(OpenMetaverse.Quaternion)) { - LSL_Rotation rot = (LSL_Rotation)lslparm; - return new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); + return (OpenMetaverse.Quaternion)((LSL_Rotation)lslparm); } } @@ -366,8 +365,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api result[i] = new UUID((LSL_Key)plist[i]); else if (plist[i] is LSL_Rotation) { - LSL_Rotation rot = (LSL_Rotation)plist[i]; - result[i] = new OpenMetaverse.Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s); + result[i] = (OpenMetaverse.Quaternion)( + (LSL_Rotation)plist[i]); } else if (plist[i] is LSL_Vector) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 321d1d8659..37766fbbb7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2565,7 +2565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence sp = World.GetScenePresence(npcId); if (sp != null) - sp.Rotation = LSL_Api.Rot2Quaternion(rotation); + sp.Rotation = rotation; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 8b3be4a440..4dd795da10 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -352,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins q = avatar.Rotation; } - LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); + LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); @@ -482,7 +482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins q = avatar.Rotation; } - LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); + LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0); diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 4ab2f236ca..c9c4753195 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -361,6 +361,14 @@ namespace OpenSim.Region.ScriptEngine.Shared s = 1; } + public Quaternion(OMV_Quaternion rot) + { + x = rot.X; + y = rot.Y; + z = rot.Z; + s = rot.W; + } + #endregion #region Overriders @@ -407,6 +415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared return new list(new object[] { r }); } + public static implicit operator OMV_Quaternion(Quaternion rot) + { + // LSL quaternions can normalize to 0, normal Quaternions can't. + if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) + rot.z = 1; // ZERO_ROTATION = 0,0,0,1 + OMV_Quaternion omvrot = new OMV_Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); + omvrot.Normalize(); + return omvrot; + } + + public static implicit operator Quaternion(OMV_Quaternion rot) + { + return new Quaternion(rot); + } + public static bool operator ==(Quaternion lhs, Quaternion rhs) { // Return true if the fields match: diff --git a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs index a1ad07d43c..cee10df54a 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/EventManager.cs @@ -391,8 +391,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine myScriptEngine.PostObjectEvent(localID, new EventParams( "at_rot_target", new object[] { new LSL_Types.LSLInteger(handle), - new LSL_Types.Quaternion(targetrot.X,targetrot.Y,targetrot.Z,targetrot.W), - new LSL_Types.Quaternion(atrot.X,atrot.Y,atrot.Z,atrot.W) }, + new LSL_Types.Quaternion(targetrot), + new LSL_Types.Quaternion(atrot) }, new DetectParams[0])); } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index eee5d7b7b9..f5ad99073d 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1558,7 +1558,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine else if (p[i] is Vector3) lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]); else if (p[i] is Quaternion) - lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); + lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]); else if (p[i] is float) lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); else @@ -1584,7 +1584,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine else if (p[i] is Vector3) lsl_p[i] = new LSL_Types.Vector3((Vector3)p[i]); else if (p[i] is Quaternion) - lsl_p[i] = new LSL_Types.Quaternion(((Quaternion)p[i]).X, ((Quaternion)p[i]).Y, ((Quaternion)p[i]).Z, ((Quaternion)p[i]).W); + lsl_p[i] = new LSL_Types.Quaternion((Quaternion)p[i]); else if (p[i] is float) lsl_p[i] = new LSL_Types.LSLFloat((float)p[i]); else