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#
		
	
| 
								 
											1 year ago
										 
									 | 
							
								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;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |