Exemplo n.º 1
0
        private void playExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            M2SceneNode      node    = ModelSceneService.Instance.MainM2SceneNode;
            AnimationContent content = ShellService.Instance.AnimationContent;
            int animIndex            = content.GetCurrentAnimaitonIndex();

            if (node == null || animIndex == -1 || Client.Instance.GetPlayer().GetRideNpcId() != 0)
            {
                return;
            }

            if (animIndex != node.AnimationPlayer.CurrentAnimationIndex ||
                node.AnimationPlayer.Loop != content._animationSelect._animationToolbar.Loop)
            {
                if (node.M2Fsm != null)
                {
                    node.M2Fsm.ResetState();
                }

                node.AnimationPlayer.Loop = content._animationSelect._animationToolbar.Loop;

                node.PlayAnimation((uint)animIndex, node.AnimationPlayer.Loop, 200);
            }

            node.AnimationPlayer.Resume();
        }
Exemplo n.º 2
0
        static SerializableAnimation ProcessAnimation(AnimationContent xnaAnimation)
        {
            SerializableAnimation animation = new SerializableAnimation();

            animation.name   = xnaAnimation.Name;
            animation.length = (float)xnaAnimation.Duration.TotalSeconds;

            foreach (KeyValuePair <string, AnimationChannel> xnaAnimationChannelPair in xnaAnimation.Channels)
            {
                AnimationChannel xnaAnimationChannel     = xnaAnimationChannelPair.Value;
                string           xnaAnimationChannelName = xnaAnimationChannelPair.Key;

                SerializableTrack track = new SerializableTrack();
                track.name = xnaAnimationChannelName;
                animation.tracks.Add(track);

                for (int i = 0; i < xnaAnimationChannel.Count; i++)
                {
                    AnimationKeyframe    xnaKeyframe = xnaAnimationChannel[i];
                    SerializableKeyFrame keyframe    = new SerializableKeyFrame((float)xnaKeyframe.Time.TotalSeconds, xnaKeyframe.Transform);
                    track.AddKeyFrame(keyframe);
                }
            }

            return(animation);
        }
Exemplo n.º 3
0
 private void RemoveFrame(AnimationContent anim, int index)
 {
     foreach (var c in anim.Channels)
     {
         c.Frames.RemoveAt(index);//letzter frame entfernen...
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// This function processes the animation content of the model, and stores the data in the Matrix[] List
        /// </summary>
        /// <param name="animations"></param>
        /// <param name="bones"></param>
        /// <param name="outKeyFrames"></param>
        /// <returns></returns>
        private Dictionary <string, InstancedAnimationClip> ProcessAnimations(
            AnimationContentDictionary animations,
            IList <BoneContent> bones,
            List <Matrix[]> outKeyFrames)
        {
            // Create a map of bones - just like in the SkinnedModel Smaple
            Dictionary <string, int> boneMap = new Dictionary <string, int>();

            for (int i = 0; i < bones.Count; i++)
            {
                string boneName = bones[i].Name;

                if (!string.IsNullOrEmpty(boneName))
                {
                    boneMap.Add(boneName, i);
                }
            }

            // This is a dictionary of all the animations in the model
            Dictionary <string, InstancedAnimationClip> animationDictionary = new Dictionary <string, InstancedAnimationClip>();

            // Loop through each animation, and add that stuff to our animation texture, as well as to our dictionary we are going to output
            foreach (KeyValuePair <string, AnimationContent> data in animations)
            {
                string           animationName = data.Key;
                AnimationContent animation     = data.Value;

                InstancedAnimationClip clip = ProcessAnimation(animation, outKeyFrames, boneMap);
                animationDictionary.Add(animationName, clip);
            }

            return(animationDictionary);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        public static ModelAnimationClip ProcessRootAnimation(AnimationContent animation, string name)
        {
            List <ModelKeyframe> keyframes = new List <ModelKeyframe>();

            // The root animation is controlling the root of the bones
            AnimationChannel channel = animation.Channels[name];

            // Add the transformations on the root of the model
            foreach (AnimationKeyframe keyframe in channel)
            {
                keyframes.Add(new ModelKeyframe(0, keyframe.Time, keyframe.Transform));
            }

            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }

            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has a zero duration.");
            }

            return(new ModelAnimationClip(animation.Duration, keyframes));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        /// <param name="animation">
        /// The animation.
        /// </param>
        /// <param name="boneMap">
        /// The bone Map.
        /// </param>
        /// <param name="keyframeStart">
        /// The keyframe Start.
        /// </param>
        /// <param name="keyframeEnd">
        /// The keyframe End.
        /// </param>
        private static AnimationClip ProcessAnimation(
            AnimationContent animation, Dictionary <string, int> boneMap, int keyframeStart, int keyframeEnd)
        {
            // map of a list of keyframes
            var keyframes = new Dictionary <int, List <Keyframe> >();

            // For each input animation channel.
            foreach (var channel in animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(
                              string.Format(
                                  "Found animation for bone '{0}', " + "which is not part of the skeleton.", channel.Key));
                }

                int keyframeNr = 0;
                int count      = 0;

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    if (count <= keyframeEnd && count >= keyframeStart)
                    {
                        if (!keyframes.ContainsKey(keyframeNr))
                        {
                            keyframes[keyframeNr] = new List <Keyframe>();
                        }

                        keyframes[keyframeNr++].Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                    }

                    count++;
                }
            }

            // Sort the merged keyframes by time.
            foreach (int i in keyframes.Keys)
            {
                keyframes[i].Sort(CompareKeyframeTimes);
            }

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }

            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has a zero duration.");
            }

            return(new AnimationClip(animation.Duration, keyframes));
        }
Exemplo n.º 7
0
        /// <summary>
        /// This does the actual heavy lifting of going through the animation keyframe data, calculating the final world transforms,
        /// and storing them in our list of matrices which will eventually become our animation texture
        /// </summary>
        /// <param name="animation"></param>
        /// <param name="animationRows"></param>
        /// <param name="boneMap"></param>
        /// <returns></returns>
        private InstancedAnimationClip ProcessAnimation(AnimationContent animation, List <Matrix[]> animationRows, Dictionary <string, int> boneMap)
        {
            // Get a list of all the key frames in the animation, sorted by time
            List <Keyframe> keyframes = GetKeyFrameList(animation, boneMap);

            // Now, we're going to sort of copy the functionality of AnimationPlayer in the original skinned model sample
            // We're going to cycle through the animation, at a specified framerate, and take snapshots of the matrices
            // We'll then store these snapshots in the list, and record the start of the snapshot
            int startRow = animationRows.Count;

            float timeDelta       = 1.0f / (float)this.sampleRate;
            float currentTime     = 0f;
            int   currentKeyFrame = 0;


            //Copy over the bindpose matrices
            Matrix[] boneTransforms = this.bindPose.ToArray();

            while (currentTime < animation.Duration.TotalSeconds)
            {
                //Update bone transforms based on the keyframes
                for (int i = currentKeyFrame; i < keyframes.Count; i++)
                {
                    Keyframe keyframe = keyframes[i];
                    if (currentTime < keyframe.Time.TotalSeconds)
                    {
                        break;
                    }

                    boneTransforms[keyframe.Bone] = keyframe.Transform;
                    currentKeyFrame = i;
                }

                //Create the world transforms
                Matrix[] worldTransforms = new Matrix[boneTransforms.Length];
                worldTransforms[0] = boneTransforms[0];
                for (int i = 1; i < worldTransforms.Length; i++)
                {
                    int parentBone = this.skeletonHierarchy[i];
                    worldTransforms[i] = boneTransforms[i] * worldTransforms[parentBone];
                }

                //Create the skinning transforms
                Matrix[] skinningTransforms = new Matrix[worldTransforms.Length];
                for (int i = 0; i < skinningTransforms.Length; i++)
                {
                    skinningTransforms[i] = this.inverseBindPose[i] * worldTransforms[i];
                }

                //Add the final skinning animation to our list of rows
                animationRows.Add(skinningTransforms);

                currentTime += timeDelta;
            }

            return(new InstancedAnimationClip(animation.Duration, startRow, animationRows.Count - 1, this.sampleRate));
        }
Exemplo n.º 8
0
        ProcessAnimation(AnimationContent animation)
        {
            // M * M = F
            //
            AnimationProcessor ap      = new AnimationProcessor();
            AnimationContent   newAnim = ap.Interpolate(animation);

            newAnim.Name = animation.Name;
            return(newAnim);

            ;
        }
Exemplo n.º 9
0
        private void pauseExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            M2SceneNode      node    = ModelSceneService.Instance.MainM2SceneNode;
            AnimationContent content = ShellService.Instance.AnimationContent;
            int animIndex            = content.GetCurrentAnimaitonIndex();

            if (node == null || animIndex == -1)
            {
                return;
            }

            node.AnimationPlayer.Pause();
        }
