Exemple #1
0
        public new static FbxImporter Create(FbxObject pContainer, string pName)
        {
            global::System.IntPtr cPtr = fbx_wrapperPINVOKE.FbxImporter_Create__SWIG_1(FbxObject.getCPtr(pContainer), pName);
            FbxImporter           ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxImporter(cPtr, false);

            return(ret);
        }
Exemple #2
0
        public new static FbxImporter Create(FbxManager pManager, string pName)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxImporter_Create__SWIG_0(FbxManager.getCPtr(pManager), pName);
            FbxImporter           ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxImporter(cPtr, false);

            return(ret);
        }
        public void FbxNonSkeletonAnimationTest()
        {
            var importer    = new FbxImporter();
            var nodeContent = importer.Import("Assets/Models/NonSkeletonAnimated.fbx", null);

            Assert.AreEqual(1, nodeContent.Animations.Count);
        }
Exemple #4
0
        public static void Main(string [] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.Error.WriteLine("Usage: FbxPrint.exe FILENAME [ FILENAME ... ]");
                return;
            }

            bool tokens = false;
            bool parse  = false;

            foreach (var filename in args)
            {
                if (filename == "--tokens")
                {
                    tokens = true;
                    continue;
                }
                if (filename == "--parse")
                {
                    parse = true;
                    continue;
                }

                if (tokens)
                {
                    using (var reader = new StreamReader(filename))
                    {
                        var t     = new Tokenizer(reader, filename: filename);
                        var token = t.GetNextToken();
                        while (token.HasValue)
                        {
                            var tt = token.Value;
                            Console.WriteLine("\"{0}\", {1}, {2}", tt.Value, tt.Type, tt.Location);
                            token = t.GetNextToken();
                        }
                    }
                    continue;
                }
                if (parse)
                {
                    using (var reader = new StreamReader(filename))
                    {
                        var p    = new Parser(new Tokenizer(reader, filename: filename));
                        var objs = p.ReadFile();
                        foreach (var obj in objs)
                        {
                            PrintParseObject(obj);
                        }
                    }
                    continue;
                }
                var importer = new FbxImporter(filename);
                var scene    = importer.Import(filename);

                var printer = new FbxSharp.ObjectPrinter();
                printer.PrintObjectGraph(scene);
            }
        }
