private List <KeyValuePair <string, AnimationClipContent> > SplitAnimation(
            AnimationClipContent animationClip, List <SplitTask> splitAnimationTaskList,
            ContentProcessorContext context)
        {
            List <KeyValuePair <string, AnimationClipContent> > keyAnimationClipList =
                new List <KeyValuePair <string, AnimationClipContent> >(splitAnimationTaskList.Count);

            foreach (SplitTask splitAnimationTask in splitAnimationTaskList)
            {
                //context.Logger.LogImportantMessage("Split animation " +
                //splitAnimationTask.Name + " [" + splitAnimationTask.StartTimeSeconds +
                //" : " + splitAnimationTask.EndTimeSeconts + "]");

                Dictionary <string, AnimationChannelContent> splitAnimationChannelsDictionary =
                    new Dictionary <string, AnimationChannelContent>();

                TimeSpan splitAnimationDuration = TimeSpan.Zero;

                foreach (KeyValuePair <string, AnimationChannelContent> animationChannelPair in
                         animationClip.Channels)
                {
                    List <AnimationKeyframeContent> splitKeyframes =
                        new List <AnimationKeyframeContent>();

                    TimeSpan?channelStartTime = null;
                    //string times = "";
                    foreach (AnimationKeyframeContent keyframe in animationChannelPair.Value)
                    {
                        if (keyframe.Time.TotalSeconds >= splitAnimationTask.StartTimeSeconds &&
                            keyframe.Time.TotalSeconds <= splitAnimationTask.EndTimeSeconts)
                        {
                            // Get the time of the first keyframe found
                            if (channelStartTime == null)
                            {
                                channelStartTime = keyframe.Time;
                            }

                            // Add keyframe
                            TimeSpan newKeyframeTime = keyframe.Time - channelStartTime.Value;
                            splitKeyframes.Add(new AnimationKeyframeContent(
                                                   newKeyframeTime, keyframe.Pose));

                            if (newKeyframeTime > splitAnimationDuration)
                            {
                                splitAnimationDuration = newKeyframeTime;
                            }

                            //times += string.Format("{0:F4}, ", newKeyframeTime.TotalSeconds);
                        }
                    }

                    //context.Logger.LogImportantMessage("-- {0}. Times: {1}",
                    //animationChannelPair.Key, times);

                    if (splitKeyframes.Count > 0)
                    {
                        splitAnimationChannelsDictionary.Add(animationChannelPair.Key,
                                                             new AnimationChannelContent(splitKeyframes));
                    }
                }

                // Is it better to set the duration as the time of the last frame?
                //TimeSpan splitAnimationDuration = TimeSpan.FromSeconds(
                //splitAnimationTask.EndTimeSeconts - splitAnimationTask.StartTimeSeconds);

                //splitAnimationDuration += TimeSpan.FromSeconds(3.0f/60);

                // Create a new animation clip
                AnimationClipContent splitAnimationClip = new AnimationClipContent(
                    splitAnimationTask.Name,
                    new AnimationChannelContentDictionary(splitAnimationChannelsDictionary),
                    splitAnimationDuration);

                // Add the new animation clip to the animation clip list
                keyAnimationClipList.Add(new KeyValuePair <string, AnimationClipContent>(
                                             splitAnimationTask.Name, splitAnimationClip));
            }

            return(keyAnimationClipList);
        }
        private AnimationClipContentDictionary ProcessAnimations(NodeContent input,
                                                                 AnimationContentDictionary animationDictionary,
                                                                 SkinnedModelBoneContentCollection boneCollection,
                                                                 ContentProcessorContext context)
        {
            // Create a collection here (Does not need a dictionary here)
            Dictionary <string, AnimationClipContent> animationClipDictionary =
                new Dictionary <string, AnimationClipContent>();

            foreach (AnimationContent animation in animationDictionary.Values)
            {
                // Validate animation
                if (!ValidateAnimation(animation, context))
                {
                    continue;
                }

                Dictionary <string, AnimationChannelContent> animationChannelDictionary =
                    new Dictionary <string, AnimationChannelContent>();

                // Process each animation channel (One channel per bone)
                foreach (KeyValuePair <string, AnimationChannel> animationChannelPair in
                         animation.Channels)
                {
                    // Validate animation channel
                    if (!ValidateAnimationChannel(animationChannelPair, animation, boneCollection,
                                                  context))
                    {
                        continue;
                    }

                    List <AnimationKeyframeContent> keyframeList =
                        new List <AnimationKeyframeContent>(animationChannelPair.Value.Count);

                    // Process all the keyframes of that channel
                    foreach (AnimationKeyframe channelKeyframe in animationChannelPair.Value)
                    {
                        // Extract the keyframe pose from its transform matrix
                        Pose keyframePose;
                        channelKeyframe.Transform.Decompose(out keyframePose.Scale,
                                                            out keyframePose.Orientation, out keyframePose.Translation);

                        keyframeList.Add(
                            new AnimationKeyframeContent(channelKeyframe.Time, keyframePose));
                    }

                    // Sort the keyframes by time
                    keyframeList.Sort();

                    animationChannelDictionary.Add(animationChannelPair.Key,
                                                   new AnimationChannelContent(keyframeList));
                }

                AnimationClipContent animationClip = new AnimationClipContent(
                    animation.Name, new AnimationChannelContentDictionary(animationChannelDictionary),
                    animation.Duration);

                animationClipDictionary.Add(animation.Name, animationClip);
            }

            // Split animations
            if (!string.IsNullOrEmpty(splitAnimationFilename))
            {
                SplitAnimations(input, animationClipDictionary, context);
            }

            return(new AnimationClipContentDictionary(animationClipDictionary));
        }