Exemplo n.º 10
0
 /// <summary>
 /// Return true if you want to trim the given animation, removing identical frames
 /// from the end. This is necessay for short animations imported through the .X
 /// importer, which somehow manages to add blank padding to the duration.
 /// </summary>
 /// <param name="ac">The animation to test against the list of animation name patterns</param>
 /// <returns></returns>
 protected virtual bool ShouldTrimAnimation(AnimationContent ac)
 {
     if (trimAnimationExpressions_ != null)
     {
         foreach (Regex re in trimAnimationExpressions_)
         {
             if (re.IsMatch(ac.Name))
             {
                 return(true);
             }
         }
     }
     return(false);
 }
Exemplo n.º 11
0
        // template AnimationSet
        // {
        //     [ Animation ]
        // }
        /// <summary>
        /// Imports an animation set that is added to the AnimationContentDictionary of
        /// the root frame.
        /// </summary>
        private void ImportAnimationSet()
        {
            AnimationContent animSet = new AnimationContent();

            animSet.Name = tokens.ReadName();
            // Give each animation a unique name
            if (animSet.Name == null)
            {
                animSet.Name = "Animation" + root.Animations.Count.ToString();
            }

            // Fill in all the channels of the animation.  Each channel refers to
            // a single bone's role in the animation.
            for (string next = tokens.NextToken(); next != "}"; next = tokens.NextToken())
            {
                if (next == "Animation")
                {
                    string           boneName;
                    AnimationChannel anim = ImportAnimationChannel(out boneName);
                    // Every channel must be attached to a bone!
                    if (boneName == null)
                    {
                        throw new Exception("Animation in file is not attached to any joint");
                    }
                    // Make sure that the duration of the animation is set to the
                    // duration of the longest animation channel
                    if (anim[anim.Count - 1].Time > animSet.Duration)
                    {
                        animSet.Duration = anim[anim.Count - 1].Time;
                    }
                    animSet.Channels.Add(boneName, anim);
                }
                // skip nodes we are uninterested in
                else if (next == "{")
                {
                    tokens.SkipNode();
                }
            }
            //skeletonRoot = MeshHelper.FindSkeleton(root);
            //skeletonRoot.Animations.Add(animSet.Name, animSet);
            if (root.Animations.ContainsKey(animSet.Name))
            {
                string error = "Attempting to add " + animSet.Name + " but it already exists.";



                throw new Exception(error);
            }
            root.Animations.Add(animSet.Name, animSet);
        }