Exemple #5
0
 public bool Equals(FbxImporter other)
 {
     if (object.ReferenceEquals(other, null))
     {
         return(false);
     }
     return(this.swigCPtr.Handle.Equals(other.swigCPtr.Handle));
 }
        public void EmptyExportImportTest()
        {
            int  N     = 10;
            long total = 0;

            for (int i = 0; i < N; i++)
            {
                m_stopwatch.Reset();
                m_stopwatch.Start();

                FbxIOSettings ioSettings = FbxIOSettings.Create(m_fbxManager, Globals.IOSROOT);
                m_fbxManager.SetIOSettings(ioSettings);

                FbxExporter exporter = FbxExporter.Create(m_fbxManager, "");

                string filename = "test.fbx";

                bool exportStatus = exporter.Initialize(filename, -1, m_fbxManager.GetIOSettings());

                // Check that export status is True
                Assert.IsTrue(exportStatus);

                // Create an empty scene to export
                FbxScene scene = FbxScene.Create(m_fbxManager, "myScene");

                // Export the scene to the file.
                exporter.Export(scene);

                exporter.Destroy();

                // Import to make sure file is valid

                FbxImporter importer = FbxImporter.Create(m_fbxManager, "");

                bool importStatus = importer.Initialize(filename, -1, m_fbxManager.GetIOSettings());

                Assert.IsTrue(importStatus);

                // Create a new scene so it can be populated
                FbxScene newScene = FbxScene.Create(m_fbxManager, "myScene2");

                importer.Import(newScene);

                importer.Destroy();

                m_stopwatch.Stop();

                total += m_stopwatch.ElapsedMilliseconds;

                // Delete the file once the test is complete
                File.Delete(filename);
            }

            CheckAgainstNative("EmptyExportImport", total / (float)N, N, 4);
        }
        public FbxReader CreateReader(FbxManager pManager, FbxImporter pImporter, int pPluginID)
        {
            global::System.IntPtr cPtr = FbxWrapperNativePINVOKE.FbxIOPluginRegistry_CreateReader(swigCPtr, FbxManager.getCPtr(pManager), FbxImporter.getCPtr(pImporter), pPluginID);
            FbxReader             ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxReader(cPtr, false);

            if (FbxWrapperNativePINVOKE.SWIGPendingException.Pending)
            {
                throw FbxWrapperNativePINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
Exemple #8
0
        public new static FbxImporter Create(FbxObject pContainer, string pName)
        {
            global::System.IntPtr cPtr = NativeMethods.FbxImporter_Create__SWIG_1(FbxObject.getCPtr(pContainer), pName);
            FbxImporter           ret  = (cPtr == global::System.IntPtr.Zero) ? null : new FbxImporter(cPtr, false);

            if (NativeMethods.SWIGPendingException.Pending)
            {
                throw NativeMethods.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
        public void Arguments()
        {
            var context  = new TestImporterContext("TestObj", "TestBin");
            var importer = new FbxImporter();

            Assert.Throws <ArgumentNullException>(() => importer.Import(null, context));
            Assert.Throws <FileNotFoundException>(() => importer.Import("does_not_exist", context));

            // XNA bug/omission:  crashes with a NullReferenceException
            // where as we correctly throw a ArgumentNullException.
#if XNA
            Assert.Throws <NullReferenceException>(() => importer.Import(DudeFbx, null));
#else
            Assert.Throws <ArgumentNullException>(() => importer.Import("file", null));
#endif
        }
Exemple #10
0
        public static void Main(string [] args)
        {
            if (args == null || args.Length < 1)
            {
                Console.Error.WriteLine("Usage: FbxPrint.exe FILENAME [ FILENAME ... ]");
                return;
            }

            foreach (var filename in args)
            {
                var importer = new FbxImporter(filename);
                var scene    = importer.Import(filename);

                var printer = new FbxSharp.ObjectPrinter();
                printer.PrintObjectGraph(scene);
            }
        }
Exemple #11
0
        public (GameObject, List <string> warnings, ImportMaterialCollector) Import()
        {
            FbxManager    fbxManager = FbxManager.Create();
            FbxIOSettings ioSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT);

            fbxManager.SetIOSettings(ioSettings);
            FbxImporter fbxImporter = FbxImporter.Create(fbxManager, "");

            if (!fbxImporter.Initialize(m_path, -1, ioSettings))
            {
                warnings.Add("Failed to initialize FBX importer");
                return(null, warnings, null);
            }
            FbxScene scene = FbxScene.Create(fbxManager, "scene");

            fbxImporter.Import(scene);

            FbxNode root = scene.GetRootNode();

            SetPivots(root);
            root.ConvertPivotAnimationRecursive(null, FbxNode.EPivotSet.eDestinationPivot, 30);
            long totalVerts     = GetTotalVerts(root);
            long completedVerts = 0;

            float fbxUnitToTiltUnit; {
                var unit = scene.GetGlobalSettings().GetSystemUnit();
                if (Path.GetExtension(m_path).ToLower() == ".obj")
                {
                    // Obj doesn't specify units. We'd rather assume m, but fbx assumes cm.
                    unit = FbxSystemUnit.m;
                }
                fbxUnitToTiltUnit = (float)unit.GetConversionFactorTo(FbxSystemUnit.m)
                                    * App.METERS_TO_UNITS;
            }

            GameObject go = ImportNodes(
                root, fbxUnitToTiltUnit, ref completedVerts, totalVerts);

            Debug.Assert(completedVerts == totalVerts);
            fbxImporter.Destroy();
            ioSettings.Destroy();
            fbxManager.Destroy();

            return(go, warnings.Distinct().ToList(), m_collector);
        }
        private void FbxImportAndTestBlendshapes(string fbxPath)
        {
            // Create the FBX manager
            using (var fbxManager = FbxManager.Create())
            {
                FbxIOSettings fbxIOSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT);

                // Configure the IO settings.
                fbxManager.SetIOSettings(fbxIOSettings);

                // Create the importer
                var fbxImporter = FbxImporter.Create(fbxManager, "Importer");

                // Initialize the importer.
                int fileFormat = -1;

                bool      status    = fbxImporter.Initialize(fbxPath, fileFormat, fbxIOSettings);
                FbxStatus fbxStatus = fbxImporter.GetStatus();

                Assert.That(status, Is.True, fbxStatus.GetErrorString());
                Assert.That(fbxImporter.IsFBX(), "file does not contain FBX data");

                // Import options. Determine what kind of data is to be imported.
                // The default is true, but here we set the options explictly.
                fbxIOSettings.SetBoolProp(Globals.IMP_FBX_MATERIAL, false);
                fbxIOSettings.SetBoolProp(Globals.IMP_FBX_TEXTURE, false);
                fbxIOSettings.SetBoolProp(Globals.IMP_FBX_ANIMATION, false);
                fbxIOSettings.SetBoolProp(Globals.IMP_FBX_EXTRACT_EMBEDDED_DATA, false);
                fbxIOSettings.SetBoolProp(Globals.IMP_FBX_GLOBAL_SETTINGS, true);

                // Create a scene
                var fbxScene = FbxScene.Create(fbxManager, "Scene");

                // Import the scene to the file.
                status    = fbxImporter.Import(fbxScene);
                fbxStatus = fbxImporter.GetStatus();
                Assert.That(status, Is.True, fbxStatus.GetErrorString());

                // Get blendshapes and check that the FbxShapes all have names
                var rootNode = fbxScene.GetRootNode();
                TestFbxShapeNamesNotEmpty(rootNode);
            }
        }
        protected void ImportScene(string fileName)
        {
            // Import the scene to make sure file is valid
            using (FbxImporter importer = FbxImporter.Create(FbxManager, "myImporter")) {
                // Initialize the importer.
                bool status = importer.Initialize(fileName, -1, FbxManager.GetIOSettings());

                Assert.IsTrue(status);

                // Create a new scene so it can be populated by the imported file.
                FbxScene scene = FbxScene.Create(FbxManager, "myScene");

                // Import the contents of the file into the scene.
                importer.Import(scene);

                // check that the scene is valid
                CheckScene(scene);
            }
        }
    /// <summary>
    /// Try to import into the given scene.
    /// Return the nodes we created.
    /// </summary>
    Dictionary <GameObject, FbxNode> TryImport(Settings settings, FbxScene scene)
    {
        using (var importer = FbxImporter.Create(scene.GetFbxManager(), ""))
        {
            if (!importer.Initialize(settings.m_FileName))
            {
                return(null);
            }
            if (!importer.Import(scene))
            {
                return(null);
            }
            // Unity: Y-up, right is +X, forward is +Z (left-handed)
            var axes = new FbxAxisSystem(
                FbxAxisSystem.EUpVector.eYAxis,
                FbxAxisSystem.EFrontVector.eParityOdd,
                FbxAxisSystem.ECoordSystem.eLeftHanded);

            // Convert as needed.
            switch (settings.m_Conversion)
            {
            case Settings.Conversion.Legacy:
                axes.ConvertScene(scene);
                break;

            case Settings.Conversion.Deep:
                axes.DeepConvertScene(scene);
                break;

            case Settings.Conversion.None:
                break;
            }

            // The root node is this node. We won't set ourselves up to match the FBX root;
            // normally it's just a null.
            var root  = scene.GetRootNode();
            var nodes = new Dictionary <GameObject, FbxNode>();
            CreateChildren(this.transform, root, nodes);

            return(nodes);
        }
    }
Exemple #15
0
        public static void Main(string [] args)
        {
            Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;


            if (args == null || args.Length < 1)
            {
                Console.Error.WriteLine("Usage: FbxPrint.exe FILENAME [ FILENAME ... ]");
                return;
            }

            foreach (var filename in args)
            {
                var importer = new FbxImporter(filename);
                var scene    = importer.Import(filename);

                var printer = new FbxSharp.ObjectPrinter();
                printer.PrintObjectGraph(scene);
            }
        }
Exemple #16
0
        // Import scene sample
        protected void ImportScene(string fileName)
        {
            using (FbxManager fbxManager = FbxManager.Create())
            {
                // configure IO settings.
                fbxManager.SetIOSettings(FbxIOSettings.Create(fbxManager, Globals.IOSROOT));

                // Import the scene to make sure file is valid
                using (FbxImporter importer = FbxImporter.Create(fbxManager, "myImporter"))
                {
                    // Initialize the importer.
                    bool status = importer.Initialize(fileName, -1, fbxManager.GetIOSettings());

                    // Create a new scene so it can be populated by the imported file.
                    FbxScene scene = FbxScene.Create(fbxManager, "myScene");

                    // Import the contents of the file into the scene.
                    importer.Import(scene);
                }
            }
        }
Exemple #17
0
        void Run()
        {
            FbxManager    manager = FbxManager.Create();
            FbxIOSettings setting = FbxIOSettings.Create(manager, "IOSRoot");

            manager.SetIOSettings(setting);

            FbxImporter impoter = FbxImporter.Create(manager, "");

            bool status = impoter.Initialize(@"D:\develop\FbxWrapper\1.fbx", -1, setting);

            Log.Info(status);

            if (!status)
            {
                return;
            }

            FbxScene scene = FbxScene.Create(manager, "scene1");

            status = impoter.Import(scene);
            Log.Info(status);


            int numTrack = scene.GetSrcObjectCount(FbxAnimStack.ClassId);

            Log.Info("num stack " + numTrack);

            FbxObject obj = scene.GetSrcObject(FbxAnimStack.ClassId, 0);

            FbxAnimStack stack = FbxAnimStack.Cast(obj);

            if (stack == null)
            {
                Log.Error("can not get anim stack!");
                return;
            }

            FbxCriteria cri      = FbxCriteria.ObjectTypeStrict(FbxAnimLayer.ClassId);
            int         numLayer = stack.GetMemberCount(cri);

            Log.Info("anim layer count : " + numLayer);

            FbxAnimLayer layer = null;

            if (numLayer > 0)
            {
                FbxObject layerobj = stack.GetMember(cri, 0);
                layer = FbxAnimLayer.Cast(layerobj);
                if (layer == null)
                {
                    Log.Error("anim layer is null!");
                    return;
                }

                Log.Info("anim layer name " + layer.GetName());
            }


            Log.Info("node count " + scene.GetNodeCount());
            for (int i = 0; i < scene.GetNodeCount(); i++)
            {
                FbxNode node = scene.GetNode(i);
                Log.Info("node " + i + " " + node.GetName());

                if (node.LclTranslation.IsAnimated(layer))
                {
                    FbxAnimCurveNode curveNode = node.LclTranslation.GetCurveNode(layer);
                    if (curveNode == null)
                    {
                        Log.Error("curve node is null");
                    }
                    else
                    {
                        for (int c = 0; c < curveNode.GetCurveCount(0); c++)
                        {
                            FbxAnimCurve curve = curveNode.GetCurve(0, (uint)c);
                            if (curve != null)
                            {
                                Log.Info("curve " + curve.GetName());
                                Log.Info("key count " + curve.KeyGetCount());
                                FbxAnimCurveKey key = curve.KeyGet(0);
                                FbxTime         t   = key.GetTime();
                                Log.Info("key " + t.GetTimeString() + " value " + key.GetValue());
                            }
                        }
                    }
                }



                if (node.GetNodeAttribute() != null)
                {
                    Log.Info("got attribu");
                    FbxNodeAttribute att = node.GetNodeAttribute();
                    PrintAttribute(att);
                }
                else
                {
                    Log.Info("att count " + node.GetNodeAttributeCount());
                    for (int j = 0; j < node.GetNodeAttributeCount(); j++)
                    {
                        FbxNodeAttribute att = node.GetNodeAttributeByIndex(j);
                        PrintAttribute(att);
                    }
                }

                FbxVector4    rot = node.GetPostRotation(FbxNode.EPivotSet.eSourcePivot);
                FbxQuaternion q;
            }
        }
Exemple #18
0
        //static bool ContainsMeshesRecursive( Node node )
        //{
        //	if( node.HasMeshes )
        //		return true;
        //	foreach( var child in node.Children )
        //	{
        //		if( ContainsMeshesRecursive( child ) )
        //			return true;
        //	}
        //	return false;
        //}

        public static void DoImport(Settings settings, out string error)
        {
            error = "(NO ERROR MESSAGE)";
            LoadNativeLibrary();

            FbxManager    manager  = null;
            FbxIOSettings setting  = null;
            FbxImporter   importer = null;
            FbxScene      scene    = null;

            try
            {
                manager = FbxManager.Create();
                setting = FbxIOSettings.Create(manager, "IOSRoot");
                manager.SetIOSettings(setting);

                importer = FbxImporter.Create(manager, "");
                var realFileName = VirtualPathUtility.GetRealPathByVirtual(settings.virtualFileName);
                //VirtualFileStream stream = null;
                //ToDo : FromStream
                bool status;
                if (!string.IsNullOrEmpty(realFileName) && File.Exists(realFileName))
                {
                    status = importer.Initialize(realFileName, -1, setting);
                }
                else
                {
                    error = "File is not exists.";
                    return;
                    //throw new NotImplementedException();
                    //ToDo : ....
                    //stream = VirtualFile.Open( settings.virtualFileName );
                    //FbxStream fbxStream = null;
                    //SWIGTYPE_p_void streamData = null;

                    //status = impoter.Initialize( fbxStream, streamData, -1, setting );
                }

                if (!status)
                {
                    return;
                }

                scene  = FbxScene.Create(manager, "scene1");
                status = importer.Import(scene);
                if (!status)
                {
                    return;
                }

                error = "";
                var importContext = new ImportContext();
                importContext.manager       = manager;
                importContext.scene         = scene;
                importContext.settings      = settings;
                importContext.directoryName = Path.GetDirectoryName(settings.virtualFileName);

                ImportScene(importContext);

                ////create meshes (Scene mode)
                //if( settings.component.Mode.Value == Component_Import3D.ModeEnum.Scene /*&& scene.HasMeshes && scene.MeshCount != 0 */)
                //{
                //	importContext.meshesGroup = settings.component.GetComponentByName( "Meshes" ) as Component_Mesh;
                //	if( importContext.meshesGroup == null )
                //	{
                //		importContext.meshesGroup = settings.component.CreateComponent<Component>( -1, false );
                //		importContext.meshesGroup.Name = "Meshes";
                //	}
                //	else
                //		importContext.meshesGroup.Enabled = false;
                //}

                ////enable groups
                //if( importContext.meshesGroup != null )
                //	importContext.meshesGroup.Enabled = true;
                //if( importContext.sceneObjectsGroup != null )
                //	importContext.sceneObjectsGroup.Enabled = true;

                //stream?.Dispose();
            }
            finally
            {
                //Особенности удаления.
                //Создается через функцию: impoter = FbxImporter.Create(manager, "");
                //В таких случаях(создание не через конструктор, а возврат указателя из функции) SWIG задает флажок что объект не владеет ссылкой, поэтому Dispose ничего не делает.
                //Хотя в SWIG можно задать в конфигурации: %newobject FbxImporter::Create; Тогда объект будет владеть ссылкой. Но все равно в С++ наследники FbxObject не имеют public destructor
                //поэтому в Dispose вставлен: throw new MethodAccessException("C++ destructor does not have public access"). Поэтому удалять только через Destroy.

                try { scene?.Destroy(); } catch { }
                try { importer?.Destroy(); } catch { }
                try { setting?.Destroy(); } catch { }
                try { manager?.Destroy(); } catch { }
            }
        }
Exemple #19
0
            /// <summary>
            /// Import all from scene.
            /// Return the number of objects we imported.
            /// </summary>
            public int ImportAll()
            {
                // Create the FBX manager
                using (var fbxManager = FbxManager.Create())
                {
                    FbxIOSettings fbxIOSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT);

                    // Configure the IO settings.
                    fbxManager.SetIOSettings(fbxIOSettings);

                    // Get the version number of the FBX files generated by the
                    // version of FBX SDK that you are using.
                    int sdkMajor = -1, sdkMinor = -1, sdkRevision = -1;
                    FbxManager.GetFileFormatVersion(out sdkMajor, out sdkMinor, out sdkRevision);

                    // Create the importer
                    var fbxImporter = FbxImporter.Create(fbxManager, "Importer");

                    // Initialize the importer.
                    int fileFormat = -1;

                    bool      status    = fbxImporter.Initialize(LastFilePath, fileFormat, fbxIOSettings);
                    FbxStatus fbxStatus = fbxImporter.GetStatus();

                    // Get the version number of the FBX file format.
                    int fileMajor = -1, fileMinor = -1, fileRevision = -1;
                    fbxImporter.GetFileVersion(out fileMajor, out fileMinor, out fileRevision);

                    // Check that initialization of the fbxImporter was successful
                    if (!status)
                    {
                        Debug.LogError(string.Format("failed to initialize FbxImporter, error returned {0}",
                                                     fbxStatus.GetErrorString()));

                        if (fbxStatus.GetCode() == FbxStatus.EStatusCode.eInvalidFileVersion)
                        {
                            Debug.LogError(string.Format("Invalid file version detected\nSDK version: {0}.{1}.{2}\nFile version: {3}.{4}.{5}",
                                                         sdkMajor, sdkMinor, sdkRevision,
                                                         fileMajor, fileMinor, fileRevision));
                        }

                        return(0);
                    }

                    // Import options. Determine what kind of data is to be imported.
                    // The default is true, but here we set the options explictly.
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_MATERIAL, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_TEXTURE, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_ANIMATION, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_EXTRACT_EMBEDDED_DATA, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_GLOBAL_SETTINGS, true);

                    // Create a scene
                    var fbxScene = FbxScene.Create(fbxManager, "Scene");

                    // Import the scene to the file.
                    status = fbxImporter.Import(fbxScene);

                    if (status == false)
                    {
                        Debug.LogError(string.Format("failed to import file ({0})",
                                                     fbxImporter.GetStatus().GetErrorString()));
                    }
                    else
                    {
                        // import data into scene
                        ProcessScene(fbxScene);
                    }

                    // cleanup
                    fbxScene.Destroy();
                    fbxImporter.Destroy();

                    return(status == true ? NumNodes : 0);
                }
            }
