custom FbxImporter to import multi animations from single FBX file for xna 4.0

   Thanks the original code, the link is here http://xnanimation.codeplex.com/discussions/254116  . I make some modification for xna 4.0 project.

Original xna fbx importer only import first animation in .fbx file,  use this customer fbx importer to pick all animation from fbx file. I use blender2.6 to make multi action animations , and export to fbx format file with xna options checked.

    

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;

// TODO: replace this with the type you want to import.
using TImport = Microsoft.Xna.Framework.Content.Pipeline.Graphics.NodeContent;

namespace SkinModelProcessor
{
    /// <summary>
    /// This class will be instantiated by the XNA Framework Content Pipeline
    /// to import a file from disk into the specified type, TImport.
    /// 
    /// This should be part of a Content Pipeline Extension Library project.
    /// 
    /// TODO: change the ContentImporter attribute to specify the correct file
    /// extension, display name, and default processor for this importer.
    /// </summary>
    [ContentImporter(".fbx", DisplayName = "Multi-take FBX Importer", DefaultProcessor = "SkinModelProcessor")]
    public class SkinnedModelImporter : FbxImporter
    {
        private List<string> _animfiles;
        private List<string> _fbxheader;
        private TImport _master;
        private ContentImporterContext _context;

        public override TImport Import(string filename, ContentImporterContext context)
        {
            // TODO: read the specified file into an instance of the imported type.
            _context = context;

            // _animfiles will contain list of new temp anim files.
            _animfiles = new List<string>();

            // Decouple header and animation data.
            ExtractAnimations(filename);

            // Process master file (this will also process the first animation)
            _master = base.Import(filename, context);

            // Process the remaining animations.
            foreach (string file in _animfiles)
            {
                NodeContent anim = base.Import(file, context);

                // Append animation to master NodeContent.
                AppendAnimation(_master, anim);
            }

            // Delete the temporary animation files.
            DeleteTempFiles();

            return _master;
            //throw new NotImplementedException();
        }

        private void AppendAnimation(NodeContent masternode, NodeContent animnode)
        {
            foreach (KeyValuePair<string, AnimationContent> anim in animnode.Animations)
            {
                masternode.Animations.Add(anim.Key, anim.Value);
            }

            //foreach (NodeContent child in animnode.Children) {
            //    if (child != null) {
            //        AppendAnimation(child);
            //    }
            //}

            for (int i = 0; i < masternode.Children.Count; i++)
            {
                if (animnode.Children[i] != null)
                {
                    AppendAnimation(masternode.Children[i], animnode.Children[i]);
                }
            }
        }

        private void ExtractAnimations(string filename)
        {
            List<string> masterFile = File.ReadAllLines(filename).ToList();
            string path = Path.GetDirectoryName(filename);
            int open_idx = 0,
                length,
                num_open = -1,
                filenum = 0;
            bool foundTake = false;

            int idx = masterFile.IndexOf("Takes:  {") + 1;
            _fbxheader = masterFile.Take(idx).ToList();
            List<string> anims = masterFile.Skip(idx).ToList();

            // Extract each animation and create a temporary anim file.
            for (int i = 0; i < anims.Count; i++)
            {
                if (anims[i].Contains("Take: "))
                {
                    open_idx = i;
                    num_open = 0;
                    foundTake = true;
                }

                if (anims[i].Contains("{") &&
                    foundTake)
                {
                    num_open++;
                }

                if (anims[i].Contains("}") &&
                    foundTake)
                {
                    num_open--;
                }

                if (num_open == 0 &&
                    foundTake)
                {
                    // Skip first animation since this is processed in the master
                    // fbx file.
                    if (filenum > 0)
                    {
                        length = i - open_idx + 1;

                        // Create temp file from header + anim data.
                        CreateTempFile(Path.Combine(path, "tmp.anim." + filenum + ".fbx"),
                                       anims.Skip(open_idx).Take(length).ToArray());
                    }
                    filenum++;
                    foundTake = false;
                }
            }
        }

        private void CreateTempFile(string filename, string[] data)
        {
            List<string> completefile = new List<string>();
            completefile.AddRange(_fbxheader);
            completefile.AddRange(data);

            try
            {
                // Write data to new temp file.
                File.WriteAllLines(filename, completefile.ToArray());

                // Store temp file name for processing.
                _animfiles.Add(filename);
            }
            catch
            {
                // Error while creating temp file.
                _context.Logger.LogWarning(null, null, "Error creating temp file: {0}", filename);
            }
        }

        private void DeleteTempFiles()
        {
            foreach (string file in _animfiles)
            {
                File.Delete(file);
            }
        }
    }
}

  Run result 

 

posted @ 2014-01-03 18:07  银龙  阅读(327)  评论(0)    收藏  举报