Exemplo n.º 12
0
 /// <summary>
 /// Return true if you want to include the specific track (bone) in the output animation set.
 /// </summary>
 /// <param name="ac">The animation to check.</param>
 /// <returns>true unless the bone name is in a semicolon-separated list called ExcludeBones</returns>
 protected virtual bool IncludeTrack(AnimationContent ac, string name)
 {
     if (excludeBonesExpressions_ != null)
     {
         foreach (Regex re in excludeBonesExpressions_)
         {
             if (re.IsMatch(name))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Exemplo n.º 13
0
 /// <summary>
 /// Return true if you want to include the specific animation in the output animation set.
 /// </summary>
 /// <param name="ac">The animation to check.</param>
 /// <returns>true unless the animation name is in a semicolon-separated list called ExcludeAnimations</returns>
 protected virtual bool IncludeAnimation(AnimationContent ac)
 {
     if (excludeAnimationsExpressions_ != null)
     {
         foreach (Regex re in excludeAnimationsExpressions_)
         {
             if (re.IsMatch(ac.Name))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
        private AnimationClip ProcessAnimation(AnimationContent value, Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            foreach (KeyValuePair <string, AnimationChannel> channel in value.Channels)
            {
                int boneIndex = boneMap[channel.Key];
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                }
            }

            keyframes.Sort(CompareKeyframeTimes);
            return(new AnimationClip(value.Duration, keyframes));
        }
Exemplo n.º 15
0
        private AnimationContent CreateAnimation(Assimp.Animation aiAnimation)
        {
            var animation = new AnimationContent
            {
                Name     = FixupAnimationName(aiAnimation.Name),
                Duration = TimeSpan.FromSeconds(aiAnimation.DurationInTicks / aiAnimation.TicksPerSecond)
            };

            foreach (var aiChannel in aiAnimation.NodeAnimationChannels)
            {
                var channel = new AnimationChannel();

                // We can have different numbers of keyframes for each, so find the max index.
                var keyCount = Math.Max(aiChannel.PositionKeyCount, Math.Max(aiChannel.RotationKeyCount, aiChannel.ScalingKeyCount));

                // Get all unique keyframe times
                var times = aiChannel.PositionKeys.Select(k => k.Time)
                            .Union(aiChannel.RotationKeys.Select(k => k.Time))
                            .Union(aiChannel.ScalingKeys.Select(k => k.Time))
                            .Distinct().ToList();

                // The rest of this loop is almost certainly wrong. Don't trust it.
                // There's some magical combination, ordering, or transposition we have
                // to figure out to translate FBX->Assimp->XNA.
                // Possibilities: matrix offset transform, missing a base transform, an extra base transform, etc.

                var toBoneSpace = _objectToBone.ContainsKey(aiChannel.NodeName)
                    ? _objectToBone[aiChannel.NodeName] * _skeletonRoot.Transform
                    : _skeletonRoot.Transform;

                foreach (var aiKeyTime in times)
                {
                    var time          = TimeSpan.FromSeconds(aiKeyTime / aiAnimation.TicksPerSecond);
                    var translation   = Matrix4x4.FromTranslation(aiChannel.PositionKeys.FirstOrDefault(k => k.Time == aiKeyTime).Value);
                    var rotation      = new Matrix4x4(aiChannel.RotationKeys.FirstOrDefault(k => k.Time == aiKeyTime).Value.GetMatrix());
                    var scale         = Matrix4x4.FromScaling(aiChannel.ScalingKeys.FirstOrDefault(k => k.Time == aiKeyTime).Value);
                    var nodeTransform = translation * rotation * scale;

                    var xform = toBoneSpace * nodeTransform * _globalInverseXform;
                    channel.Add(new AnimationKeyframe(time, ToXna(xform)));
                }

                animation.Channels.Add(aiChannel.NodeName, channel);
            }

            return(animation);
        }
        } // AddAnimationNodes

        #endregion

        #region Process Root Animation

        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        internal static RootAnimationClip ProcessRootAnimation(AnimationContent animation, string name)
        {
            List<RootKeyframe> keyframes = new List<RootKeyframe>();

            // The root animation is controlling the root of the bones
            AnimationChannel channel = animation.Channels[name];
            
            // Add the transformations on the root of the model
            foreach (AnimationKeyframe keyframe in channel)
            {
                keyframes.Add(new RootKeyframe((float)(keyframe.Time.TotalSeconds), keyframe.Transform));
            }            

            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            #region Key Frame Reduction

            // We drop key frame data where the bone transformation is equal to the previous key frame.
            List<RootKeyframe> keyframesReduced = new List<RootKeyframe>();
            keyframesReduced.Add(keyframes[0]);
            for (int i = 1; i < keyframes.Count; i++)
            {
                if (keyframes[i - 1].Transform != keyframes[i].Transform)
                {
                    keyframesReduced.Add(keyframes[i]);
                }
            }
            keyframes = keyframesReduced;
            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            #endregion

            if (keyframes.Count == 0)
                throw new InvalidContentException("Animation has no keyframes.");

            if (animation.Duration <= TimeSpan.Zero)
                throw new InvalidContentException("Animation has a zero duration.");

            RootKeyframe[] keyframesArray = new RootKeyframe[keyframes.Count];
            for (int i = 0; i < keyframes.Count; i++)
            {
                keyframesArray[i] = keyframes[i];
            }
            return new RootAnimationClip((float)(animation.Duration.TotalSeconds), keyframesArray);
        } // ProcessRootAnimation
Exemplo n.º 17
0
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        static Clip ProcessAnimation(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            Dictionary <int, Channel> channels = new Dictionary <int, Channel>();

            // For each input animation channel.
            foreach (KeyValuePair <string, AnimationChannel> inputChannel in animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(inputChannel.Key, out boneIndex))
                {
                    continue;
                }

                if (inputChannel.Value.Count > 0)
                {
                    Channel newChannel = null;

                    if (!channels.TryGetValue(boneIndex, out newChannel))
                    {
                        channels[boneIndex]  = newChannel = new Channel();
                        newChannel.BoneIndex = boneIndex;
                    }

                    foreach (AnimationKeyframe keyframe in inputChannel.Value)
                    {
                        newChannel.Add(new Keyframe(keyframe.Time, keyframe.Transform));
                    }

                    newChannel.Sort(CompareKeyframeTimes);

                    for (int i = 2; i < newChannel.Count; i++)
                    {
                        Keyframe keyframe = newChannel[i];
                        if (newChannel[i - 1].Transform.Equals(keyframe.Transform) &&
                            newChannel[newChannel.Count - 2].Transform.Equals(keyframe.Transform))
                        {
                            newChannel.RemoveAt(i - 1);
                            i--;
                        }
                    }
                }
            }

            return(new Clip(channels.Values));
        }
Exemplo n.º 18
0
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        static AnimationClip ProcessAnimation(AnimationContent animation,
                                              Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            // For each input animation channel.
            foreach (KeyValuePair <string, AnimationChannel> channel in
                     animation.Channels)
            {
                if (!channel.Key.StartsWith("Bone"))
                {
                    continue;
                }
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                                                          "Found animation for bone '{0}', " +
                                                          "which is not part of the skeleton.", channel.Key));
                }

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time,
                                               keyframe.Transform));
                }
            }

            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }

            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has a zero duration.");
            }

            return(new AnimationClip(animation.Duration, keyframes));
        }
        // Extracts all animations and stores them in _animations.
        private void BuildAnimations()
        {
            SplitAnimations();

            _animations = new Dictionary <string, SkeletonKeyFrameAnimation>();
            foreach (var item in _rootBone.Animations)
            {
                string           animationName    = item.Key;
                AnimationContent animationContent = item.Value;

                // Convert the AnimationContent to a SkeletonKeyFrameAnimation.
                var skeletonAnimation = BuildAnimation(animationContent);
                if (skeletonAnimation != null)
                {
                    _animations.Add(animationName, skeletonAnimation);
                }
            }
        }
