aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
authordahlia2015-02-06 22:36:26 -0800
committerdahlia2015-02-06 22:36:26 -0800
commit506e62f81548200899b5b4f844f91582ad358962 (patch)
tree0c63310982cfc66839f6dc058a16f29b9f8c368c /OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
parentManage Angular Velocity during llLookAt() rotation of physical objects (diff)
downloadopensim-SC-506e62f81548200899b5b4f844f91582ad358962.zip
opensim-SC-506e62f81548200899b5b4f844f91582ad358962.tar.gz
opensim-SC-506e62f81548200899b5b4f844f91582ad358962.tar.bz2
opensim-SC-506e62f81548200899b5b4f844f91582ad358962.tar.xz
llLookAt() and llRotLookAt(): all orientation updates now done via angular velocity manipulation. Also correct some orientation glitches during interpolation.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs45
1 files changed, 28 insertions, 17 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 887c7fc..ea0245c 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4881,28 +4881,39 @@ namespace OpenSim.Region.Framework.Scenes
4881 { 4881 {
4882 if (APIDTarget != Quaternion.Identity) 4882 if (APIDTarget != Quaternion.Identity)
4883 { 4883 {
4884 4884 PhysicsActor pa = ParentGroup.RootPart.PhysActor;
4885 if (m_APIDIterations <= 1) 4885 if (pa == null || !pa.IsPhysical)
4886 { 4886 {
4887 AngularVelocity = Vector3.Zero; 4887 StopLookAt();
4888 UpdateRotation(APIDTarget);
4889 APIDTarget = Quaternion.Identity;
4890 return; 4888 return;
4891 } 4889 }
4892 4890
4893 Quaternion rot = Quaternion.Slerp(RotationOffset,APIDTarget,1.0f/(float)m_APIDIterations); 4891 Quaternion currRot = GetWorldRotation();
4894 rot.Normalize(); 4892 currRot.Normalize();
4893
4894 // difference between current orientation and desired orientation
4895 Quaternion dR = new Quaternion(currRot.X, currRot.Y, currRot.Z, -currRot.W) * APIDTarget;
4896
4897 // find axis of rotation to rotate to desired orientation
4898 Vector3 axis = Vector3.UnitX;
4899 float s = (float)Math.Sqrt(1.0f - dR.W * dR.W);
4900 if (s >= 0.001)
4901 {
4902 float invS = 1.0f / s;
4903 if (dR.W < 0) invS = -invS;
4904 axis = new Vector3(dR.X * invS, dR.Y * invS, dR.Z * invS) * currRot;
4905 axis.Normalize();
4906 }
4895 4907
4896 Quaternion dR = rot / RotationOffset; 4908 // angle between current and desired orientation
4897 Vector3 axis; 4909 float angle = 2.0f * (float)Math.Acos(dR.W);
4898 float angle; 4910 if (angle > Math.PI)
4899 dR.GetAxisAngle(out axis, out angle); 4911 angle = 2.0f * (float)Math.PI - angle;
4900 axis *= RotationOffset; 4912
4901 axis.Normalize(); 4913 // set angular velocity to rotate to desired orientation
4902 axis *= angle / 11; // simulator update frequency is 10-11 Hz 4914 // with velocity proportional to strength and angle
4903 AngularVelocity = axis; 4915 // the factor of 10 seems to make rotation speed closer to LL implementation
4904 4916 AngularVelocity = axis * angle * APIDStrength * (float)Math.PI * 10.0f;
4905 m_APIDIterations--;
4906 4917
4907 // This ensures that we'll check this object on the next iteration 4918 // This ensures that we'll check this object on the next iteration
4908 ParentGroup.QueueForUpdateCheck(); 4919 ParentGroup.QueueForUpdateCheck();