180 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			180 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								using UnityEngine;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace UnityEditor.U2D.Animation
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    internal static class SkeletonCacheExtensions
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        public static void RotateBones(this SkeletonCache skeleton, BoneCache[] bones, float deltaAngle)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								                
							 | 
						||
| 
								 | 
							
								                bone.localRotation *= Quaternion.AngleAxis(deltaAngle, Vector3.forward);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void MoveBones(this SkeletonCache skeleton, BoneCache[] bones, Vector3 deltaPosition)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                bone.position += deltaPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.parentBone != null && bone.parentBone.chainedChild == bone)
							 | 
						||
| 
								 | 
							
								                    bone.parentBone.OrientToChainedChild(false);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void FreeMoveBones(this SkeletonCache skeleton, BoneCache[] bones, Vector3 deltaPosition)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                var childrenWorldPose = bone.GetChildrenWoldPose();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.chainedChild != null && ArrayUtility.Contains(bones, bone.chainedChild) == false)
							 | 
						||
| 
								 | 
							
								                    bone.chainedChild = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.parentBone != null && bone.parentBone.chainedChild == bone && ArrayUtility.Contains(bones, bone.parentBone) == false)
							 | 
						||
| 
								 | 
							
								                    bone.parentBone.chainedChild = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                bone.position += deltaPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                bone.SetChildrenWorldPose(childrenWorldPose);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void MoveJoints(this SkeletonCache skeleton, BoneCache[] bones, Vector3 deltaPosition)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                var childrenWorldPose = bone.GetChildrenWoldPose();
							 | 
						||
| 
								 | 
							
								                var endPosition = bone.endPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                bone.position += deltaPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.localLength > 0f)
							 | 
						||
| 
								 | 
							
								                    bone.endPosition = endPosition;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.parentBone != null && bone.parentBone.chainedChild == bone)
							 | 
						||
| 
								 | 
							
								                    bone.parentBone.OrientToChainedChild(true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                bone.SetChildrenWorldPose(childrenWorldPose);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if (bone.chainedChild != null)
							 | 
						||
| 
								 | 
							
								                    bone.OrientToChainedChild(true);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void SetEndPosition(this SkeletonCache skeleton, BoneCache bone, Vector3 endPosition)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								            Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            var childrenStorage = bone.GetChildrenWoldPose();
							 | 
						||
| 
								 | 
							
								            bone.endPosition = endPosition;
							 | 
						||
| 
								 | 
							
								            bone.SetChildrenWorldPose(childrenStorage);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static BoneCache SplitBone(this SkeletonCache skeleton, BoneCache boneToSplit, float splitLength, string name)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton.Contains(boneToSplit));
							 | 
						||
| 
								 | 
							
								            Debug.Assert(boneToSplit.length > splitLength);
							 | 
						||
| 
								 | 
							
								            
							 | 
						||
| 
								 | 
							
								            var endPosition = boneToSplit.endPosition;
							 | 
						||
| 
								 | 
							
								            var chainedChild = boneToSplit.chainedChild;
							 | 
						||
| 
								 | 
							
								            var splitPosition = boneToSplit.position + boneToSplit.right * splitLength;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            boneToSplit.length = splitLength;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            var bone = skeleton.CreateBone(boneToSplit, splitPosition, endPosition, true, name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (chainedChild != null)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                chainedChild.SetParent(bone);
							 | 
						||
| 
								 | 
							
								                bone.chainedChild = chainedChild;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return bone;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static BoneCache CreateBone(this SkeletonCache skeleton, BoneCache parentBone, Vector3 position, Vector3 endPosition, bool isChained, string name)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (parentBone != null)
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(parentBone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            var bone = skeleton.skinningCache.CreateCache<BoneCache>();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            bone.SetParent(parentBone);
							 | 
						||
| 
								 | 
							
								            bone.name = name;
							 | 
						||
| 
								 | 
							
								            bone.bindPoseColor = ModuleUtility.CalculateNiceColor(skeleton.boneCount, 6);
							 | 
						||
| 
								 | 
							
								            bone.position = position;
							 | 
						||
| 
								 | 
							
								            bone.endPosition = endPosition;
							 | 
						||
| 
								 | 
							
								            bone.guid = GUID.Generate().ToString();
							 | 
						||
| 
								 | 
							
								            if (isChained && parentBone != null)
							 | 
						||
| 
								 | 
							
								                parentBone.chainedChild = bone;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            skeleton.AddBone(bone);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return bone;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void SetBones(this SkeletonCache skeleton, BoneCache[] bones)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            skeleton.SetBones(bones, true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void SetBones(this SkeletonCache skeleton, BoneCache[] bones, bool worldPositionStays)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            skeleton.Clear();
							 | 
						||
| 
								 | 
							
								            skeleton.AddBones(bones, worldPositionStays);
							 | 
						||
| 
								 | 
							
								            skeleton.SetDefaultPose();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void AddBones(this SkeletonCache skeleton, BoneCache[] bones)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            skeleton.AddBones(bones, true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void AddBones(this SkeletonCache skeleton, BoneCache[] bones, bool worldPositionStays)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								                skeleton.AddBone(bone, worldPositionStays);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        public static void DestroyBones(this SkeletonCache skeleton, BoneCache[] bones)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            Debug.Assert(skeleton != null);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            foreach (var bone in bones)
							 | 
						||
| 
								 | 
							
								            {
							 | 
						||
| 
								 | 
							
								                Debug.Assert(bone != null);
							 | 
						||
| 
								 | 
							
								                Debug.Assert(skeleton.Contains(bone));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                skeleton.DestroyBone(bone);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |