From 9ff9279a7cd76a6a5aaf84ef759053d7bde4001a Mon Sep 17 00:00:00 2001 From: Charles Krinke Date: Sat, 19 Jul 2008 14:45:10 +0000 Subject: Mantis#1785. Thank you kindly, Junta_Kohime for a patch that" llAxes2Rot now implemented. Important note: quaternion is equal to <-x,-y,-z,-s>. The result may be different from LSL output, but it is correct. A problem of rounding caused an error of square rooting of zero as negative number, corrected by squaring again. Function tested 360° along 3 axes. Vector fwd, left and up have to be normalized. --- .../ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 34 ++++++++++++++++++++-- .../Shared/Api/Implementation/LSL_Api.cs | 33 +++++++++++++++++++-- 2 files changed, 62 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 682d566..40e225d 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -423,10 +423,38 @@ namespace OpenSim.Region.ScriptEngine.Common public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) { m_host.AddScriptLPS(1); - NotImplemented("llAxes2Rot"); - return new LSL_Types.Quaternion(); + double x,y,z,s; + int f=0; + // Important Note: q1= is equal to q2=<-x,-y,-z,-s> + // Computing quaternion x,y,z,s values + x=((fwd.x-left.y-up.z+1)/4); + x*=x; + x=Math.Sqrt(Math.Sqrt(x)); + y=((1-up.z)/2-x*x); + y*=y; + y=Math.Sqrt(Math.Sqrt(y)); + z=((1-left.y)/2-x*x); + z*=z; + z=Math.Sqrt(Math.Sqrt(z)); + s=(1-x*x-y*y-z*z); + s*=s; + s=Math.Sqrt(Math.Sqrt(s)); + + // Set f for signs detection + if (fwd.y+left.x >= 0){f+=1;} + if (fwd.z+up.x >= 0){f+=2;} + if (left.z-up.y >= 0){f+=4;} + // Set correct quaternion signs based on f value + if (f==0){x=-x;} + if (f==1){x=-x;y=-y;} + if (f==2){x=-x;z=-z;} + if (f==3){s=-s;} + if (f==4){x=-x;s=-s;} + if (f==5){z=-z;} + if (f==6){y=-y;} + return new LSL_Types.Quaternion(x, y, z, s); } - + public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c3255b1..c597661 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -410,8 +410,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) { m_host.AddScriptLPS(1); - NotImplemented("llAxes2Rot"); - return new LSL_Types.Quaternion(); + double x,y,z,s; + int f=0; + // Important Note: q1= is equal to q2=<-x,-y,-z,-s> + // Computing quaternion x,y,z,s values + x=((fwd.x-left.y-up.z+1)/4); + x*=x; + x=Math.Sqrt(Math.Sqrt(x)); + y=((1-up.z)/2-x*x); + y*=y; + y=Math.Sqrt(Math.Sqrt(y)); + z=((1-left.y)/2-x*x); + z*=z; + z=Math.Sqrt(Math.Sqrt(z)); + s=(1-x*x-y*y-z*z); + s*=s; + s=Math.Sqrt(Math.Sqrt(s)); + + // Set f for signs detection + if (fwd.y+left.x >= 0){f+=1;} + if (fwd.z+up.x >= 0){f+=2;} + if (left.z-up.y >= 0){f+=4;} + // Set correct quaternion signs based on f value + if (f==0){x=-x;} + if (f==1){x=-x;y=-y;} + if (f==2){x=-x;z=-z;} + if (f==3){s=-s;} + if (f==4){x=-x;s=-s;} + if (f==5){z=-z;} + if (f==6){y=-y;} + return new LSL_Types.Quaternion(x, y, z, s); + } public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) -- cgit v1.1