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).
iar_mods
Mic Bowman 2012-01-13 14:48:56 -08:00
parent adea92f8b7
commit e1a2c44ebe
3 changed files with 34 additions and 49 deletions

View File

@ -1613,12 +1613,6 @@ namespace OpenSim.Region.Framework.Scenes
RootPart.PhysActor.PIDActive = false; RootPart.PhysActor.PIDActive = false;
} }
public void stopLookAt()
{
if (RootPart.PhysActor != null)
RootPart.PhysActor.APIDActive = false;
}
/// <summary> /// <summary>
/// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds.
/// </summary> /// </summary>

View File

@ -217,11 +217,10 @@ namespace OpenSim.Region.Framework.Scenes
public Quaternion SpinOldOrientation = Quaternion.Identity; public Quaternion SpinOldOrientation = Quaternion.Identity;
public Quaternion m_APIDTarget = Quaternion.Identity; protected int m_APIDIterations = 0;
protected Quaternion m_APIDTarget = Quaternion.Identity;
public float m_APIDDamp = 0; protected float m_APIDDamp = 0;
protected float m_APIDStrength = 0;
public float m_APIDStrength = 0;
/// <summary> /// <summary>
/// This part's inventory /// This part's inventory
@ -563,22 +562,21 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
protected Quaternion APIDTarget
public Quaternion APIDTarget
{ {
get { return m_APIDTarget; } get { return m_APIDTarget; }
set { m_APIDTarget = value; } set { m_APIDTarget = value; }
} }
public float APIDDamp protected float APIDDamp
{ {
get { return m_APIDDamp; } get { return m_APIDDamp; }
set { m_APIDDamp = value; } set { m_APIDDamp = value; }
} }
public float APIDStrength protected float APIDStrength
{ {
get { return m_APIDStrength; } get { return m_APIDStrength; }
set { m_APIDStrength = value; } set { m_APIDStrength = value; }
@ -2696,11 +2694,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
public void RotLookAt(Quaternion target, float strength, float damping) 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) if (ParentGroup.IsAttachment)
{ {
@ -2716,17 +2709,26 @@ namespace OpenSim.Region.Framework.Scenes
APIDDamp = damping; APIDDamp = damping;
APIDStrength = strength; APIDStrength = strength;
APIDTarget = target; 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; RotLookAt(target,strength,damping);
APIDStrength = strength;
APIDTarget = rot;
} }
public void stopLookAt() public void StopLookAt()
{ {
APIDTarget = Quaternion.Identity; APIDTarget = Quaternion.Identity;
} }
@ -3417,13 +3419,6 @@ namespace OpenSim.Region.Framework.Scenes
} }
} }
public void StopLookAt()
{
ParentGroup.stopLookAt();
ParentGroup.ScheduleGroupForTerseUpdate();
}
/// <summary> /// <summary>
/// Set the text displayed for this part. /// Set the text displayed for this part.
/// </summary> /// </summary>
@ -4731,24 +4726,20 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (APIDTarget != Quaternion.Identity) if (APIDTarget != Quaternion.Identity)
{ {
if (Single.IsNaN(APIDTarget.W) == true) if (m_APIDIterations <= 1)
{ {
UpdateRotation(APIDTarget);
APIDTarget = Quaternion.Identity; APIDTarget = Quaternion.Identity;
return; return;
} }
Quaternion rot = RotationOffset;
Quaternion dir = (rot - APIDTarget); Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations);
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();
UpdateRotation(rot); UpdateRotation(rot);
m_APIDIterations--;
// This ensures that we'll check this object on the next iteration
ParentGroup.QueueForUpdateCheck();
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -2865,13 +2865,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Per discussion with Melanie, for non-physical objects llLookAt appears to simply // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
// set the rotation of the object, copy that behavior // 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); llSetRot(rot);
} }
else 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 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
// set the rotation of the object, copy that behavior // 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); llSetLocalRot(target);
} }
else else
{ {
m_host.RotLookAt(Rot2Quaternion(target), (float)damping, (float)strength); m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
} }
} }