Exemplo n.º 20
0
        protected virtual void CollectAnimatedBones(AnimationContentDictionary dict, NodeContent bone)
        {
            AnimationContentDictionary acd = bone.Animations;

            if (acd != null)
            {
                foreach (string name in acd.Keys)
                {
                    //  merge each animation into the dictionary
                    AnimationContent ac = acd[name];
                    AnimationContent xac;
                    if (!dict.TryGetValue(name, out xac))
                    {
                        //  create it if we haven't already seen it, and there's something there
                        if (ac.Channels.Count > 0)
                        {
                            xac = ac;
                            dict.Add(name, xac);
                        }
                    }
                    else
                    {
                        //  merge the animation content
                        foreach (KeyValuePair <string, AnimationChannel> kvp in ac.Channels)
                        {
                            AnimationChannel ov;
                            if (xac.Channels.TryGetValue(kvp.Key, out ov))
                            {
                                throw new System.ArgumentException(
                                          String.Format("The animation {0} has multiple channels named {1}.",
                                                        name, kvp.Key));
                            }
                            xac.Channels.Add(kvp.Key, kvp.Value);
                        }
                        xac.Duration = new TimeSpan((long)
                                                    (Math.Max(xac.Duration.TotalSeconds, ac.Duration.TotalSeconds) * 1e7));
                    }
                }
            }
            foreach (NodeContent nc in bone.Children)
            {
                CollectAnimatedBones(dict, nc);
            }
        }
Exemplo n.º 21
0
        static AnimationClip ProcessAnimation(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            // For each input animation channel.
            foreach (KeyValuePair <string, AnimationChannel> channel in animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex = boneMap[channel.Key];
                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                }
            }

            // Sort the merged keyframes by time.  keyframes.Sort(CompareKeyframeTimes);
            return(new AnimationClip(animation.Duration, keyframes));
        }
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// into our runtime AnimationClip format
        /// </summary>
        /// <param name="animation"></param>
        /// <param name="boneMap"></param>
        /// <returns></returns>
        static AnimationClip ProcessAnimation(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            int    boneIndex;
            Matrix trans;

            // for each input animation channel
            foreach (KeyValuePair <string, AnimationChannel> channel in animation.Channels)
            {
                // look up what bone this channel is controlling
                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                                                          "Found animation for bone {0}, which is not a part of the skeleton",
                                                          channel.Key
                                                          ));
                }

                // convert the keyframe data
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                }
            }

            // sort the merged keyframes by time
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }
            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has an invalid duration.");
            }

            return(new AnimationClip(animation.Duration, keyframes));
        }
        /// <summary>
        /// Converts an intermediate-format content pipeline AnimationContent object
        /// to an avatar-specific AvatarKeyFrame list.
        /// </summary>
        List <AvatarKeyFrame> ProcessAnimation(AnimationContent animation,
                                               Dictionary <string, int> boneMap)
        {
            // Create the output list of keyframes
            List <AvatarKeyFrame> keyframes = new List <AvatarKeyFrame>();

            // Process each channel in the animation
            foreach (KeyValuePair <string, AnimationChannel> channel
                     in animation.Channels)
            {
                // Don't add animation nodes with "_END" in the name
                // -- These bones were removed from the skeleton already
                if (channel.Key.Contains("_END"))
                {
                    continue;
                }

                // Look up what bone this channel is controlling.
                int boneIndex;
                if (!boneMap.TryGetValue(CleanBoneName(channel.Key), out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                                                          "Found animation for bone '{0}', " +
                                                          "which is not part of the skeleton.", channel.Key));
                }

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new AvatarKeyFrame(boneIndex, keyframe.Time,
                                                     CreateKeyframeMatrix(keyframe, boneIndex)));
                }
            }

            // Sort the merged keyframes by time.
            keyframes.Sort((frame1, frame2) => frame1.Time.CompareTo(frame2.Time));

            return(keyframes);
        }
Exemplo n.º 24
0
        private bool ValidateAnimationChannel(
            KeyValuePair <string, AnimationChannel> animationChannelPair,
            AnimationContent parentAnimation, SkinnedModelBoneContentCollection boneCollection,
            ContentProcessorContext context)
        {
            // Check if this channel has any keyframe
            if (animationChannelPair.Value.Count == 0)
            {
                context.Logger.LogWarning(null, parentAnimation.Identity, String.Format(
                                              "Channel {0} in animation {1} does not contain any keyframe and will be skipped.",
                                              animationChannelPair.Key, parentAnimation.Name));

                return(false);
            }

            // Check if the animation channel exists in the skeleton
            bool boneFound = false;

            foreach (SkinnedModelBoneContent boneContent in boneCollection)
            {
                if (boneContent.Name.Equals(animationChannelPair.Key))
                {
                    boneFound = true;
                    break;
                }
            }

            if (!boneFound)
            {
                context.Logger.LogWarning(null, parentAnimation.Identity, String.Format(
                                              "Channel {0} in animation {1} affects a bone that does not exists in the " +
                                              "model's skeleton and will be skipped.", animationChannelPair.Key,
                                              parentAnimation.Name));

                return(false);
            }

            return(true);
        }
        static List <Keyframe> ProcessAnimationKeyframe(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            foreach (KeyValuePair <string, AnimationChannel> channel in animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                                                          "Found animation for bone '{0}', " +
                                                          "which is not part of the skeleton.",
                                                          channel.Key));
                }

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                }
            }

            keyframes.Sort((Keyframe a, Keyframe b) => { return(a.Time.CompareTo(b.Time)); });

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }

            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has a zero duration.");
            }

            return(keyframes);
        }
Exemplo n.º 26
0
        /// <summary>
        /// アニメーションデータを構築
        /// </summary>
        static AnimationClip ProcessAnimation(AnimationContent animation, Dictionary <string, int> boneMap)
        {
            List <Keyframe> keyframes = new List <Keyframe>();

            foreach (KeyValuePair <string, AnimationChannel> channel in animation.Channels)
            {
                // ボーン名をキーにしてボーンインデックスを取得
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                                                          "Found animation for bone '{0}', " +
                                                          "which is not part of the skeleton.", channel.Key));
                }

                // キーフレーム配列を作成
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time, keyframe.Transform));
                }
            }

            // キーフレーム配列を昇順にソート
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
            {
                throw new InvalidContentException("Animation has no keyframes.");
            }

            if (animation.Duration <= TimeSpan.Zero)
            {
                throw new InvalidContentException("Animation has a zero duration.");
            }

            return(new AnimationClip(animation.Name, animation.Duration, keyframes));
        }
Exemplo n.º 27
0
        private bool ValidateAnimation(AnimationContent animation, ContentProcessorContext context)
        {
            // Check if this animation has any channel
            if (animation.Channels.Count == 0)
            {
                context.Logger.LogWarning(null, animation.Identity, String.Format(
                                              "Animation {0} does not contain any channel and will be skipped.",
                                              animation.Name));

                return(false);
            }

            // Check if this channel has any keyframe
            if (animation.Duration <= TimeSpan.Zero)
            {
                context.Logger.LogWarning(null, animation.Identity, String.Format(
                                              "Animation {0} has a zero duration and will be skipped.", animation.Name));

                return(false);
            }

            return(true);
        }