Exemple #20
0
        void Run()
        {
            FbxManager    manager = FbxManager.Create();
            FbxIOSettings setting = FbxIOSettings.Create(manager, "IOSRoot");

            //fbxiosettingspath.h
            //PostProcessSteps.CalculateTangentSpace = #define EXP_TANGENTSPACE				EXP_GEOMETRY "|" IOSN_TANGENTS_BINORMALS
            //PostProcessSteps.JoinIdenticalVertices = #define IOSN_DXF_WELD_VERTICES           "WeldVertices"
            //PostProcessSteps.Triangulate = #define IOSN_TRIANGULATE                "Triangulate"
            //PostProcessSteps.RemoveComponent =
            //PostProcessSteps.GenerateSmoothNormals =
            //setting.AddProperty()
            setting.SetBoolProp("Import|AdvOptGrp|Dxf|WeldVertices", true);
            setting.SetBoolProp("Triangulate", true);

            manager.SetIOSettings(setting);

            FbxImporter impoter = FbxImporter.Create(manager, "");

            bool status = impoter.Initialize(@"1.fbx", -1, setting);

            Log.Info(status);

            if (!status)
            {
                return;
            }

            FbxScene scene = FbxScene.Create(manager, "scene1");

            status = impoter.Import(scene);
            Log.Info(status);


            int numTrack = scene.GetSrcObjectCount(FbxCriteria.ObjectType(FbxAnimStack.ClassId));

            Log.Info("num stack " + numTrack);

            FbxObject obj = scene.GetSrcObject(FbxCriteria.ObjectType(FbxAnimStack.ClassId), 0);

            FbxAnimStack stack = FbxAnimStack.Cast(obj);

            if (stack == null)
            {
                Log.Error("can not get anim stack!");
                return;
            }

            FbxCriteria cri      = FbxCriteria.ObjectTypeStrict(FbxAnimLayer.ClassId);
            int         numLayer = stack.GetMemberCount(cri);

            Log.Info("anim layer count : " + numLayer);

            FbxAnimLayer layer = null;

            if (numLayer > 0)
            {
                FbxObject layerobj = stack.GetMember(cri, 0);
                layer = FbxAnimLayer.Cast(layerobj);
                if (layer == null)
                {
                    Log.Error("anim layer is null!");
                    return;
                }

                Log.Info("anim layer name " + layer.GetName());
            }


            Log.Info("node count " + scene.GetNodeCount());
            for (int i = 0; i < scene.GetNodeCount(); i++)
            {
                FbxNode node = scene.GetNode(i);
                Log.Info("node " + i + " " + node.GetName() + " ChildCount:" + node.GetChildCount());

                //----------------
                //node.LclTranslation.IsAnimated
                //----------------
                //ToDo :

                if (node.LclTranslation.IsAnimated(layer))
                {
                    FbxAnimCurveNode curveNode = node.LclTranslation.GetCurveNode(layer);
                    if (curveNode == null)
                    {
                        Log.Error("curve node is null");
                    }
                    else
                    {
                        for (int c = 0; c < curveNode.GetCurveCount(0); c++)
                        {
                            FbxAnimCurve curve = curveNode.GetCurve(0, (uint)c);
                            if (curve != null)
                            {
                                Log.Info("curve " + curve.GetName());
                                Log.Info("key count " + curve.KeyGetCount());
                                FbxAnimCurveKey key = curve.KeyGet(0);
                                FbxTime         t   = key.GetTime();
                                Log.Info("key " + t.GetTimeString() + " value " + key.GetValue());
                            }
                        }
                    }
                }



                if (node.GetNodeAttribute() != null)
                {
                    Log.Info("got attribu");
                    FbxNodeAttribute att = node.GetNodeAttribute();
                    PrintAttribute(manager, att);
                }
                else
                {
                    Log.Info("att count " + node.GetNodeAttributeCount());
                    for (int j = 0; j < node.GetNodeAttributeCount(); j++)
                    {
                        FbxNodeAttribute att = node.GetNodeAttributeByIndex(j);
                        PrintAttribute(manager, att);
                    }
                }

                FbxVector4    rot = node.GetPostRotation(FbxNode.EPivotSet.eSourcePivot);
                FbxQuaternion q;
            }
        }
