Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
integrated recent commits by Dahlia regarding llLookAt handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ft committed Feb 13, 2015
1 parent de0c097 commit 2063129
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 23 deletions.
46 changes: 38 additions & 8 deletions OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,13 @@ public Vector3 AngularVelocity
}
return m_angularVelocity;
}
set { m_angularVelocity = value; }
set
{
m_angularVelocity = value;
PhysicsActor actor = PhysActor;
if ((actor != null) && actor.IsPhysical)
actor.RotationalVelocity = m_angularVelocity;
}
}

/// <summary></summary>
Expand Down Expand Up @@ -4853,18 +4859,42 @@ public void UpdateLookAt()
{
if (APIDTarget != Quaternion.Identity)
{
if (m_APIDIterations <= 1)
PhysicsActor pa = ParentGroup.RootPart.PhysActor;
if (pa == null || !pa.IsPhysical || APIDStrength < 0.04)
{
UpdateRotation(APIDTarget);
APIDTarget = Quaternion.Identity;
StopLookAt();
return;
}

Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations);
rot.Normalize();
UpdateRotation(rot);
Quaternion currRot = WorldRotation;
currRot.Normalize();

// difference between current orientation and desired orientation
Quaternion dR = new Quaternion(currRot.X, currRot.Y, currRot.Z, -currRot.W) * APIDTarget;

// find axis of rotation to rotate to desired orientation
Vector3 axis = Vector3.UnitX;
float s = (float)Math.Sqrt(1.0f - dR.W * dR.W);
if (s >= 0.001)
{
float invS = 1.0f / s;
if (dR.W < 0) invS = -invS;
axis = new Vector3(dR.X * invS, dR.Y * invS, dR.Z * invS) * currRot;
axis.Normalize();
}

// angle between current and desired orientation
float angle = 2.0f * (float)Math.Acos(dR.W);
if (angle > Math.PI)
angle = 2.0f * (float)Math.PI - angle;

// clamp strength to avoid overshoot
float strength = 1.0f / APIDStrength;
if (strength > 1.0) strength = 1.0f;

m_APIDIterations--;
// set angular velocity to rotate to desired orientation
// with velocity proportional to strength and angle
AngularVelocity = axis * angle * strength * (float)Math.PI;

// This ensures that we'll check this object on the next iteration
ParentGroup.QueueForUpdateCheck();
Expand Down
9 changes: 9 additions & 0 deletions OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,14 @@ private void setMass()
}
}

private void setAngularVelocity(float x, float y, float z)
{
if (Body != (IntPtr)0)
{
d.BodySetAngularVel(Body, x, y, z);
}
}

/// <summary>
/// Stop a prim from being subject to physics.
/// </summary>
Expand Down Expand Up @@ -2650,6 +2658,7 @@ public override Vector3 RotationalVelocity
if (value.IsFinite())
{
m_rotationalVelocity = value;
setAngularVelocity(value.X, value.Y, value.Z);
}
else
{
Expand Down
27 changes: 12 additions & 15 deletions OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3049,20 +3049,17 @@ public void llLookAt(LSL_Vector target, double strength, double damping)
// 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);

// 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;

// Calculate pitch
angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z)));

// we need to convert from a vector describing
// the angles of rotation in radians into rotation value
LSL_Rotation rot = llEuler2Rot(angle);
// normalized direction to target
LSL_Vector dir = llVecNorm(target - from);
// use vertical to help compute left axis
LSL_Vector up = new LSL_Vector(0.0, 0.0, 1.0);
// find normalized left axis parallel to horizon
LSL_Vector left = llVecNorm(LSL_Vector.Cross(up, dir));
// make up orthogonal to left and dir
up = LSL_Vector.Cross(dir, left);

// compute rotation based on orthogonal axes
LSL_Rotation rot = new LSL_Rotation(0.0, 0.707107, 0.0, 0.707107) * llAxes2Rot(dir, left, up);

// Per discussion with Melanie, for non-physical objects llLookAt appears to simply
// set the rotation of the object, copy that behavior
Expand Down Expand Up @@ -10090,7 +10087,7 @@ public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List
res.Add(new LSL_Vector(textColor.R,
textColor.G,
textColor.B));
res.Add(new LSL_Float(textColor.A));
res.Add(new LSL_Float(1 - textColor.A));
break;
case (int)ScriptBaseClass.PRIM_NAME:
res.Add(new LSL_String(part.Name));
Expand Down

0 comments on commit 2063129

Please sign in to comment.