Exemplo n.º 28
0
        List <AnimationContent> CreateAnimations()
        {
            var animations = new List <AnimationContent>();

            for (int i = 0; i < collada.JointAnimations.Count; i++)
            {
                var sourceAnim = collada.JointAnimations[i];

                AnimationContent animation = new AnimationContent();
                animation.Name     = sourceAnim.Name ?? String.Format("Take {0:000}", (i + 1));
                animation.Duration = TimeSpan.FromSeconds(sourceAnim.EndTime - sourceAnim.StartTime);

                foreach (var sourceChannel in sourceAnim.Channels)
                {
                    AnimationChannel channel = new AnimationChannel();

                    // Adds the different keyframes to the animation channel
                    // NOTE: Might be better to sample the keyframes
                    foreach (var sourceKeyframe in sourceChannel.Sampler.Keyframes)
                    {
                        TimeSpan time      = TimeSpan.FromSeconds(sourceKeyframe.Time);
                        Matrix   transform = sourceKeyframe.Transform;

                        AnimationKeyframe keyframe = new AnimationKeyframe(time, transform);
                        channel.Add(keyframe);
                    }

                    String key = GetJointKey(sourceChannel.Target);
                    animation.Channels.Add(key, channel);
                }

                animation.OpaqueData.Add("FPS", sourceAnim.FramesPerSecond);
                animations.Add(animation);
            }

            return(animations);
        }
