diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7494b88584..ebd281efd3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -5554,5 +5554,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api DateTime time = TimeZoneInfo.ConvertTime(DateTime.UtcNow, PSTTimeZone); return time.TimeOfDay.TotalSeconds; } + + public LSL_Rotation osSlerp(LSL_Rotation a, LSL_Rotation b, LSL_Float amount) + { + if(amount < 0) + amount= 0; + else if(amount > 1.0) + amount = 1.0; + a.Normalize(); + b.Normalize(); + + return LSL_Rotation.Slerp(a, b, amount); + } } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 1bd6e086fb..369b361007 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -36,6 +36,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; @@ -554,5 +555,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String osGetInventoryDesc(LSL_String itemNameOrId); LSL_Key osGetLastChangedEventKey(); LSL_Float osGetPSTWallclock(); + LSL_Rotation osSlerp(LSL_Rotation a, LSL_Rotation b, LSL_Float amount); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 3f880e4562..7edda5813e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -35,7 +35,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public partial class ScriptBaseClass { // SCRIPTS CONSTANTS - public static readonly LSLInteger OS_APIVERSION = 7; + public static readonly LSLInteger OS_APIVERSION = 8; public static readonly LSLInteger TRUE = 1; public static readonly LSLInteger FALSE = 0; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 549047c03d..866a955e4d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -1407,5 +1407,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_OSSL_Functions.osGetPSTWallclock(); } + public rotation osSlerp(rotation a, rotation b, LSL_Float amount) + { + return m_OSSL_Functions.osSlerp(a, b, amount); + } + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index b52f767f40..40e82044e3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -434,6 +434,58 @@ namespace OpenSim.Region.ScriptEngine.Shared return this; } + + public static Quaternion Slerp(Quaternion q1, Quaternion q2, double amount) + { + double angle = (q1.x * q2.x) + (q1.y * q2.y) + (q1.z * q2.z) + (q1.s * q2.s); + + if (angle < 0f) + { + q1.x = -q1.x; + q1.y = -q1.y; + q1.z = -q1.z; + q1.s = -q1.s; + angle *= -1.0; + } + + double scale; + double invscale; + + if ((angle + 1f) > 0.05f) + { + if ((1f - angle) >= 0.05f) + { + // slerp + double theta = Math.Acos(angle); + double invsintheta = 1.0 / Math.Sin(theta); + scale = Math.Sin(theta * (1.0 - amount)) * invsintheta; + invscale = Math.Sin(theta * amount) * invsintheta; + } + else + { + // lerp + scale = 1.0 - amount; + invscale = amount; + } + } + else + { + q2.x = -q1.y; + q2.y = q1.x; + q2.z = -q1.s; + q2.s = q1.z; + + scale = Math.Sin(Math.PI * (0.5 - amount)); + invscale = Math.Sin(Math.PI * amount); + } + + return new Quaternion( + q1.x * scale + q2.x * invscale, + q1.y * scale + q2.y * invscale, + q1.z * scale + q2.z * invscale, + q1.s * scale + q2.s * invscale + ); + } #endregion #region Overriders