From 08f3d212ce71de0b3bbedcc57bd6c60644bd445c Mon Sep 17 00:00:00 2001 From: Dahlia Trimble Date: Mon, 21 Jul 2008 05:34:31 +0000 Subject: does some verification of the quaternion returned by llAxes2Rot and modifies the sign of the s term if a discrepency is found. This helps llAxes2Rot more closely match the Linden implementation. --- .../ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 51 +++++++++------- .../Shared/Api/Implementation/LSL_Api.cs | 70 ++++++++++++---------- 2 files changed, 69 insertions(+), 52 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 7745d95..bea805e 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -427,32 +427,41 @@ namespace OpenSim.Region.ScriptEngine.Common 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)); - + 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); + 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; } + + LSL_Types.Quaternion result = new LSL_Types.Quaternion(x, y, z, s); + + // a hack to correct a few questionable angles :( + LSL_Types.Vector3 fwdTest = new LSL_Types.Vector3(1, 0, 0); + LSL_Types.Vector3 leftTest = new LSL_Types.Vector3(0, 1, 0); + if (llVecDist(fwdTest * result, fwd) > 0.001 || llVecDist(leftTest * result, left) > 0.001) + result.s = -s; + + return result; } public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 79bd6fe..9b860f5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -406,41 +406,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Types.Quaternion(x, y, z, s); } - + public LSL_Types.Quaternion llAxes2Rot(LSL_Types.Vector3 fwd, LSL_Types.Vector3 left, LSL_Types.Vector3 up) { m_host.AddScriptLPS(1); - 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); + 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; } + + LSL_Types.Quaternion result = new LSL_Types.Quaternion(x, y, z, s); + + // a hack to correct a few questionable angles :( + LSL_Types.Vector3 fwdTest = new LSL_Types.Vector3(1, 0, 0); + LSL_Types.Vector3 leftTest = new LSL_Types.Vector3(0, 1, 0); + if (llVecDist(fwdTest * result, fwd) > 0.001 || llVecDist(leftTest * result, left) > 0.001) + result.s = -s; + return result; } public LSL_Types.Vector3 llRot2Fwd(LSL_Types.Quaternion r) -- cgit v1.1