Exemplo n.º 29
0
        private FrameworkElement ProcessAnimation(PageBlockAnimation block)
        {
            var galleryItem = new GalleryAnimationItem(ViewModel.ProtoService, block.Animation, block.Caption?.ToString());

            ViewModel.Gallery.Items.Add(galleryItem);

            var message = GetMessage(new MessageAnimation(block.Animation, null));
            var element = new StackPanel {
                Tag = message, Style = Resources["BlockVideoStyle"] as Style
            };

            if (block.Animation.Thumbnail != null)
            {
                _filesMap[block.Animation.Thumbnail.Photo.Id].Add(element);
            }

            _filesMap[block.Animation.AnimationData.Id].Add(element);

            var content = new AnimationContent(message);

            content.HorizontalAlignment = HorizontalAlignment.Center;
            content.ClearValue(MaxWidthProperty);
            content.ClearValue(MaxHeightProperty);

            element.Children.Add(content);

            var caption = ProcessText(block, true);

            if (caption != null)
            {
                caption.Margin = new Thickness(0, 8, 0, 0);
                element.Children.Add(caption);
            }

            return(element);
        }
        /// <summary>
        /// Interpolates an AnimationContent object to 60 fps.
        /// </summary>
        /// <param name="input">The AnimationContent to interpolate.</param>
        /// <returns>The interpolated AnimationContent.</returns>
        public virtual AnimationContent Interpolate(AnimationContent input)
        {
            AnimationContent output            = new AnimationContent();
            long             time              = 0;
            long             animationDuration = input.Duration.Ticks;

            // default XNA importers, due to floating point errors or TimeSpan
            // estimation, sometimes  have channels with a duration slightly longer than
            // the animation duration.  So, set the animation duration to its true
            // value
            foreach (KeyValuePair <string, AnimationChannel> c in input.Channels)
            {
                if (c.Value[c.Value.Count - 1].Time.Ticks > animationDuration)
                {
                    animationDuration = c.Value[c.Value.Count - 1].Time.Ticks;
                }
            }

            foreach (KeyValuePair <string, AnimationChannel> c in input.Channels)
            {
                time = 0;
                string           channelName = c.Key;
                AnimationChannel channel     = c.Value;
                AnimationChannel outChannel  = new AnimationChannel();
                int currentFrame             = 0;

                // Step through time until the time passes the animation duration
                while (time <= animationDuration)
                {
                    AnimationKeyframe keyframe;
                    // Clamp the time to the duration of the animation and make this
                    // keyframe equal to the last animation frame.
                    if (time >= animationDuration)
                    {
                        time     = animationDuration;
                        keyframe = new AnimationKeyframe(new TimeSpan(time),
                                                         channel[channel.Count - 1].Transform);
                    }
                    else
                    {
                        // If the channel only has one keyframe, set the transform for the current time
                        // to that keyframes transform
                        if (channel.Count == 1 || time < channel[0].Time.Ticks)
                        {
                            keyframe = new AnimationKeyframe(new TimeSpan(time), channel[0].Transform);
                        }
                        // If the current track duration is less than the animation duration,
                        // use the last transform in the track once the time surpasses the duration
                        else if (channel[channel.Count - 1].Time.Ticks <= time)
                        {
                            keyframe = new AnimationKeyframe(new TimeSpan(time), channel[channel.Count - 1].Transform);
                        }
                        else // proceed as normal
                        {
                            // Go to the next frame that is less than the current time
                            while (channel[currentFrame + 1].Time.Ticks < time)
                            {
                                currentFrame++;
                            }
                            // Numerator of the interpolation factor
                            double interpNumerator = (double)(time - channel[currentFrame].Time.Ticks);
                            // Denominator of the interpolation factor
                            double interpDenom = (double)(channel[currentFrame + 1].Time.Ticks - channel[currentFrame].Time.Ticks);
                            // The interpolation factor, or amount to interpolate between the current
                            // and next frame
                            double interpAmount = interpNumerator / interpDenom;

                            // If the frames are roughly 60 frames per second apart, use linear interpolation
                            if (channel[currentFrame + 1].Time.Ticks - channel[currentFrame].Time.Ticks
                                <= ContentUtil.TICKS_PER_60FPS * 1.05)
                            {
                                keyframe = new AnimationKeyframe(new TimeSpan(time),
                                                                 Matrix.Lerp(
                                                                     channel[currentFrame].Transform,
                                                                     channel[currentFrame + 1].Transform,
                                                                     (float)interpAmount));
                            }
                            else // else if the transforms between the current frame and the next aren't identical
                                 // decompose the matrix and interpolate the rotation separately
                            if (channel[currentFrame].Transform != channel[currentFrame + 1].Transform)
                            {
                                keyframe = new AnimationKeyframe(new TimeSpan(time),
                                                                 ContentUtil.SlerpMatrix(
                                                                     channel[currentFrame].Transform,
                                                                     channel[currentFrame + 1].Transform,
                                                                     (float)interpAmount));
                            }
                            else // Else the adjacent frames have identical transforms and we can use
                                 // the current frames transform for the current keyframe.
                            {
                                keyframe = new AnimationKeyframe(new TimeSpan(time),
                                                                 channel[currentFrame].Transform);
                            }
                        }
                    }
                    // Add the interpolated keyframe to the new channel.
                    outChannel.Add(keyframe);
                    // Step the time forward by 1/60th of a second
                    time += ContentUtil.TICKS_PER_60FPS;
                }

                // Compensate for the time error,(animation duration % TICKS_PER_60FPS),
                // caused by the interpolation by setting the last keyframe in the
                // channel to the animation duration.
                if (outChannel[outChannel.Count - 1].Time.Ticks < animationDuration)
                {
                    outChannel.Add(new AnimationKeyframe(
                                       TimeSpan.FromTicks(animationDuration),
                                       channel[channel.Count - 1].Transform));
                }

                outChannel.Add(new AnimationKeyframe(input.Duration,
                                                     channel[channel.Count - 1].Transform));
                // Add the interpolated channel to the animation
                output.Channels.Add(channelName, outChannel);
            }
            // Set the interpolated duration to equal the inputs duration for consistency
            output.Duration = TimeSpan.FromTicks(animationDuration);
            return(output);
        }
        /// <summary>
        /// Converts an intermediate format content pipeline AnimationContent
        /// object to our runtime AnimationClip format.
        /// </summary>
        static AnimationClip ProcessAnimation(AnimationContent animation,
                                              Dictionary<string, int> boneMap)
        {
            List<Keyframe> keyframes = new List<Keyframe>();

            // For each input animation channel.
            foreach (KeyValuePair<string, AnimationChannel> channel in
                animation.Channels)
            {
                // Look up what bone this channel is controlling.
                int boneIndex;

                if (!boneMap.TryGetValue(channel.Key, out boneIndex))
                {
                    throw new InvalidContentException(string.Format(
                        "Found animation for bone '{0}', " +
                        "which is not part of the skeleton.", channel.Key));
                }

                // Convert the keyframe data.
                foreach (AnimationKeyframe keyframe in channel.Value)
                {
                    keyframes.Add(new Keyframe(boneIndex, keyframe.Time,
                                               keyframe.Transform));
                }
            }

            // Sort the merged keyframes by time.
            keyframes.Sort(CompareKeyframeTimes);

            if (keyframes.Count == 0)
                throw new InvalidContentException("Animation has no keyframes.");

            if (animation.Duration <= TimeSpan.Zero)
                throw new InvalidContentException("Animation has a zero duration.");

            return new AnimationClip(animation.Duration, keyframes);
        }