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.
		
		
		
		
		
			
		
			
				
	
	
		
			185 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			185 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C#
		
	
using UnityEngine;
 | 
						|
using System.Collections;
 | 
						|
 | 
						|
namespace RootMotion.FinalIK {
 | 
						|
 | 
						|
	/// <summary>
 | 
						|
	/// Maps a 3-segmented bone hierarchy to a node chain of an %IK Solver
 | 
						|
	/// </summary>
 | 
						|
	[System.Serializable]
 | 
						|
	public class IKMappingLimb: IKMapping {
 | 
						|
		
 | 
						|
		#region Main Interface
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Limb Bone Map type
 | 
						|
		/// </summary>
 | 
						|
		[System.Serializable]
 | 
						|
		public enum BoneMapType {
 | 
						|
			Parent,
 | 
						|
			Bone1,
 | 
						|
			Bone2,
 | 
						|
			Bone3
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// The optional parent bone (clavicle).
 | 
						|
		/// </summary>
 | 
						|
		public Transform parentBone;
 | 
						|
		/// <summary>
 | 
						|
		/// The first bone (upper arm or thigh).
 | 
						|
		/// </summary>
 | 
						|
		public Transform bone1;
 | 
						|
		/// <summary>
 | 
						|
		/// The second bone (forearm or calf).
 | 
						|
		/// </summary>
 | 
						|
		public Transform bone2;
 | 
						|
		/// <summary>
 | 
						|
		/// The third bone (hand or foot).
 | 
						|
		/// </summary>
 | 
						|
		public Transform bone3;
 | 
						|
		/// <summary>
 | 
						|
		/// The weight of maintaining the third bone's rotation as it was in the animation
 | 
						|
		/// </summary>
 | 
						|
		[Range(0f, 1f)]
 | 
						|
		public float maintainRotationWeight;
 | 
						|
		/// <summary>
 | 
						|
		/// The weight of mapping the limb to its IK pose. This can be useful if you want to disable the effect of IK for the limb.
 | 
						|
		/// </summary>
 | 
						|
		[Range(0f, 1f)]
 | 
						|
		public float weight = 1f; // Added in 0.2
 | 
						|
        /// <summary>
 | 
						|
        /// Disable this to maintain original sampled rotations of the limb bones relative to each other.
 | 
						|
        /// </summary>
 | 
						|
        [System.NonSerializedAttribute] public bool updatePlaneRotations = true;
 | 
						|
 | 
						|
        /// <summary>
 | 
						|
        /// Determines whether this IKMappingLimb is valid
 | 
						|
        /// </summary>
 | 
						|
        public override bool IsValid(IKSolver solver, ref string message) {
 | 
						|
			if (!base.IsValid(solver, ref message)) return false;
 | 
						|
			
 | 
						|
			if (!BoneIsValid(bone1, solver, ref message)) return false;
 | 
						|
			if (!BoneIsValid(bone2, solver, ref message)) return false;
 | 
						|
			if (!BoneIsValid(bone3, solver, ref message)) return false;
 | 
						|
			
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Gets the bone map of the specified bone.
 | 
						|
		/// </summary>
 | 
						|
		public BoneMap GetBoneMap(BoneMapType boneMap) {
 | 
						|
			switch(boneMap) {
 | 
						|
			case BoneMapType.Parent:
 | 
						|
				if (parentBone == null) Warning.Log("This limb does not have a parent (shoulder) bone", bone1);
 | 
						|
				return boneMapParent;
 | 
						|
			case BoneMapType.Bone1: return boneMap1;
 | 
						|
			case BoneMapType.Bone2: return boneMap2;
 | 
						|
			default: return boneMap3;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		/// <summary>
 | 
						|
		/// Makes the limb mapped to the specific local directions of the bones. Added in 0.3
 | 
						|
		/// </summary>
 | 
						|
		public void SetLimbOrientation(Vector3 upper, Vector3 lower) {
 | 
						|
			boneMap1.defaultLocalTargetRotation = Quaternion.Inverse(Quaternion.Inverse(bone1.rotation) * Quaternion.LookRotation(bone2.position - bone1.position, bone1.rotation * -upper));
 | 
						|
			boneMap2.defaultLocalTargetRotation = Quaternion.Inverse(Quaternion.Inverse(bone2.rotation) * Quaternion.LookRotation(bone3.position - bone2.position, bone2.rotation * -lower));
 | 
						|
		}
 | 
						|
		
 | 
						|
		#endregion Main Interface
 | 
						|
		
 | 
						|
		private BoneMap boneMapParent = new BoneMap(), boneMap1 = new BoneMap(), boneMap2 = new BoneMap(), boneMap3 = new BoneMap();
 | 
						|
		
 | 
						|
		public IKMappingLimb() {}
 | 
						|
		
 | 
						|
		public IKMappingLimb(Transform bone1, Transform bone2, Transform bone3, Transform parentBone = null) {
 | 
						|
			SetBones(bone1, bone2, bone3, parentBone);
 | 
						|
		}
 | 
						|
		
 | 
						|
		public void SetBones(Transform bone1, Transform bone2, Transform bone3, Transform parentBone = null) {
 | 
						|
			this.bone1 = bone1;
 | 
						|
			this.bone2 = bone2;
 | 
						|
			this.bone3 = bone3;
 | 
						|
			this.parentBone = parentBone;
 | 
						|
		}
 | 
						|
		
 | 
						|
		public void StoreDefaultLocalState() {
 | 
						|
			if (parentBone != null) boneMapParent.StoreDefaultLocalState();
 | 
						|
			boneMap1.StoreDefaultLocalState();
 | 
						|
			boneMap2.StoreDefaultLocalState();
 | 
						|
			boneMap3.StoreDefaultLocalState();
 | 
						|
		}
 | 
						|
		
 | 
						|
		public void FixTransforms() {
 | 
						|
			if (parentBone != null) boneMapParent.FixTransform(false);
 | 
						|
			boneMap1.FixTransform(true);
 | 
						|
			boneMap2.FixTransform(false);
 | 
						|
			boneMap3.FixTransform(false);
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*
 | 
						|
		 * Initiating and setting defaults
 | 
						|
		 * */
 | 
						|
		public override void Initiate(IKSolverFullBody solver) {
 | 
						|
			if (boneMapParent == null) boneMapParent = new BoneMap();
 | 
						|
			if (boneMap1 == null) boneMap1 = new BoneMap();
 | 
						|
			if (boneMap2 == null) boneMap2 = new BoneMap();
 | 
						|
			if (boneMap3 == null) boneMap3 = new BoneMap();
 | 
						|
 | 
						|
			// Finding the nodes
 | 
						|
			if (parentBone != null) boneMapParent.Initiate(parentBone, solver);
 | 
						|
			boneMap1.Initiate(bone1, solver);
 | 
						|
			boneMap2.Initiate(bone2, solver);
 | 
						|
			boneMap3.Initiate(bone3, solver);
 | 
						|
 | 
						|
			// Define plane points for the bone maps
 | 
						|
			boneMap1.SetPlane(solver, boneMap1.transform, boneMap2.transform, boneMap3.transform);
 | 
						|
			boneMap2.SetPlane(solver, boneMap2.transform, boneMap3.transform, boneMap1.transform);
 | 
						|
 | 
						|
			// Find the swing axis for the parent bone
 | 
						|
			if (parentBone != null) boneMapParent.SetLocalSwingAxis(boneMap1);
 | 
						|
		}
 | 
						|
		
 | 
						|
		/*
 | 
						|
		 * Presolving the bones and maintaining rotation
 | 
						|
		 * */
 | 
						|
		public void ReadPose() {
 | 
						|
            boneMap1.UpdatePlane(updatePlaneRotations, true);
 | 
						|
            boneMap2.UpdatePlane(updatePlaneRotations, false);
 | 
						|
 | 
						|
            // Clamping weights
 | 
						|
            weight = Mathf.Clamp(weight, 0f, 1f);
 | 
						|
 | 
						|
			// Define plane points for the bone maps
 | 
						|
			boneMap3.MaintainRotation();
 | 
						|
		}
 | 
						|
 | 
						|
		public void WritePose(IKSolverFullBody solver, bool fullBody) {
 | 
						|
			if (weight <= 0f) return;
 | 
						|
 | 
						|
			// Swing the parent bone to look at the first node's position
 | 
						|
			if (fullBody) {
 | 
						|
				if (parentBone != null) {
 | 
						|
					boneMapParent.Swing(solver.GetNode(boneMap1.chainIndex, boneMap1.nodeIndex).solverPosition, weight);
 | 
						|
					//boneMapParent.Swing(boneMap1.node.solverPosition, weight);
 | 
						|
				}
 | 
						|
				
 | 
						|
				// Fix the first bone to its node
 | 
						|
				boneMap1.FixToNode(solver, weight);
 | 
						|
			}
 | 
						|
 | 
						|
			// Rotate the 2 first bones to the plane points
 | 
						|
			boneMap1.RotateToPlane(solver, weight);
 | 
						|
			boneMap2.RotateToPlane(solver, weight);
 | 
						|
 | 
						|
			// Rotate the third bone to the rotation it had before solving
 | 
						|
			boneMap3.RotateToMaintain(maintainRotationWeight * weight * solver.IKPositionWeight);
 | 
						|
			
 | 
						|
			// Rotate the third bone to the effector rotation
 | 
						|
			boneMap3.RotateToEffector(solver, weight);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |