示例#1
0
        private BoneInfo[] played_boneInfos; //tu wrzucac wszystko i tym sterowac caloscia

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Constructor for the animation player. It makes the 
        /// association between a clip and a model and sets up for playing
        /// </summary>
        /// <param name="clip"></param>
        public AnimationPlayer(Dictionary<String, AnimationClip> Clips, AnimatedModel model)
        {
            blendedBones = new AnimationClip.Bone[model.Bones.Count];

            this.Clips = Clips;
            this.model = model;
            current_clip = Clips["Take 001"];

            looping = true;

            // Create the bone information classes
            boneCnt = current_clip.Bones.Count;

            played_boneInfos = new BoneInfo[boneCnt];

            for (int b = 0; b < played_boneInfos.Length; b++)
            {
                // Create it
                played_boneInfos[b] = new BoneInfo(current_clip.Bones[b]);

                // Assign it to a model bone
                played_boneInfos[b].SetModel(model);
            }

            Position = 0;
        }
示例#2
0
        /// <summary>
        /// Recursive function that processes the entire scene graph, collecting up
        /// all of the animation data.
        /// </summary>
        private void ProcessAnimationsRecursive(NodeContent input)
        {
            // Look up the bone for this input channel
            int inputBoneIndex;
            if (bones.TryGetValue(input.Name, out inputBoneIndex))
            {
                // Save the transform
                boneTransforms[inputBoneIndex] = input.Transform;
            }

            foreach (KeyValuePair<string, AnimationContent> animation in input.Animations)
            {
                // Do we have this animation before?
                AnimationClip clip;
                string clipName = animation.Key;

                if (!clips.TryGetValue(clipName, out clip))
                {
                    // Never seen before clip
                    clip = new AnimationClip();
                    modelExtra.Clips.Add(clipName,clip);

                    // Retain by name
                    clips[clipName] = clip;

                    clip.Name = clipName;
                    foreach (ModelBoneContent bone in model.Bones)
                    {
                        AnimationClip.Bone clipBone = new AnimationClip.Bone();
                        clipBone.Name = bone.Name;

                        clip.Bones.Add(clipBone);
                    }
                }

                // Ensure the duration is always set
                if (animation.Value.Duration.TotalSeconds > clip.Duration)
                    clip.Duration = animation.Value.Duration.TotalSeconds;

                //
                // For each channel, determine the bone and then process all of the
                // keyframes for that bone.
                //

                foreach (KeyValuePair<string, AnimationChannel> channel in animation.Value.Channels)
                {
                    // What is the bone index?
                    int boneIndex;
                    if (!bones.TryGetValue(channel.Key, out boneIndex))
                        continue;           // Ignore if not a named bone

                    // An animation is useless if it is for a bone not assigned to any meshes at all
                    if (UselessAnimationTest(boneIndex))
                        continue;

                    // I'm collecting up in a linked list so we can process the data
                    // and remove redundant keyframes
                    LinkedList<AnimationClip.Keyframe> keyframes = new LinkedList<AnimationClip.Keyframe>();
                    foreach (AnimationKeyframe keyframe in channel.Value)
                    {
                        Matrix transform = keyframe.Transform;      // Keyframe transformation

                        AnimationClip.Keyframe newKeyframe = new AnimationClip.Keyframe();
                        newKeyframe.Time = keyframe.Time.TotalSeconds;
                        newKeyframe.Transform = transform;

                        keyframes.AddLast(newKeyframe);
                    }

                    foreach (AnimationClip.Keyframe keyframe in keyframes)
                    {
                        clip.Bones[boneIndex].Keyframes.Add(keyframe);
                    }

                }

            }

            foreach (NodeContent child in input.Children)
            {
                ProcessAnimationsRecursive(child);
            }
        }
示例#3
0
        /// <summary>
        /// Entry point for animation processing. 
        /// </summary>
        /// <param name="model"></param>
        /// <param name="input"></param>
        /// <param name="context"></param>
        private void ProcessAnimations(ModelContent model, NodeContent input, ContentProcessorContext context, ContentIdentity sourceIdentity)
        {
            // First build a lookup table so we can determine the
            // index into the list of bones from a bone name.
            for (int i = 0; i < model.Bones.Count; i++)
            {
                bones[model.Bones[i].Name] = i;
            }

            // For saving the bone transforms
            boneTransforms = new Matrix[model.Bones.Count];

            //
            // Collect up all of the animation data
            //

            ProcessAnimationsRecursive(input);

            // Check to see if there's an animation clip definition
            // Here, we're checking for a file with the _Anims suffix.
            // So, if your model is named dude.fbx, we'd add dude_Anims.xml in the same folder
            // and the pipeline will see the file and use it to override the animations in the
            // original model file.
            string SourceModelFile = sourceIdentity.SourceFilename;
            string SourcePath = Path.GetDirectoryName(SourceModelFile);
            string AnimFilename = Path.GetFileNameWithoutExtension(SourceModelFile);
            AnimFilename += "_Anims.xml";
            string AnimPath = Path.Combine(SourcePath, AnimFilename);
            if (File.Exists(AnimPath))
            {
                // Add the filename as a dependency, so if it changes, the model is rebuilt
                context.AddDependency(AnimPath);

                // Load the animation definition from the XML file
                AnimationDefinition AnimDef = context.BuildAndLoadAsset<XmlImporter, AnimationDefinition>(new ExternalReference<XmlImporter>(AnimPath), null);

                if (modelExtra.Clips.Count > 0) //if there are some animations in our model
                {
                    foreach (AnimationDefinition.ClipPart Part in AnimDef.ClipParts)
                    {
                        // Grab the main clip that we are using and copy to MainClip

                        AnimationClip MainClip = new AnimationClip();

                        float StartTime = GetTimeSpanForFrame(Part.StartFrame, AnimDef.OriginalFrameCount, modelExtra.Clips[AnimDef.OriginalClipName].Duration);
                        float EndTime = GetTimeSpanForFrame(Part.EndFrame, AnimDef.OriginalFrameCount, modelExtra.Clips[AnimDef.OriginalClipName].Duration);

                        MainClip.Duration = EndTime-StartTime;
                        MainClip.Name = modelExtra.Clips[AnimDef.OriginalClipName].Name;

                        // Process each of our new animation clip parts
                        for (int i = 0; i < modelExtra.Clips[AnimDef.OriginalClipName].Bones.Count; i++)
                        {
                            AnimationClip.Bone clipBone = new AnimationClip.Bone();
                            clipBone.Name = modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Name;
                            LinkedList<AnimationClip.Keyframe> keyframes = new LinkedList<AnimationClip.Keyframe>();

                            if (modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes.Count != 0)
                            {

                                for (int j = 0; j < modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes.Count; j++)
                                {

                                    if ((modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes[j].Time >= StartTime) && (modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes[j].Time <= EndTime))
                                    {
                                        AnimationClip.Keyframe frame = new AnimationClip.Keyframe();
                                        frame.Rotation = modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes[j].Rotation;
                                        frame.Time = modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes[j].Time - StartTime;
                                        frame.Translation = modelExtra.Clips[AnimDef.OriginalClipName].Bones[i].Keyframes[j].Translation;
                                        keyframes.AddLast(frame);
                                       //clipBone.Keyframes.Add(frame);
                                    }

                                }
                            }
                           // LinearKeyframeReduction(keyframes);
                            clipBone.Keyframes = keyframes.ToList<AnimationClip.Keyframe>();
                            MainClip.Bones.Add(clipBone);

                        }
                        modelExtra.Clips.Add(Part.ClipName, MainClip);

                    }
                }
            }

            // Ensure there is always a clip, even if none is included in the FBX
            // That way we can create poses using FBX files as one-frame
            // animation clips
            if (modelExtra.Clips.Count == 0)
            {
                AnimationClip clip = new AnimationClip();
                modelExtra.Clips.Add("Take 001",clip);

                string clipName = "Take 001";

                // Retain by name
                clips[clipName] = clip;

                clip.Name = clipName;
                foreach (ModelBoneContent bone in model.Bones)
                {
                    AnimationClip.Bone clipBone = new AnimationClip.Bone();
                    clipBone.Name = bone.Name;

                    clip.Bones.Add(clipBone);
                }
            }

            //Ensure all animations have a first key frame for every bone
            foreach (KeyValuePair<string,AnimationClip> clip in modelExtra.Clips)
            {
                for (int b = 0; b < bones.Count; b++)
                {
                    List<AnimationClip.Keyframe> keyframes = clip.Value.Bones[b].Keyframes;
                    if (keyframes.Count == 0 || keyframes[0].Time > 0)
                    {
                        AnimationClip.Keyframe keyframe = new AnimationClip.Keyframe();
                        keyframe.Time = 0;
                        keyframe.Transform = boneTransforms[b];
                        keyframes.Insert(0, keyframe);
                    }
                }
            }
        }
