From e1a2c44ebe8f10cf00a14578e44b000ff16b68df Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 13 Jan 2012 14:48:56 -0800 Subject: Cleaned up the LookAt code in SOP and SOG. Added support for incrementally rotating physical objects. This does not use physics. Currently the rate of change is determined as 1 / (PI * Strength). --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 6 -- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 69 ++++++++++------------ .../Shared/Api/Implementation/LSL_Api.cs | 8 +-- 3 files changed, 34 insertions(+), 49 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8860764..cad09b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1613,12 +1613,6 @@ namespace OpenSim.Region.Framework.Scenes RootPart.PhysActor.PIDActive = false; } - public void stopLookAt() - { - if (RootPart.PhysActor != null) - RootPart.PhysActor.APIDActive = false; - } - /// /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e9c33eb..ad3bcd5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -217,11 +217,10 @@ namespace OpenSim.Region.Framework.Scenes public Quaternion SpinOldOrientation = Quaternion.Identity; - public Quaternion m_APIDTarget = Quaternion.Identity; - - public float m_APIDDamp = 0; - - public float m_APIDStrength = 0; + protected int m_APIDIterations = 0; + protected Quaternion m_APIDTarget = Quaternion.Identity; + protected float m_APIDDamp = 0; + protected float m_APIDStrength = 0; /// /// This part's inventory @@ -563,22 +562,21 @@ namespace OpenSim.Region.Framework.Scenes } } - - public Quaternion APIDTarget + protected Quaternion APIDTarget { get { return m_APIDTarget; } set { m_APIDTarget = value; } } - public float APIDDamp + protected float APIDDamp { get { return m_APIDDamp; } set { m_APIDDamp = value; } } - public float APIDStrength + protected float APIDStrength { get { return m_APIDStrength; } set { m_APIDStrength = value; } @@ -2697,11 +2695,6 @@ namespace OpenSim.Region.Framework.Scenes public void RotLookAt(Quaternion target, float strength, float damping) { - rotLookAt(target, strength, damping); - } - - public void rotLookAt(Quaternion target, float strength, float damping) - { if (ParentGroup.IsAttachment) { /* @@ -2716,17 +2709,26 @@ namespace OpenSim.Region.Framework.Scenes APIDDamp = damping; APIDStrength = strength; APIDTarget = target; + + if (APIDStrength <= 0) + { + m_log.WarnFormat("[SceneObjectPart] Invalid rotation strength {0}",APIDStrength); + return; + } + + m_APIDIterations = 1 + (int)(Math.PI * APIDStrength); } + + // Necessary to get the lookat deltas applied + ParentGroup.QueueForUpdateCheck(); } - public void startLookAt(Quaternion rot, float damp, float strength) + public void StartLookAt(Quaternion target, float strength, float damping) { - APIDDamp = damp; - APIDStrength = strength; - APIDTarget = rot; + RotLookAt(target,strength,damping); } - public void stopLookAt() + public void StopLookAt() { APIDTarget = Quaternion.Identity; } @@ -3417,13 +3419,6 @@ namespace OpenSim.Region.Framework.Scenes } } - public void StopLookAt() - { - ParentGroup.stopLookAt(); - - ParentGroup.ScheduleGroupForTerseUpdate(); - } - /// /// Set the text displayed for this part. /// @@ -4731,24 +4726,20 @@ namespace OpenSim.Region.Framework.Scenes { if (APIDTarget != Quaternion.Identity) { - if (Single.IsNaN(APIDTarget.W) == true) + if (m_APIDIterations <= 1) { + UpdateRotation(APIDTarget); APIDTarget = Quaternion.Identity; return; } - Quaternion rot = RotationOffset; - Quaternion dir = (rot - APIDTarget); - float speed = ((APIDStrength / APIDDamp) * (float)(Math.PI / 180.0f)); - if (dir.Z > speed) - { - rot.Z -= speed; - } - if (dir.Z < -speed) - { - rot.Z += speed; - } - rot.Normalize(); + + Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations); UpdateRotation(rot); + + m_APIDIterations--; + + // This ensures that we'll check this object on the next iteration + ParentGroup.QueueForUpdateCheck(); } } catch (Exception ex) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 30145c7..ab175ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2865,13 +2865,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior - if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) + if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) { llSetRot(rot); } else { - m_host.startLookAt(Rot2Quaternion(rot), (float)damping, (float)strength); + m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); } } @@ -3251,13 +3251,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Per discussion with Melanie, for non-physical objects llLookAt appears to simply // set the rotation of the object, copy that behavior - if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) + if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) { llSetLocalRot(target); } else { - m_host.RotLookAt(Rot2Quaternion(target), (float)damping, (float)strength); + m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); } } -- cgit v1.1