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(); 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); } } } }