Exemple #21
0
            /// <summary>
            /// Import all from scene.
            /// Return the number of objects we imported.
            /// </summary>
            public int ImportAll(IEnumerable <UnityEngine.Object> unitySelectionSet)
            {
                // Create the FBX manager
                using (var fbxManager = FbxManager.Create())
                {
                    FbxIOSettings fbxIOSettings = FbxIOSettings.Create(fbxManager, Globals.IOSROOT);

                    // Configure the IO settings.
                    fbxManager.SetIOSettings(fbxIOSettings);

                    // Get the version number of the FBX files generated by the
                    // version of FBX SDK that you are using.
                    int sdkMajor = -1, sdkMinor = -1, sdkRevision = -1;

                    FbxManager.GetFileFormatVersion(out sdkMajor, out sdkMinor, out sdkRevision);

                    // Create the importer
                    var fbxImporter = FbxImporter.Create(fbxManager, "Importer");

                    // Initialize the importer.
                    int fileFormat = -1;

                    bool      status    = fbxImporter.Initialize(LastFilePath, fileFormat, fbxIOSettings);
                    FbxStatus fbxStatus = fbxImporter.GetStatus();

                    // Get the version number of the FBX file format.
                    int fileMajor = -1, fileMinor = -1, fileRevision = -1;
                    fbxImporter.GetFileVersion(out fileMajor, out fileMinor, out fileRevision);

                    // Check that initialization of the fbxImporter was successful
                    if (!status)
                    {
                        Debug.LogError(string.Format("failed to initialize FbxImporter, error returned {0}",
                                                     fbxStatus.GetErrorString()));

                        if (fbxStatus.GetCode() == FbxStatus.EStatusCode.eInvalidFileVersion)
                        {
                            Debug.LogError(string.Format("Invalid file version detected\nSDK version: {0}.{1}.{2}\nFile version: {3}.{4}.{5}",
                                                         sdkMajor, sdkMinor, sdkRevision,
                                                         fileMajor, fileMinor, fileRevision));
                        }

                        return(0);
                    }

                    MsgLine.Add("Import Scene Report");
                    MsgLine.Add(kBorderLine);

                    MsgLine.Add(kPadding + string.Format("FilePath: {0}", LastFilePath));
                    MsgLine.Add(kPadding + string.Format("SDK version: {0}.{1}.{2}",
                                                         sdkMajor, sdkMinor, sdkRevision));

                    if (!fbxImporter.IsFBX())
                    {
                        Debug.LogError(string.Format("file does not contain FBX data {0}", LastFilePath));
                        return(0);
                    }

                    MsgLine.Add(kPadding + string.Format("File version: {0}.{1}.{2}",
                                                         fileMajor, fileMinor, fileRevision));

                    MsgLine.Add(kBorderLine);
                    MsgLine.Add("Animation");
                    MsgLine.Add(kBorderLine);

                    int numAnimStack = fbxImporter.GetAnimStackCount();

                    MsgLine.Add(kPadding + string.Format("number of stacks: {0}", numAnimStack));
                    MsgLine.Add(kPadding + string.Format("active animation stack: \"{0}\"\n", fbxImporter.GetActiveAnimStackName()));

                    for (int i = 0; i < numAnimStack; i++)
                    {
#if UNI_18972
                        FbxTakeInfo fbxTakeInfo = fbxImporter.GetTakeInfo(i);
                        MsgLine.Add(kPadding + string.Format("Animation Stack ({0})", i));
                        MsgLine.Add(kPadding + string.Format("name: \"{0}\"", fbxTakeInfo.mName) + string.kNewLine);
                        MsgLine.Add(kPadding + string.Format("description: \"{0}\"", fbxTakeInfo.mDescription));
                        MsgLine.Add(kPadding + string.Format("import name: \"{0}\"", fbxTakeInfo.mImportName));
                        MsgLine.Add(kPadding + string.Format("import state: \"{0}\"", fbxTakeInfo.mSelect));
#endif
                    }

                    // Import options. Determine what kind of data is to be imported.
                    // The default is true, but here we set the options explictly.
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_MATERIAL, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_TEXTURE, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_ANIMATION, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_EXTRACT_EMBEDDED_DATA, false);
                    fbxIOSettings.SetBoolProp(Globals.IMP_FBX_GLOBAL_SETTINGS, true);

                    // Create a scene
                    var fbxScene = FbxScene.Create(fbxManager, "Scene");

                    // Import the scene to the file.
                    status    = fbxImporter.Import(fbxScene);
                    fbxStatus = fbxImporter.GetStatus();

                    if (status == false)
                    {
                        if (fbxStatus.GetCode() == FbxStatus.EStatusCode.ePasswordError)
                        {
                            Debug.LogError(string.Format("failed to import, file is password protected ({0})", fbxStatus.GetErrorString()));
                        }
                        else
                        {
                            Debug.LogError(string.Format("failed to import file ({0})", fbxStatus.GetErrorString()));
                        }
                    }
                    else
                    {
                        // import data into scene
                        ProcessScene(fbxScene, unitySelectionSet);
                    }

                    // cleanup
                    fbxScene.Destroy();
                    fbxImporter.Destroy();

                    return(status == true ? NumNodes : 0);
                }
            }
