예제 #1
0
        /// <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;
        }
예제 #2
0
        // Convert each clip to a string array for saving
        // boneFilter is a list of bones to match that will be saved all other discarded
        // leave null or empty to select all bones
        public List<string> GetSaveClipData(AnimationClip clip, bool isTypeClip, IDictionary<string, int> boneMap, string clipName, List<string> bonesFilter, float centreFrame)
        {
            if (clip == null || boneMap == null)
            {
                form.AddMessageLine("Animation does not exist in the file: " + clipName);
                return null;
            }

            return ParseClips.GetAnimationClipData(clip, isTypeClip, boneMap, bonesFilter, centreFrame);
        }
예제 #3
0
        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);
        }
예제 #4
0
 // Add a clip to the list and diplays it
 public void AddToClipList(AnimationClip clip, string name)
 {
     if (clip != null)
     {
         if (loadedClips.ContainsKey(name))
         {
             // rename to avoid duplicates
             name += DateTime.Now.ToString(GlobalSettings.timeFormat);
         }
         clipNames.Add(name);
         loadedClips.Add(name, clip);
         currentClipName = name;
         string error = modelViewerControl.SetExternalClip(clip);
         SaveClipMenu.Enabled = true;
         if (!string.IsNullOrEmpty(error))
         {
             AddMessageLine(error);
             DisplayTheBindPose();
         }
     }
     else
     {
         AddMessageLine("No clip data!");
     }
     HaveClipsLoaded();
 }
예제 #5
0
        // Returns the name of the saved file
        private string ClipSaveDialogue(AnimationClip clip, IDictionary<string, int> boneMap)
        {
            // Path to default location
            string pathToSaveFolder = defaultFileFolder;
            string assetName = "";
            string fileName = currentClipName;
            // If we have loaded a file use that for the path and the name
            if (lastLoadedFile != "")
            {
                pathToSaveFolder = Path.GetDirectoryName(lastLoadedFile);
                assetName = Path.GetFileNameWithoutExtension(lastLoadedFile) + "-";
            }
            // Append the name to the end of the filename
            fileName = assetName + fileName;

            SaveFileDialog fileDialog = new SaveFileDialog();

            fileDialog.InitialDirectory = pathToSaveFolder;

            fileDialog.Title = "Save the animation clip";

            fileDialog.FileName = fileName;

            fileDialog.Filter = "Clip File (*.clip)|*.clip|" +
                                "Head File (*.head)|*.head|" +
                                "Arms File (*.arms)|*.arms|" +
                                "Pose File (*.pose)|*.pose|" +
                                "Animation File Types (*.clip;*.arms;*.head;*.pose)|*.clip;*.arms;*.head;*.pose|" +
                                "All Files (*.*)|*.*";

            if (fileDialog.ShowDialog() == DialogResult.OK)
            {
                string fileType = Path.GetExtension(fileDialog.FileName).ToLower();
                bool isClip = false;
                if (fileType == "clip" || fileType == ".clip" || fileType == "pose" || fileType == ".pose")
                {
                    isClip = true;
                }

                List<string> data = ParseClips.GetAnimationClipData(clip, isClip,
                    boneMap, currentBoneFilter, currentCentreFrame);
                if (data == null || data.Count < 1)
                {
                    AddMessageLine("No clip data!");
                    return "";
                }
                SaveTextFile(fileDialog.FileName, data);
                return fileDialog.FileName;
            }
            return "";
        }
예제 #6
0
 private void MergeAnimations(AnimationClip upper, AnimationClip lower, string mergeFilePath, List<string> upperBodyBones)
 {
     AnimationClip result = ParseClips.MergeClips(upper, lower, form.GetBoneMap(), upperBodyBones);
     List<string> data = ParseClips.GetAnimationClipData(result, true, null, null, 0);
     form.AddMessageLine("Saving: " + mergeFilePath);
     File.WriteAllLines(mergeFilePath, data);
     string name = Path.GetFileNameWithoutExtension(mergeFilePath);
     form.AddToClipList(result, name);
 }
 // returns any error message
 public string SetExternalClip(AnimationClip clip)
 {
     if (isAnimated && model != null && animationPlayer != null)
     {
         // Change the animation
         return animationPlayer.StartClip(clip);
     }
     return "The model is not animated!";
 }
예제 #8
0
        /// <summary>
        /// Starts decoding the specified animation clip.
        /// Returns an error message
        /// </summary>
        public string StartClip(AnimationClip clip)
        {
            string error = "";
            // Use a null clip to set the model to the bind pose
            if (clip != null && (skinningDataValue == null || clip.BoneCount != skinningDataValue.BoneMap.Count))
            {
                error += "\nThe number of bones in the clip does not match the number in the model!";
                return error;
            }

            currentClipValue = clip;
            currentTimeValue = TimeSpan.Zero;
            currentKeyframe = 0;

            // Initialize bone transforms to the bind pose.
            skinningDataValue.BindPose.CopyTo(boneTransforms, 0);

            return error;
        }