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