Exemple #22
0
        private void AddParsedFbx()
        {
            var importer = new FbxImporter();

            importer.Load(_scene, "C:\\test.fbx");
        }
Exemple #23
0
            //---------------------------------------------------------------------------------------------------------
            /// <summary>
            /// Открытие файла
            /// </summary>
            //---------------------------------------------------------------------------------------------------------
            public void OpenFile(TreeView model_tree_view)
            {
                if (mIsLoading)
                {
                    return;
                }
                String path = XFileDialog.OpenUseExtension("Открыть 3D файл", OpenFileFilter);

                if (path == null)
                {
                    return;
                }
                StopAnimation();



                // Create the FBX SDK manager
                FbxManager lSdkManager = FbxManager.Create();

                // Create an IOSettings object.
                FbxIOSettings ios = FbxIOSettings.Create(lSdkManager, Globals.IOSROOT);

                lSdkManager.SetIOSettings(ios);

                // ... Configure the FbxIOSettings object ...

                // Create an importer.
                FbxImporter lImporter = FbxImporter.Create(lSdkManager, "");

                // Initialize the importer.
                bool lImportStatus = lImporter.Initialize(path, -1, lSdkManager.GetIOSettings());



                mIsLoading = true;
                Task.Run(() =>
                {
                    var loader = new Importer();

                    //loader.Configuration.AssimpPostProcessSteps =
                    //loader.Configuration.AssimpPostProcessSteps |
                    //Assimp.PostProcessSteps.OptimizeGraph;

                    return(loader.Load(path));
                }).ContinueWith((result) =>
                {
                    mIsLoading = false;
                    if (result.IsCompleted)
                    {
                        HelixToolkitScene helix_toolkit_scene = result.Result;
                        if (helix_toolkit_scene == null)
                        {
                            return;
                        }
                        mSceneRoot       = helix_toolkit_scene.Root;
                        mSceneAnimations = helix_toolkit_scene.Animations;
                        Animations.Clear();
                        GroupModel.Clear();
                        if (helix_toolkit_scene != null)
                        {
                            if (helix_toolkit_scene.Root != null)
                            {
                                foreach (var node in helix_toolkit_scene.Root.Traverse())
                                {
                                    if (node is MaterialGeometryNode m)
                                    {
                                        if (m.Material is PBRMaterialCore pbr)
                                        {
                                            pbr.RenderEnvironmentMap = RenderEnvironmentMap;
                                        }
                                        else if (m.Material is PhongMaterialCore phong)
                                        {
                                            phong.RenderEnvironmentMap = RenderEnvironmentMap;
                                        }
                                    }
                                }
                            }

                            GroupModel.AddNode(helix_toolkit_scene.Root);
                            if (helix_toolkit_scene.HasAnimation)
                            {
                                var dict = helix_toolkit_scene.Animations.CreateAnimationUpdaters();
                                foreach (var animation in dict.Values)
                                {
                                    Animations.Add(animation);
                                }
                            }
                            foreach (var node in helix_toolkit_scene.Root.Traverse())
                            {
                                //node.Tag = new AttachedNodeViewModel(node);
                            }
                        }

                        Boolean is_y_up            = threeViewer.IsModelUpDirectionY();
                        checkBoxYUpModel.IsChecked = is_y_up;
                        if (is_y_up)
                        {
                        }

                        model_tree_view.ItemsSource = mSceneRoot.Items;
                        //Scene = new CScene3D()
                    }
                    else if (result.IsFaulted && result.Exception != null)
                    {
                        MessageBox.Show(result.Exception.Message);
                    }
                }, TaskScheduler.FromCurrentSynchronizationContext());
            }
