/// <summary> /// Get the animation clip in the format used to save and load clips. /// boneFilter is a list of bones to match that will be saved all other discarded /// leave null or empty to select all bones /// </summary> public static List<string> GetAnimationClipData(AnimationClip clip, bool isTypeClip, IDictionary<string, int> BoneMap, List<string> bonesFilter, float centreFrame) { // This is where we store the lines to export to the file List<string> data = new List<string>(); if (isTypeClip) { // CLIP // Add the details from the AnimationClip string output = ParseData.IntToString(clip.BoneCount) + " " + ParseData.TimeToString(clip.Duration); // Add the sound times for (int s = 0; s < clip.SoundFrameTimes.Count; s++) { output += " " + ParseData.TimeToString(clip.SoundFrameTimes[s]); } data.Add(output); } else { // PART, head or arms // Use the details from the AnimationClip to create the AnimationPart file // Add the extra header information for, max, min and defaultFrame data.Add(String.Format("{0} {1} {2} {3}", ParseData.IntToString(clip.BoneCount), ParseData.FloatToString(GlobalSettings.armAnimateAngleUp), ParseData.FloatToString(GlobalSettings.armAnimateAngleDown), ParseData.FloatToString(centreFrame))); } IList<Keyframe> frames = clip.Keyframes; if (frames == null) { data.Clear(); // Animation does not have any frames return null; } // Add each keyframe WantedBones BoneTest = new WantedBones(BoneMap, bonesFilter); for (int i = 0; i < frames.Count; i++) { // FRAME // Include some or all of the bones to create // either an AnimationClip or AnimationPart file if (BoneTest.IsBoneWeWant(frames[i].Bone)) { data.Add(String.Format("{0} {1}{2}{3}", ParseData.IntToString(frames[i].Bone), ParseData.TimeToString(frames[i].Time), ParseData.div, ParseData.MatrixToString(frames[i].Transform))); } } return data; }
public static AnimationClip MergeClips(AnimationClip upper, AnimationClip lower, IDictionary<string, int> BoneMap, List<string> upperBonesFilter) { // Only valid if both clips are for the same skeleton int boneCount = upper.BoneCount; if (lower.BoneCount != boneCount) { return null; } TimeSpan duration = lower.Duration; if (upper.Duration > lower.Duration) { duration = upper.Duration; } // The foot sounds only come from the lower bones. List<TimeSpan> steps = lower.SoundFrameTimes; IList<Keyframe> keyframes = new List<Keyframe>(); IList<Keyframe> upperframes = upper.Keyframes; IList<Keyframe> lowerframes = lower.Keyframes; WantedBones UpperBoneTest = new WantedBones(BoneMap, upperBonesFilter); int nextUpper = 0; int nextLower = 0; while (nextLower < lowerframes.Count) { while (nextUpper < upperframes.Count && upperframes[nextUpper].Time <= lowerframes[nextLower].Time) { if (UpperBoneTest.IsBoneWeWant(upperframes[nextUpper].Bone)) { keyframes.Add(upperframes[nextUpper]); } nextUpper++; } if (!UpperBoneTest.IsBoneWeWant(lowerframes[nextLower].Bone)) { keyframes.Add(lowerframes[nextLower]); } nextLower++; } // Add the remainder if (nextUpper < upperframes.Count) { for (int i = nextUpper; i < upperframes.Count; i++) { if (UpperBoneTest.IsBoneWeWant(upperframes[nextUpper].Bone)) { keyframes.Add(upperframes[i]); } } } return new AnimationClip(boneCount, duration, keyframes, steps); }