Ejemplo n.º 1
0
    /// <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);
        }
    }
Ejemplo n.º 2
0
        static void ImportScene(ImportContext context)
        {
            var settings = context.settings;
            var scene    = context.scene;

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

            //get materials data
            var materialsData = GetMaterialsData(context);

            //create Materials group
            context.materialsGroup = context.settings.component.GetComponent("Materials");
            if (context.materialsGroup == null /*&& materialsData.Count != 0*/ && settings.updateMaterials)
            {
                context.materialsGroup      = context.settings.component.CreateComponent <Component>();
                context.materialsGroup.Name = "Materials";
            }

            //create materials
            foreach (var data in materialsData)
            {
                Component_Material material = null;
                if (context.settings.updateMaterials)
                {
                    material = CreateMaterial(context.materialsGroup, data);
                }
                else
                {
                    if (context.materialsGroup != null)
                    {
                        material = context.materialsGroup.GetComponent(data.Name) as Component_Material;
                    }
                }
                if (material != null)
                {
                    context.materialByIndex.Add(data.Index, material);
                }
            }

            //-------------------------

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

            var sceneLoader = new SceneLoader();

            var mode = settings.component.Mode.Value;

            if (mode == Component_Import3D.ModeEnum.Auto)
            {
                mode = Component_Import3D.ModeEnum.OneMesh;
            }

            //create one mesh (OneMesh mode)
            if (mode == Component_Import3D.ModeEnum.OneMesh && settings.updateMeshes)
            {
                sceneLoader.Load(scene, context.manager, options, additionalTransform);
                Component_Skeleton skeletonComponent = CreateSkeletonComponent(context, sceneLoader.Skeleton, out int[] newIndexFromOldIndex, out SkeletonBone[] oldBoneFromNewIndex, additionalTransform);
Ejemplo n.º 3
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);
        }