Exemple #24
0
        static bool LoadFBX(ImportContext context, string virtualFileName, out List <MeshData> geometries)
        {
            geometries = null;

            var settings = context.settings;

            ImportFBX.LoadNativeLibrary();

            FbxManager    manager  = null;
            FbxIOSettings setting  = null;
            FbxImporter   importer = null;
            FbxScene      scene    = null;

            try
            {
                manager = FbxManager.Create();
                setting = FbxIOSettings.Create(manager, "IOSRoot");
                manager.SetIOSettings(setting);

                importer = FbxImporter.Create(manager, "");
                var realFileName = VirtualPathUtility.GetRealPathByVirtual(virtualFileName);
                //VirtualFileStream stream = null;
                //ToDo : FromStream
                bool status;
                if (!string.IsNullOrEmpty(realFileName) && File.Exists(realFileName))
                {
                    status = importer.Initialize(realFileName, -1, setting);
                }
                else
                {
                    return(false);
                    //throw new NotImplementedException();
                    //ToDo : ....
                    //stream = VirtualFile.Open( settings.virtualFileName );
                    //FbxStream fbxStream = null;
                    //SWIGTYPE_p_void streamData = null;

                    //status = impoter.Initialize( fbxStream, streamData, -1, setting );
                }

                if (!status)
                {
                    return(false);
                }

                scene  = FbxScene.Create(manager, "scene1");
                status = importer.Import(scene);
                if (!status)
                {
                    return(false);
                }

                //convert axis
                if (context.settings.component.ForceFrontXAxis)
                {
                    //Через такой конструктор не получится создать такие же оси как EPreDefinedAxisSystem.eMax - Front Axis имеет обратное направление, а направление задать нельзя.
                    //new FbxAxisSystem( FbxAxisSystem.EUpVector.eZAxis, FbxAxisSystem.EFrontVector.eParityOdd, FbxAxisSystem.ECoordSystem.eRightHanded );
                    //FromFBX Docs:
                    //The enum values ParityEven and ParityOdd denote the first one and the second one of the remain two axes in addition to the up axis.
                    //For example if the up axis is X, the remain two axes will be Y And Z, so the ParityEven is Y, and the ParityOdd is Z ;

                    //We desire to convert the scene from Y-Up to Z-Up. Using the predefined axis system: Max (UpVector = +Z, FrontVector = -Y, CoordSystem = +X (RightHanded))
                    var maxAxisSystem = new FbxAxisSystem(FbxAxisSystem.EPreDefinedAxisSystem.eMax);

                    if (!scene.GetGlobalSettings().GetAxisSystem().eq(maxAxisSystem))
                    {
                        maxAxisSystem.ConvertScene(scene);                           //No conversion will take place if the scene current axis system is equal to the new one. So condition can be removed.
                    }
                }

                //convert units
                if (!scene.GetGlobalSettings().GetSystemUnit().eq(FbxSystemUnit.m))
                {
                    FbxSystemUnit.m.ConvertScene(scene);
                }

                var additionalTransform = new Matrix4(settings.component.Rotation.Value.ToMatrix3() * Matrix3.FromScale(settings.component.Scale), settings.component.Position);

                var options = new ImportOptions
                {
                    NormalsOptions         = NormalsAndTangentsLoadOptions.FromFileIfPresentOrCalculate,
                    TangentsOptions        = NormalsAndTangentsLoadOptions.FromFileIfPresentOrCalculate,
                    ImportPostProcessFlags = ImportPostProcessFlags.FixInfacingNormals
                };
                options.ImportPostProcessFlags |= ImportPostProcessFlags.SmoothNormals | ImportPostProcessFlags.SmoothTangents;
                if (context.settings.component.FlipUVs)
                {
                    options.ImportPostProcessFlags |= ImportPostProcessFlags.FlipUVs;
                }
                //if( importContext.settings.component.MergeMeshGeometries )
                //	options.ImportPostProcessFlags |= ImportPostProcessFlags.MergeGeometriesByMaterials;

                var sceneLoader = new SceneLoader();
                sceneLoader.Load(scene, manager, options, additionalTransform);

                geometries = sceneLoader.Geometries;
                //foreach( var geometry in sceneLoader.Geometries )
                //	ImportGeometry( context, destinationMesh, geometry );

                ////check is it a billboard
                //MeshGetIsBillboard( context, destinationMesh );

                //stream?.Dispose();
            }
            finally
            {
                //Особенности удаления.
                //Создается через функцию: impoter = FbxImporter.Create(manager, "");
                //В таких случаях(создание не через конструктор, а возврат указателя из функции) SWIG задает флажок что объект не владеет ссылкой, поэтому Dispose ничего не делает.
                //Хотя в SWIG можно задать в конфигурации: %newobject FbxImporter::Create; Тогда объект будет владеть ссылкой. Но все равно в С++ наследники FbxObject не имеют public destructor
                //поэтому в Dispose вставлен: throw new MethodAccessException("C++ destructor does not have public access"). Поэтому удалять только через Destroy.

                try { scene?.Destroy(); } catch { }
                try { importer?.Destroy(); } catch { }
                try { setting?.Destroy(); } catch { }
                try { manager?.Destroy(); } catch { }
            }

            return(true);
        }
