You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			103 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			103 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
 | 
						|
namespace RootMotion.FinalIK {
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Using a spline to limit the range of rotation on universal and ball-and-socket joints. 
 | 
						|
	/// Reachable area is defined by an AnimationCurve orthogonally mapped onto a sphere.
 | 
						|
	/// </summary>
 | 
						|
	[HelpURL("http://www.root-motion.com/finalikdox/html/page14.html")]
 | 
						|
	[AddComponentMenu("Scripts/RootMotion.FinalIK/Rotation Limits/Rotation Limit Spline")]
 | 
						|
	public class RotationLimitSpline : RotationLimit {
 | 
						|
 | 
						|
		// Open the User Manual URL
 | 
						|
		[ContextMenu("User Manual")]
 | 
						|
		private void OpenUserManual() {
 | 
						|
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/page14.html");
 | 
						|
		}
 | 
						|
		
 | 
						|
		// Open the Script Reference URL
 | 
						|
		[ContextMenu("Scrpt Reference")]
 | 
						|
		private void OpenScriptReference() {
 | 
						|
			Application.OpenURL("http://www.root-motion.com/finalikdox/html/class_root_motion_1_1_final_i_k_1_1_rotation_limit_spline.html");
 | 
						|
		}
 | 
						|
		
 | 
						|
		// Link to the Final IK Google Group
 | 
						|
		[ContextMenu("Support Group")]
 | 
						|
		void SupportGroup() {
 | 
						|
			Application.OpenURL("https://groups.google.com/forum/#!forum/final-ik");
 | 
						|
		}
 | 
						|
		
 | 
						|
		// Link to the Final IK Asset Store thread in the Unity Community
 | 
						|
		[ContextMenu("Asset Store Thread")]
 | 
						|
		void ASThread() {
 | 
						|
			Application.OpenURL("http://forum.unity3d.com/threads/final-ik-full-body-ik-aim-look-at-fabrik-ccd-ik-1-0-released.222685/");
 | 
						|
		}
 | 
						|
 | 
						|
		#region Main Interface
 | 
						|
		
 | 
						|
		/// <summary>
 | 
						|
		/// Limit of twist rotation around the main axis.
 | 
						|
		/// </summary>
 | 
						|
		[Range(0f, 180f)] public float twistLimit = 180;
 | 
						|
		
 | 
						|
		/// <summary>
 | 
						|
		/// Set the spline keyframes.
 | 
						|
		/// </summary>
 | 
						|
		/// <param name='keyframes'>
 | 
						|
		/// Keyframes.
 | 
						|
		/// </param>
 | 
						|
		public void SetSpline(Keyframe[] keyframes) {
 | 
						|
			spline.keys = keyframes;
 | 
						|
		}
 | 
						|
 | 
						|
        /*
 | 
						|
		 * The AnimationCurve orthogonally mapped onto a sphere that defines the swing limits
 | 
						|
		 * */
 | 
						|
        [HideInInspector] public AnimationCurve spline;
 | 
						|
 | 
						|
        #endregion Main Interface
 | 
						|
 | 
						|
        /*
 | 
						|
		 * Limits the rotation in the local space of this instance's Transform.
 | 
						|
		 * */
 | 
						|
        protected override Quaternion LimitRotation(Quaternion rotation) {		
 | 
						|
			// Subtracting off-limits swing
 | 
						|
			Quaternion swing = LimitSwing(rotation);
 | 
						|
			
 | 
						|
			// Apply twist limits
 | 
						|
			return LimitTwist(swing, axis, secondaryAxis, twistLimit);
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*
 | 
						|
		 * Apply the swing rotation limits
 | 
						|
		 * */
 | 
						|
		public Quaternion LimitSwing(Quaternion rotation) {
 | 
						|
			if (axis == Vector3.zero) return rotation; // Ignore with zero axes
 | 
						|
			if (rotation == Quaternion.identity) return rotation; // Assuming initial rotation is in the reachable area
 | 
						|
			
 | 
						|
			// Get the rotation angle orthogonal to Axis
 | 
						|
			Vector3 swingAxis = rotation * axis;
 | 
						|
			float angle = GetOrthogonalAngle(swingAxis, secondaryAxis, axis);
 | 
						|
			
 | 
						|
			// Convert angle from 180 to 360 degrees representation
 | 
						|
			float dot = Vector3.Dot(swingAxis, crossAxis);
 | 
						|
			if (dot < 0) angle = 180 + (180 - angle);
 | 
						|
			
 | 
						|
			// Evaluate the limit for this angle
 | 
						|
			float limit = spline.Evaluate(angle);
 | 
						|
			
 | 
						|
			// Get the limited swing axis
 | 
						|
			Quaternion swingRotation = Quaternion.FromToRotation(axis, swingAxis);
 | 
						|
			Quaternion limitedSwingRotation = Quaternion.RotateTowards(Quaternion.identity, swingRotation, limit);
 | 
						|
			
 | 
						|
			// Rotation from current(illegal) swing rotation to the limited(legal) swing rotation
 | 
						|
			Quaternion toLimits = Quaternion.FromToRotation(swingAxis, limitedSwingRotation * axis);
 | 
						|
			
 | 
						|
			// Subtract the illegal rotation
 | 
						|
			return toLimits * rotation;
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |