From 4e0bb49394d303c7c7707f85b02e47b7c2053201 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 23 Jan 2012 13:48:16 +0100 Subject: [PATCH] Fix llLookAt the right way --- .../Shared/Api/Implementation/LSL_Api.cs | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ac22638718..7af5d2ded6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3040,34 +3040,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llLookAt(LSL_Vector target, double strength, double damping) { m_host.AddScriptLPS(1); - // Determine where we are looking from - LSL_Vector from = llGetPos(); - // Work out the normalised vector from the source to the target - LSL_Vector delta = llVecNorm(target - from); - LSL_Vector angle = new LSL_Vector(0,0,0); + // Get the normalized vector to the target + LSL_Vector d1 = llVecNorm(target - llGetPos()); - // Calculate the yaw - // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system - angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; + // Get the bearing (yaw) + LSL_Vector a1 = new LSL_Vector(0,0,0); + a1.z = llAtan2(d1.y, d1.x); - // Calculate pitch - angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); + // Get the elevation (pitch) + LSL_Vector a2 = new LSL_Vector(0,0,0); + a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y))); - // we need to convert from a vector describing - // the angles of rotation in radians into rotation value + LSL_Rotation r1 = llEuler2Rot(a1); + LSL_Rotation r2 = llEuler2Rot(a2); + LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107); - LSL_Rotation rot = llEuler2Rot(angle); - - // Per discussion with Melanie, for non-physical objects llLookAt appears to simply - // set the rotation of the object, copy that behavior - if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) + if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) { - llSetRot(rot); + // Do nothing if either value is 0 (this has been checked in SL) + if (strength <= 0.0 || damping <= 0.0) + return; + + llSetRot(r3 * r2 * r1); } else { - m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); + if (strength == 0) + { + llSetRot(r3 * r2 * r1); + return; + } + + m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping); } }