Exemple #25
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FbxImporter obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
        public void Dude()
        {
            var context  = new TestImporterContext("TestObj", "TestBin");
            var importer = new FbxImporter();

            var nodeContent = importer.Import(DudeFbx, context);

            Assert.AreEqual("RootNode", nodeContent.Name);
            Assert.AreEqual(null, nodeContent.Parent);

            Assert.AreEqual(0, nodeContent.Animations.Count);

            Assert.AreEqual(Matrix.Identity, nodeContent.Transform);
            Assert.AreEqual(Matrix.Identity, nodeContent.AbsoluteTransform);

            Assert.NotNull(nodeContent.Identity);
            Assert.NotNull(nodeContent.Identity.SourceFilename);
            Assert.IsNull(nodeContent.Identity.FragmentIdentifier);
            Assert.AreEqual("FbxImporter", nodeContent.Identity.SourceTool);

            Assert.AreEqual(2, nodeContent.Children.Count);


            // MeshContent
            Assert.IsInstanceOf <MeshContent>(nodeContent.Children[0]);
            var meshContent = nodeContent.Children[0] as MeshContent;

            Assert.AreEqual("him", meshContent.Name);
            Assert.AreEqual(nodeContent, meshContent.Parent);
            Assert.AreEqual(0, meshContent.Children.Count);
            Assert.AreEqual(0, meshContent.Animations.Count);
            Assert.AreEqual(0, meshContent.OpaqueData.Count);
            Assert.AreEqual(Matrix.Identity, meshContent.AbsoluteTransform);
            Assert.AreEqual(Matrix.Identity, meshContent.Transform);
            Assert.AreEqual(5, meshContent.Geometry.Count);

            // TODO: MG returns more positions than XNA.
            //
            //  - Is this a bug in our FbxImporer?
            //  - A limitation of AssImp?
            //  - Conversion bug from FBX 6.1.0 to FBX 7.1.0?
            //  - Are we missing some welding of verts?
            //
#if XNA
            Assert.AreEqual(11433, meshContent.Positions.Count);
#else
            Assert.AreEqual(13126, meshContent.Positions.Count);
#endif


            // MaterialContent
            var materials = new Dictionary <string, BasicMaterialContent>();
            foreach (var g in meshContent.Geometry)
            {
                Assert.IsNull(g.Name);
                //Assert.IsNull(g.Identity);
                Assert.AreEqual(meshContent, g.Parent);
                Assert.AreEqual(0, g.OpaqueData.Count);
                Assert.Greater(g.Indices.Count, 0);
                Assert.Greater(g.Vertices.VertexCount, 0);
                Assert.Greater(g.Vertices.Positions.Count, 0);
                Assert.Greater(g.Vertices.PositionIndices.Count, 0);

                Assert.NotNull(g.Material);
                Assert.IsInstanceOf <BasicMaterialContent>(g.Material);
                Assert.NotNull(g.Material.Identity);
                Assert.NotNull(g.Material.Identity.SourceFilename);
                Assert.IsNull(g.Material.Identity.FragmentIdentifier);
                Assert.AreEqual("FbxImporter", g.Material.Identity.SourceTool);
                Assert.NotNull(g.Material.Name);
                Assert.IsFalse(materials.ContainsKey(g.Material.Name));
                materials.Add(g.Material.Name, g.Material as BasicMaterialContent);
            }

            Assert.AreEqual(5, materials.Count);

            foreach (var m in materials.Values)
            {
                Assert.AreEqual(1, m.Alpha);
                Assert.AreEqual(new Vector3(0.0f, 0.0f, 0.0f), m.EmissiveColor);
                Assert.AreEqual(new Vector3(0.5f, 0.5f, 0.5f), m.SpecularColor);
                Assert.AreEqual(null, m.VertexColorEnabled);
                Assert.AreEqual(3, m.Textures.Count);
                Assert.AreEqual(m.Texture, m.Textures["Texture"]);
                Assert.IsNull(m.Textures["Texture"].Name);
                Assert.IsNull(m.Textures["Specular"].Name);
                Assert.IsNull(m.Textures["Bump"].Name);
                Assert.AreEqual("TextureCoordinate0", m.Textures["Texture"].OpaqueData["TextureCoordinate"]);
                Assert.AreEqual("TextureCoordinate0", m.Textures["Specular"].OpaqueData["TextureCoordinate"]);
                Assert.AreEqual("TextureCoordinate0", m.Textures["Bump"].OpaqueData["TextureCoordinate"]);
            }

            Assert.AreEqual(new Vector3(1.0f, 1.0f, 1.0f), materials["character_anim:headM"].DiffuseColor);
            Assert.AreEqual(new Vector3(1.0f, 1.0f, 1.0f), materials["character_anim:jacketM"].DiffuseColor);
            Assert.AreEqual(new Vector3(0.8f, 0.8f, 0.8f), materials["character_anim:pantsM"].DiffuseColor);
            Assert.AreEqual(new Vector3(1.0f, 1.0f, 1.0f), materials["character_anim:upBodyM"].DiffuseColor);
            Assert.AreEqual(new Vector3(1.0f, 1.0f, 1.0f), materials["character_anim:eyeBallM"].DiffuseColor);
            Assert.AreEqual(1.24573088f, materials["character_anim:headM"].SpecularPower, 0.00001f);
            Assert.AreEqual(1.24573088f, materials["character_anim:jacketM"].SpecularPower, 0.00001f);
            Assert.AreEqual(1.24573088f, materials["character_anim:pantsM"].SpecularPower, 0.00001f);
            Assert.AreEqual(1.19371974f, materials["character_anim:upBodyM"].SpecularPower, 0.00001f);
            Assert.AreEqual(65.986f, materials["character_anim:eyeBallM"].SpecularPower, 0.00001f);

            Paths.AreEqual(@"Assets/Models/Dude/head.tga", materials["character_anim:headM"].Textures["Texture"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/headS.tga", materials["character_anim:headM"].Textures["Specular"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/headN.tga", materials["character_anim:headM"].Textures["Bump"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/jacket.tga", materials["character_anim:jacketM"].Textures["Texture"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/jacketS.tga", materials["character_anim:jacketM"].Textures["Specular"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/jacketN.tga", materials["character_anim:jacketM"].Textures["Bump"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/pants.tga", materials["character_anim:pantsM"].Textures["Texture"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/pantsS.tga", materials["character_anim:pantsM"].Textures["Specular"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/pantsN.tga", materials["character_anim:pantsM"].Textures["Bump"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upBodyC.tga", materials["character_anim:upBodyM"].Textures["Texture"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upBodyS.tga", materials["character_anim:upBodyM"].Textures["Specular"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upbodyN.tga", materials["character_anim:upBodyM"].Textures["Bump"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upBodyC.tga", materials["character_anim:eyeBallM"].Textures["Texture"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upBodyS.tga", materials["character_anim:eyeBallM"].Textures["Specular"].Filename);
            Paths.AreEqual(@"Assets/Models/Dude/upbodyN.tga", materials["character_anim:eyeBallM"].Textures["Bump"].Filename);

            // BoneContent
            Assert.IsInstanceOf <BoneContent>(nodeContent.Children[1]);
            var bonehContent = nodeContent.Children[1] as BoneContent;
            Assert.AreEqual("Root", bonehContent.Name);
            Assert.AreEqual(1, bonehContent.Children.Count);

            // TODO: MG doesn't return this.
            //
            //  - Is this a bug in our FbxImporer?
            //  - A limitation of AssImp?
            //  - Conversion bug from FBX 6.1.0 to FBX 7.1.0?
            //  - What is "liw" and why is it false?
            //  - Do we care about this incompatibility?
            //
#if XNA
            Assert.AreEqual(1, bonehContent.OpaqueData.Count);
            Assert.AreEqual(false, bonehContent.OpaqueData["liw"]);
#endif


            // AnimationContent
            Assert.AreEqual(1, bonehContent.Animations.Count);
            Assert.IsTrue(bonehContent.Animations.ContainsKey("Take 001"));
            var animationContent = bonehContent.Animations["Take 001"];
            Assert.AreEqual("Take 001", animationContent.Name);
            Assert.AreEqual(0, animationContent.OpaqueData.Count);

            // TODO: A few channels are missing from XNA:
            //
            //  - Is this a bug in our FbxImporer?
            //  - A limitation of AssImp?
            //  - Conversion bug from FBX 6.1.0 to FBX 7.1.0?
            //  - Do these missing channels matter?
            //
#if XNA
            Assert.AreEqual(58, animationContent.Channels.Count);
#endif
            var channels = new[] {
                "Pelvis", "Spine1", "Spine2", "Spine3", "Neck", "Head", "L_eye_joint1", "R_eye_joint",
                "L_eyeBall_joint2", "R_eyeBall_joint", "L_UpperArm", "L_Forearm", "L_Hand", "L_Thumb1",
                "L_Thumb2", "L_Thumb3", "L_Index1", "L_Index2", "L_Index3", "L_Middle1", "L_Middle2", "L_Middle3",
                "L_Ring1", "L_Ring2", "L_Ring3", "L_Pinky1", "L_Pinky2", "L_Pinky3", "R_UpperArm", "R_Forearm",
                "R_Hand", "R_Thumb1", "R_Thumb2", "R_Thumb3", "R_Index1", "R_Index2", "R_Index3", "R_Middle1", "R_Middle2",
                "R_Middle3", "R_Ring1", "R_Ring2", "R_Ring3", "R_Pinky1", "R_Pinky2", "R_Pinky3", "L_Thigh1", "L_Knee2",
                "L_Ankle1", "L_Ball", "R_Thigh", "R_Knee", "R_Ankle", "R_Ball",

                // TODO: These channels are missing in MG!
#if XNA
                "Root", "Spine", "L_Clavicle", "R_Clavicle",
#endif
            };
            foreach (var name in channels)
            {
                Assert.IsTrue(animationContent.Channels.ContainsKey(name), "Channels.ContainsKey failed: " + name);
            }
            foreach (var c in animationContent.Channels.Values)
            {
                Assert.Greater(c.Count, 0);
            }

            // I think in this case the old XNA FBX importer was bugged and
            // returned a bigger animation duration that is correct.  Looking
            // at the content of the FBX ascii i can see the math is:
            //
            //  (57732697500 - 1924423250) / 46186158000 = 1.208 seconds
            //
            // Which is the correct result and what our FBX importer returns.
            // I highly suspect that XNA was wrong.
            //
            // https://github.com/assimp/assimp/issues/1720
            //
#if XNA
            Assert.AreEqual(12670000, animationContent.Duration.Ticks);
#else
            Assert.AreEqual(12080000, animationContent.Duration.Ticks);
#endif

            // TODO: XNA assigns the identity to null on all NodeContent
            // other than the one returned from the importer.
            //
            //  - Is this something we should fix?
            //
#if XNA
            Assert.IsNull(meshContent.Identity);
            Assert.IsNull(bonehContent.Identity);
            Assert.IsNull(animationContent.Identity);
#endif
        }