示例#4
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="bone"></param>
 public BoneInfo(AnimationClip.Bone bone)
 {
     this.ClipBone = bone;
     SetKeyframes();
     SetPosition(0);
 }
示例#5
0
        /// <summary>
        /// Reset back to time zero.
        /// </summary>
        //public void Rewind()
        //{
        //    Position = 0;
        //}
        /// <summary>
        /// Update the clip position
        /// </summary>
        /// <param name="delta"></param>
        public void Update(GameTime gameTime)
        {
            #region Update current_clip
            current_Position = current_Position + (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (looping && current_Position >= current_clip.Duration)
                current_Position = 0;
            #endregion
             /*#region Update current_clip
             Position = Position + (float)gameTime.ElapsedGameTime.TotalSeconds;
             if (looping && Position >= Duration)
                 Position = 0;
             #endregion  */

            //if not blending, copy current transforms;
            if (next_clip == null)
            {
                #region Copying
                for (int i = 0; i < current_clip.Bones.Count(); i++)
                {
                    blendedBones[i] = new AnimationClip.Bone();
                    blendedBones[i].Name = current_clip.Bones[i].Name;
                    for (int j = 0; j < current_clip.Bones[i].Keyframes.Count(); j++)
                    {
                        blendedBones[i].Keyframes.Add(new AnimationClip.Keyframe());
                        blendedBones[i].Keyframes[j].Rotation = current_clip.Bones[i].Keyframes[j].Rotation;
                        blendedBones[i].Keyframes[j].Translation = current_clip.Bones[i].Keyframes[j].Translation;
                        blendedBones[i].Keyframes[j].Time = current_clip.Bones[i].Keyframes[j].Time;
                    }
                }
                #endregion
                for (int b = 0; b < blendedBones.Length; b++)
                {
                    // Create it
                    played_boneInfos[b] = new BoneInfo(blendedBones[b]);

                    // Assign it to a model bone
                    played_boneInfos[b].SetModel(model);
                }
                return;
            }

            //if we get there, means that we blending WOW!
               // #region Update next_clip
               // next_Position = next_Position + (float)gameTime.ElapsedGameTime.TotalSeconds;
               // if (looping && next_Position >= next_clip.Duration)
               //     next_Position = 0;
               // #endregion

            if (current_Position < current_clip.Duration)
            {

                if (currentblendTime.TotalSeconds > (float)current_clip.Duration) //we try to catch , where are we in current animation
                    currentblendTime = TimeSpan.Zero;
                else
                    currentblendTime += gameTime.ElapsedGameTime;

            }

            float blendAmount = (float)(currentblendTime.TotalSeconds / totalblendTime.TotalSeconds);

               // Console.WriteLine(blendAmount);

            if (blendAmount > 1.0f)
            {
                current_clip = next_clip;
                #region Copying
                for (int i = 0; i < current_clip.Bones.Count(); i++)
                {
                    blendedBones[i] = new AnimationClip.Bone();
                    blendedBones[i].Name = current_clip.Bones[i].Name;
                    for (int j = 0; j < current_clip.Bones[i].Keyframes.Count(); j++)
                    {
                        blendedBones[i].Keyframes.Add(new AnimationClip.Keyframe());
                        blendedBones[i].Keyframes[j].Rotation = current_clip.Bones[i].Keyframes[j].Rotation;
                        blendedBones[i].Keyframes[j].Translation = current_clip.Bones[i].Keyframes[j].Translation;
                        blendedBones[i].Keyframes[j].Time = current_clip.Bones[i].Keyframes[j].Time;
                    }
                }
                #endregion
                next_clip = null;
                for (int b = 0; b < blendedBones.Length; b++)
                {
                    // Create it
                    played_boneInfos[b] = new BoneInfo(blendedBones[b]);
                    // Assign it to a model bone
                    played_boneInfos[b].SetModel(model);
                }
               // Console.WriteLine("AFTER Blend Clip");
                return;

            }

               #region Blending
            Quaternion currentRotation, nextRotation, blendedRotation;
            Vector3 currentTranslation, nextTranslation, blendedTranslation;

            for (int i = 0; i < boneCnt; i++)
            {
                blendedBones[i] = new AnimationClip.Bone();
                blendedBones[i].Name = current_clip.Bones[i].Name;

               // Console.WriteLine(i + " Kość: " + blendedBones[i].Name + " Klatek: " + current_clip.Bones[i].Keyframes.Count());
                if (i == 0 || i == 1)
                {
                }
                else
                {

                    int h = 10;
                    if (current_clip.Bones[i].Keyframes.Count > next_clip.Bones[i].Keyframes.Count)
                        h = next_clip.Bones[i].Keyframes.Count;
                    else
                        h = current_clip.Bones[i].Keyframes.Count;
                    for (int j = 0; j < h; j++)
                    {
                        blendedBones[i].Keyframes.Add(new AnimationClip.Keyframe());

                        currentRotation = current_clip.Bones[i].Keyframes[j].Rotation;
                        currentTranslation = current_clip.Bones[i].Keyframes[j].Translation;
                        nextRotation = next_clip.Bones[i].Keyframes[j].Rotation;
                        nextTranslation = next_clip.Bones[i].Keyframes[j].Translation;

                        //Console.WriteLine("Obecna rotacja: "+currentRotation);
                        //Console.WriteLine("Obecna translacja: " + currentTranslation);
                        //Console.WriteLine("Nastepna rotacja: " + nextRotation);
                        //Console.WriteLine("Nastepna translacja: " + nextTranslation);
                        Quaternion.Slerp(ref currentRotation, ref nextRotation, blendAmount, out blendedRotation);
                        Vector3.Lerp(ref currentTranslation, ref nextTranslation, blendAmount, out blendedTranslation);

                          blendedBones[i].Keyframes[j].Rotation = blendedRotation;
                          blendedBones[i].Keyframes[j].Translation = blendedTranslation;
                          blendedBones[i].Keyframes[j].Time = current_clip.Bones[i].Keyframes[j].Time;

                              // Create it
                              played_boneInfos[i] = new BoneInfo(blendedBones[i]);

                              // Assign it to a model bone
                              played_boneInfos[i].SetModel(model);

                    }
                }
            }
             //   Console.WriteLine(current_clip.Bones[0].Keyframes.Count());
              //  Console.WriteLine(current_clip.Bones[1].Keyframes.Count());
             //   Console.WriteLine(current_clip.Bones[2].Keyframes.Count());

             //   Console.WriteLine(next_clip.Bones[0].Keyframes.Count());
             //   Console.WriteLine(next_clip.Bones[1].Keyframes.Count());
             //   Console.WriteLine(next_clip.Bones[2].Keyframes.Count());

             // System.Threading.Thread.Sleep(100000);

               // Console.WriteLine(blendAmount);
            #endregion
        }
示例#6
0
 public void PlayClip(String name, Boolean looping)
 {
     this.looping = looping;
     next_clip = Clips[name];
     currentblendTime = TimeSpan.Zero;
     next_position = 0;
 }