/// <summary> /// Allows the motor to process after the camera and controller have completed /// </summary> public override void PostRigLateUpdate() { Transform lAnchor = Anchor; if (lAnchor != null) { mWasAnchorRotating = !QuaternionExt.IsEqual(mAnchorLastRotation, lAnchor.rotation); mAnchorLastPosition = lAnchor.position; mAnchorLastRotation = lAnchor.rotation; } mFocusLastPosition = GetFocusPosition(RigController._Transform.rotation); // Reset our internal rotation targets if (Mathf.Abs(_EulerTarget.y - _Euler.y) < EPSILON) { _Euler.y = LocalYaw; _EulerTarget.y = _Euler.y; mViewVelocityY = 0f; } // Reset our internal rotation targets if (Mathf.Abs(_EulerTarget.x - _Euler.x) < EPSILON) { _Euler.x = LocalPitch; _EulerTarget.x = _Euler.x; mViewVelocityX = 0f; } base.PostRigLateUpdate(); }
/// <summary> /// Allow the joint to render it's own GUI. This GUI is used /// for displaying and manipulating the joint itself. /// </summary> /// <returns>Reports if the object's value was changed</returns> public override bool OnInspectorManipulatorGUI(IKBoneModifier rModifier) { #if UNITY_EDITOR // Determine if the swing is changing if (mBone != null) { Vector3 lSwing = rModifier.Swing.eulerAngles; Vector3 lNewSwing = InspectorHelper.Vector3Fields("Swing", "Euler angles to swing the bone.", lSwing, true, true, false); if (lNewSwing != lSwing) { // Grab the amount that was just rotated by based on the current rotation. // We do this so the change is relative to the current swing rotation Vector3 lDeltaRotations = lNewSwing - lSwing; rModifier.Swing = rModifier.Swing * Quaternion.Euler(lDeltaRotations); rModifier.IsDirty = true; } // Determine if the twist is changing //float lTwist = mBone.Twist.eulerAngles.y; float lTwist = Vector3Ext.SignedAngle(Vector3.up, rModifier.Twist * Vector3.up, Vector3.forward); float lNewTwist = EditorGUILayout.FloatField("Twist", lTwist); if (_AllowTwist && lNewTwist != lTwist) { rModifier.Twist = Quaternion.AngleAxis(lNewTwist, Vector3.forward); rModifier.IsDirty = true; } // Reset the values if needed if (GUILayout.Button("reset rotation", EditorStyles.miniButton)) { rModifier.Swing = Quaternion.identity; rModifier.Twist = (_AllowTwist ? Quaternion.identity : mBone._Twist); rModifier.IsDirty = true; mBone._Transform.localRotation = mBone._BindRotation; } if (rModifier.IsDirty) { // Before we go to far, see if we are within the joint limits. If not, // we need to go back to a good position. bool lIsInLimits = ApplyLimits(ref rModifier.Swing, ref rModifier.Twist); if (lIsInLimits || QuaternionExt.IsEqual(rModifier.Swing, Quaternion.identity)) { mLastSwing = rModifier.Swing; mLastTwist = rModifier.Twist; } else { rModifier.Swing = mLastSwing; rModifier.Twist = mLastTwist; } } } #endif return(rModifier.IsDirty); }
/// <summary> /// Causes us to ignore user input and force the camera to the specified localangles /// </summary> /// <param name="rYaw">Target local yaw</param> /// <param name="rPitch">Target local pitch</param> /// <param name="rSpeed">Degrees per second we'll rotate</param> public void SetTargetYawPitch(float rYaw, float rPitch, float rSpeed = -1f, bool rAutoClearTarget = true) { ClearTargetForward(); mTargetYaw = rYaw; mTargetPitch = rPitch; mAutoClearTarget = rAutoClearTarget; float lDeltaYaw = Mathf.Abs(mTargetYaw - LocalYaw); float lDeltaPitch = Mathf.Abs(mTargetPitch - LocalPitch); if (rSpeed > 0f) { float lTime = (lDeltaYaw >= lDeltaPitch ? lDeltaYaw / rSpeed : lDeltaPitch / rSpeed); if (lTime > 0f) { mTargetYawSpeed = lDeltaYaw / lTime; mTargetPitchSpeed = lDeltaPitch / lTime; } } else if (rSpeed == 0f) { mTargetYawSpeed = 0f; mTargetPitchSpeed = 0f; } else { float lAnchorRotatingMultiplier = 1f; if (mWasAnchorRotating) { lAnchorRotatingMultiplier = _TargetRotationMultiplier; } else if (Anchor != null && !QuaternionExt.IsEqual(mAnchorLastRotation, Anchor.rotation)) { lAnchorRotatingMultiplier = _TargetRotationMultiplier; } mTargetYawSpeed = _YawSpeed * lAnchorRotatingMultiplier; mTargetPitchSpeed = _PitchSpeed * lAnchorRotatingMultiplier; } }
/// <summary> /// Allows us to render joint info into the scene. This GUI is /// used for displaying and manipulating the joint itself. /// </summary> /// <returns>Reports if the object's value was changed</returns> public override bool OnSceneManipulatorGUI(IKBoneModifier rModifier) { #if UNITY_EDITOR //Quaternion lSwing = mBone.Swing; //Quaternion lTwist = mBone.Twist; bool lIsSwingDirty = HandlesHelper.JointSwingHandle(mBone, rModifier); if (lIsSwingDirty) { //rModifier.Swing = lSwing; rModifier.IsDirty = true; } bool lIsTwistDirty = HandlesHelper.JointTwistHandle(mBone, rModifier); if (lIsTwistDirty) { //rModifier.Twist = lTwist; rModifier.IsDirty = true; } if (rModifier.IsDirty) { // Before we go to far, see if we are within the joint limits. If not, // we need to go back to a good position. bool lIsInLimits = ApplyLimits(ref rModifier.Swing, ref rModifier.Twist); if (lIsInLimits || QuaternionExt.IsEqual(rModifier.Swing, Quaternion.identity)) { mLastSwing = rModifier.Swing; mLastTwist = rModifier.Twist; } else { rModifier.Swing = mLastSwing; rModifier.Twist = mLastTwist; } } #endif return(rModifier.IsDirty); }