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