Exemplo n.º 1
0
        private void FBXButton_Click(object sender, EventArgs e)
        {
            Content.Content.Get().Changes.BlockingResMod(new ResAction(() =>
            {
                var interactive = AnimDisplay.Renderer;
                var ava         = (VMAvatar)interactive.TargetOBJ.BaseObject;

                var exp = new GLTFExporter();
                var scn = exp.SceneGroup(ava.Avatar.Bindings.Select(x => x.Mesh).ToList(),
                                         new List <Animation> {
                    ava.Animations[0].Anim
                },
                                         ava.Avatar.Bindings.Select(x => x.Texture?.Get(GameFacade.GraphicsDevice)).ToList(),
                                         ava.Avatar.BaseSkeleton);

                scn.SaveGLTF("C:/Users/Rhys/Desktop/fsoexport/testsim.gltf");

                /*
                 * var scn = MeshExporter.SceneGroup(
                 *  ava.Avatar.Bindings.Select(x => x.Mesh).ToList(),
                 *  new List<Animation> { ava.Animations[0].Anim },
                 *  ava.Avatar.Bindings.Select(x => x.Texture?.Get(GameFacade.GraphicsDevice)).ToList(),
                 *  ava.Avatar.BaseSkeleton);
                 *
                 * MeshExporter.ExportToFBX(scn, @"C:\Users\Rhys\Desktop\fsoexport\test.dae");
                 */
            }));
        }
Exemplo n.º 2
0
    // Use this for initialization
    void Awake()
    {
        var exporter = new GLTFExporter(new [] { transform });
        var appPath  = Application.dataPath;
        var wwwPath  = appPath.Substring(0, appPath.LastIndexOf("Assets")) + "www";

        exporter.SaveGLTFandBin(Path.Combine(wwwPath, "TestScene"), "TestScene");
    }
Exemplo n.º 3
0
    static void ExportScene()
    {
        var scene       = SceneManager.GetActiveScene();
        var gameObjects = scene.GetRootGameObjects();
        var transforms  = Array.ConvertAll(gameObjects, gameObject => gameObject.transform);

        var exporter = new GLTFExporter(transforms);
        var path     = EditorUtility.OpenFolderPanel("glTF Export Path", "", "");

        exporter.SaveGLTFandBin(path, scene.name);
    }
    void Start()
    {
        var exporter = new GLTFExporter(new [] { transform });
        var root     = exporter.GetRoot();

        var scene = root.GetDefaultScene();

        IntegrationTest.Assert(scene.Name == gameObject.name);



        IntegrationTest.Assert(root.Materials[0].AlphaMode == AlphaMode.BLEND);

        IntegrationTest.Pass();
    }
Exemplo n.º 5
0
        private void ExportGLTFButton_Click(object sender, EventArgs e)
        {
            var dialog = new SaveFileDialog();

            dialog.Title        = "Save the scene as a glTF/glb file.";
            dialog.Filter       = "glTF Binary Package|*.glb|glTF Separate|*.gltf";
            dialog.DefaultExt   = "glb";
            dialog.AddExtension = true;
            FormsUtils.StaExecute(() =>
            {
                dialog.ShowDialog();
            });

            Content.Content.Get().Changes.BlockingResMod(new ResAction(() =>
            {
                var interactive = Animator.Renderer;
                var ava         = (VMAvatar)interactive.TargetOBJ.BaseObject;

                var exp             = new GLTFExporter();
                ava.Avatar.Skeleton = ava.Avatar.BaseSkeleton.Clone();
                ava.Avatar.ReloadSkeleton();
                var scn = exp.SceneGroup(ava.Avatar.Bindings.Select(x => x.Mesh).ToList(),
                                         SceneAnimations.Select(x => x.Anim).ToList(),
                                         ava.Avatar.Bindings.Select(x => x.Texture?.Get(GameFacade.GraphicsDevice)).ToList(),
                                         ava.Avatar.BaseSkeleton);

                if (dialog.FileName == "")
                {
                    return;
                }
                if (dialog.FileName.EndsWith(".gltf"))
                {
                    scn.SaveGLTF(dialog.FileName);
                }
                else
                {
                    scn.SaveGLB(dialog.FileName);
                }
            }));

            SetImportMode(false, Path.GetFileName(dialog.FileName));
        }
Exemplo n.º 6
0
    static void ExportSelected()
    {
        string name;

        if (Selection.transforms.Length > 1)
        {
            name = SceneManager.GetActiveScene().name;
        }
        else if (Selection.transforms.Length == 1)
        {
            name = Selection.activeGameObject.name;
        }
        else
        {
            throw new Exception("No objects selected, cannot export.");
        }

        var exporter = new GLTFExporter(Selection.transforms);
        var path     = EditorUtility.OpenFolderPanel("glTF Export Path", "", "");

        exporter.SaveGLTFandBin(path, name);
    }
Exemplo n.º 7
0
    public MaxGLTFMaterialExporter(ExportParameters exportParameters, GLTFExporter gltfExporter, ILoggingProvider logger)
    {
        // Instantiate custom material exporters
        this.materialExporters = new Dictionary <ClassIDWrapper, IMaxMaterialExporter>();
        foreach (Type type in Tools.GetAllLoadableTypes())
        {
            if (type.IsAbstract || type.IsInterface || !typeof(IMaxMaterialExporter).IsAssignableFrom(type))
            {
                continue;
            }

            IMaxMaterialExporter exporter = Activator.CreateInstance(type) as IMaxMaterialExporter;

            if (exporter == null)
            {
                logger.RaiseWarning("Creating exporter instance failed: " + type.Name, 1);
            }

            materialExporters.Add(exporter.MaterialClassID, exporter);
        }
        this.exportParameters = exportParameters;
        this.gltfExporter     = gltfExporter;
    }
Exemplo n.º 8
0
        public void Export(ExportParameters exportParameters)
        {
            this.exportParameters = exportParameters;
            IINode exportNode = null;

            if (exportParameters is MaxExportParameters)
            {
                MaxExportParameters maxExporterParameters = (exportParameters as MaxExportParameters);
                exportNode = maxExporterParameters.exportNode;
                if (maxExporterParameters.flattenScene)
                {
                    FlattenHierarchy(exportNode);
                }
                if (maxExporterParameters.mergeInheritedContainers)
                {
                    ExportClosedContainers();
                }
            }



            this.scaleFactor = Tools.GetScaleFactorToMeters();

            var scaleFactorFloat = 1.0f;
            // Check input text is valid
            float scaleFactor = exportParameters.scaleFactor;

            long quality = exportParameters.txtQuality;

            try
            {
                if (quality < 0 || quality > 100)
                {
                    throw new Exception();
                }
            }
            catch
            {
                RaiseError("Quality is not a valid number. It should be an integer between 0 and 100.");
                RaiseError("This parameter sets the quality of jpg compression.");
                return;
            }



            var gameConversionManger = Loader.Global.ConversionManager;

            gameConversionManger.CoordSystem = Autodesk.Max.IGameConversionManager.CoordSystem.D3d;

            var gameScene = Loader.Global.IGameInterface;

            if (exportNode == null || exportNode.IsRootNode)
            {
                gameScene.InitialiseIGame(false);
            }
            else
            {
                gameScene.InitialiseIGame(exportNode, true);
            }

            gameScene.SetStaticFrame(0);

            MaxSceneFileName = gameScene.SceneFileName;

            IsCancelled = false;

            string fileExportString = exportNode != null
                ? $"{exportNode.NodeName} | {exportParameters.outputPath}"
                : exportParameters.outputPath;

            RaiseMessage($"Exportation started: {fileExportString}", Color.Blue);
            ReportProgressChanged(0);

            string tempOutputDirectory  = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            string outputDirectory      = Path.GetDirectoryName(exportParameters.outputPath);
            string folderOuputDirectory = exportParameters.textureFolder;
            string outputFileName       = Path.GetFileName(exportParameters.outputPath);

            // Check directory exists
            if (!Directory.Exists(outputDirectory))
            {
                RaiseError("Exportation stopped: Output folder does not exist");
                ReportProgressChanged(100);
                return;
            }
            Directory.CreateDirectory(tempOutputDirectory);

            var outputBabylonDirectory = tempOutputDirectory;

            // Force output file extension to be babylon
            outputFileName = Path.ChangeExtension(outputFileName, "babylon");

            var babylonScene = new BabylonScene(outputBabylonDirectory);

            var rawScene = Loader.Core.RootNode;

            var watch = new Stopwatch();

            watch.Start();

            string outputFormat = exportParameters.outputFormat;

            isBabylonExported = outputFormat == "babylon" || outputFormat == "binary babylon";
            isGltfExported    = outputFormat == "gltf" || outputFormat == "glb";

            // Get scene parameters
            optimizeAnimations = !Loader.Core.RootNode.GetBoolProperty("babylonjs_donotoptimizeanimations");
            exportNonAnimated  = Loader.Core.RootNode.GetBoolProperty("babylonjs_animgroup_exportnonanimated");

            // Save scene
            if (exportParameters.autoSaveSceneFile)
            {
                RaiseMessage("Saving 3ds max file");
                var forceSave = Loader.Core.FileSave;

                callerForm?.BringToFront();
            }

            // Producer
            babylonScene.producer = new BabylonProducer
            {
                name = "3dsmax",
#if MAX2019
                version = "2019",
#elif MAX2018
                version = "2018",
#elif MAX2017
                version = "2017",
#else
                version = Loader.Core.ProductVersion.ToString(),
#endif
                exporter_version = exporterVersion,
                file             = outputFileName
            };

            // Global
            babylonScene.autoClear    = true;
            babylonScene.clearColor   = Loader.Core.GetBackGround(0, Tools.Forever).ToArray();
            babylonScene.ambientColor = Loader.Core.GetAmbient(0, Tools.Forever).ToArray();

            babylonScene.TimelineStartFrame      = Loader.Core.AnimRange.Start / Loader.Global.TicksPerFrame;
            babylonScene.TimelineEndFrame        = Loader.Core.AnimRange.End / Loader.Global.TicksPerFrame;
            babylonScene.TimelineFramesPerSecond = MaxSceneTicksPerSecond / Loader.Global.TicksPerFrame;

            babylonScene.gravity             = rawScene.GetVector3Property("babylonjs_gravity");
            ExportQuaternionsInsteadOfEulers = rawScene.GetBoolProperty("babylonjs_exportquaternions", 1);
            if (string.IsNullOrEmpty(exportParameters.pbrEnvironment) && Loader.Core.UseEnvironmentMap && Loader.Core.EnvironmentMap != null)
            {
                // Environment texture
                var environmentMap = Loader.Core.EnvironmentMap;
                // Copy image file to output if necessary
                var babylonTexture = ExportEnvironmnentTexture(environmentMap, babylonScene);
                if (babylonTexture != null)
                {
                    babylonScene.environmentTexture = babylonTexture.name;

                    // Skybox
                    babylonScene.createDefaultSkybox = rawScene.GetBoolProperty("babylonjs_createDefaultSkybox");
                    babylonScene.skyboxBlurLevel     = rawScene.GetFloatProperty("babylonjs_skyboxBlurLevel");
                }
            }
            else if (!string.IsNullOrEmpty(exportParameters.pbrEnvironment))
            {
                babylonScene.createDefaultSkybox = rawScene.GetBoolProperty("babylonjs_createDefaultSkybox");
                babylonScene.skyboxBlurLevel     = rawScene.GetFloatProperty("babylonjs_skyboxBlurLevel");
            }

            // Instantiate custom material exporters
            materialExporters = new Dictionary <ClassIDWrapper, IMaxMaterialExporter>();
            foreach (Type type in Tools.GetAllLoadableTypes())
            {
                if (type.IsAbstract || type.IsInterface || !typeof(IMaxMaterialExporter).IsAssignableFrom(type))
                {
                    continue;
                }

                IMaxMaterialExporter exporter = Activator.CreateInstance(type) as IMaxMaterialExporter;

                if (exporter == null)
                {
                    RaiseWarning("Creating exporter instance failed: " + type.Name, 1);
                }

                materialExporters.Add(exporter.MaterialClassID, exporter);
            }

            // Sounds
            var soundName = rawScene.GetStringProperty("babylonjs_sound_filename", "");

            if (!string.IsNullOrEmpty(soundName))
            {
                var filename = Path.GetFileName(soundName);

                var globalSound = new BabylonSound
                {
                    autoplay = rawScene.GetBoolProperty("babylonjs_sound_autoplay", 1),
                    loop     = rawScene.GetBoolProperty("babylonjs_sound_loop", 1),
                    name     = filename
                };

                babylonScene.SoundsList.Add(globalSound);

                if (isBabylonExported)
                {
                    try
                    {
                        File.Copy(soundName, Path.Combine(babylonScene.OutputPath, filename), true);
                    }
                    catch
                    {
                    }
                }
            }

            // Root nodes
            RaiseMessage("Exporting nodes");
            HashSet <IIGameNode> maxRootNodes = getRootNodes(gameScene);
            var progressionStep = 80.0f / maxRootNodes.Count;
            var progression     = 10.0f;
            ReportProgressChanged((int)progression);
            referencedMaterials.Clear();
            Tools.guids.Clear();
            // Reseting is optionnal. It makes each morph target manager export starts from id = 0.
            BabylonMorphTargetManager.Reset();
            foreach (var maxRootNode in maxRootNodes)
            {
                BabylonNode node = exportNodeRec(maxRootNode, babylonScene, gameScene);

                // if we're exporting from a specific node, reset the pivot to {0,0,0}
                if (node != null && exportNode != null && !exportNode.IsRootNode)
                {
                    SetNodePosition(ref node, ref babylonScene, new float[] { 0, 0, 0 });
                }

                progression += progressionStep;
                ReportProgressChanged((int)progression);
                CheckCancelled();
            }
            ;
            RaiseMessage(string.Format("Total meshes: {0}", babylonScene.MeshesList.Count), Color.Gray, 1);


            // In 3DS Max the default camera look down (in the -z direction for the 3DS Max reference (+y for babylon))
            // In Babylon the default camera look to the horizon (in the +z direction for the babylon reference)
            // In glTF the default camera look to the horizon (in the +Z direction for glTF reference)
            RaiseMessage("Update camera rotation and position", 1);
            for (int index = 0; index < babylonScene.CamerasList.Count; index++)
            {
                BabylonCamera camera = babylonScene.CamerasList[index];
                FixCamera(ref camera, ref babylonScene);
            }

            // Light for glTF
            if (isGltfExported)
            {
                RaiseMessage("Update light rotation for glTF export", 1);
                for (int index = 0; index < babylonScene.LightsList.Count; index++)
                {
                    BabylonNode light = babylonScene.LightsList[index];
                    FixNodeRotation(ref light, ref babylonScene, -Math.PI / 2);
                }
            }

            // Main camera
            BabylonCamera babylonMainCamera   = null;
            ICameraObject maxMainCameraObject = null;
            if (babylonMainCamera == null && babylonScene.CamerasList.Count > 0)
            {
                // Set first camera as main one
                babylonMainCamera           = babylonScene.CamerasList[0];
                babylonScene.activeCameraID = babylonMainCamera.id;
                RaiseMessage("Active camera set to " + babylonMainCamera.name, Color.Green, 1, true);

                // Retreive camera node with same GUID
                var maxCameraNodesAsTab = gameScene.GetIGameNodeByType(Autodesk.Max.IGameObject.ObjectTypes.Camera);
                var maxCameraNodes      = TabToList(maxCameraNodesAsTab);
                var maxMainCameraNode   = maxCameraNodes.Find(_camera => _camera.MaxNode.GetGuid().ToString() == babylonMainCamera.id);
                maxMainCameraObject = (maxMainCameraNode.MaxNode.ObjectRef as ICameraObject);
            }

            if (babylonMainCamera == null)
            {
                RaiseWarning("No camera defined", 1);
            }
            else
            {
                RaiseMessage(string.Format("Total cameras: {0}", babylonScene.CamerasList.Count), Color.Gray, 1);
            }

            // Default light
            bool addDefaultLight = rawScene.GetBoolProperty("babylonjs_addDefaultLight", 1);
            if (!exportParameters.pbrNoLight && addDefaultLight && babylonScene.LightsList.Count == 0)
            {
                RaiseWarning("No light defined", 1);
                RaiseWarning("A default hemispheric light was added for your convenience", 1);
                ExportDefaultLight(babylonScene);
            }
            else
            {
                RaiseMessage(string.Format("Total lights: {0}", babylonScene.LightsList.Count), Color.Gray, 1);
            }

            if (scaleFactorFloat != 1.0f)
            {
                RaiseMessage("A root node is added for scaling", 1);

                // Create root node for scaling
                BabylonMesh rootNode = new BabylonMesh {
                    name = "root", id = Guid.NewGuid().ToString()
                };
                rootNode.isDummy = true;
                float rootNodeScale = scaleFactorFloat;
                rootNode.scaling = new float[3] {
                    rootNodeScale, rootNodeScale, rootNodeScale
                };

                if (ExportQuaternionsInsteadOfEulers)
                {
                    rootNode.rotationQuaternion = new float[] { 0, 0, 0, 1 };
                }
                else
                {
                    rootNode.rotation = new float[] { 0, 0, 0 };
                }

                // Update all top nodes
                var babylonNodes = new List <BabylonNode>();
                babylonNodes.AddRange(babylonScene.MeshesList);
                babylonNodes.AddRange(babylonScene.CamerasList);
                babylonNodes.AddRange(babylonScene.LightsList);
                foreach (BabylonNode babylonNode in babylonNodes)
                {
                    if (babylonNode.parentId == null)
                    {
                        babylonNode.parentId = rootNode.id;
                    }
                }

                // Store root node
                babylonScene.MeshesList.Add(rootNode);
            }

            // Materials
            if (exportParameters.exportMaterials)
            {
                RaiseMessage("Exporting materials");
                var matsToExport = referencedMaterials.ToArray(); // Snapshot because multimaterials can export new materials
                foreach (var mat in matsToExport)
                {
                    ExportMaterial(mat, babylonScene);
                    CheckCancelled();
                }
                RaiseMessage(string.Format("Total: {0}", babylonScene.MaterialsList.Count + babylonScene.MultiMaterialsList.Count), Color.Gray, 1);
            }
            else
            {
                RaiseMessage("Skipping material export.");
            }

            // Fog
            for (var index = 0; index < Loader.Core.NumAtmospheric; index++)
            {
                var atmospheric = Loader.Core.GetAtmospheric(index);

                if (atmospheric.Active(0) && atmospheric.ClassName == "Fog")
                {
                    var fog = atmospheric as IStdFog;

                    RaiseMessage("Exporting fog");

                    if (fog != null)
                    {
                        babylonScene.fogColor = fog.GetColor(0).ToArray();
                        babylonScene.fogMode  = 3;
                    }
                    if (babylonMainCamera != null)
                    {
                        babylonScene.fogStart = maxMainCameraObject.GetEnvRange(0, 0, Tools.Forever);
                        babylonScene.fogEnd   = maxMainCameraObject.GetEnvRange(0, 1, Tools.Forever);
                    }
                }
            }

            // Skeletons
            if (skins.Count > 0)
            {
                RaiseMessage("Exporting skeletons");
                foreach (var skin in skins)
                {
                    ExportSkin(skin, babylonScene);
                }
            }

            // ----------------------------
            // ----- Animation groups -----
            // ----------------------------
            RaiseMessage("Export animation groups");
            // add animation groups to the scene
            babylonScene.animationGroups = ExportAnimationGroups(babylonScene);

            if (isBabylonExported)
            {
                // if we are exporting to .Babylon then remove then remove animations from nodes if there are animation groups.
                if (babylonScene.animationGroups.Count > 0)
                {
                    foreach (BabylonNode node in babylonScene.MeshesList)
                    {
                        node.animations = null;
                    }
                    foreach (BabylonNode node in babylonScene.LightsList)
                    {
                        node.animations = null;
                    }
                    foreach (BabylonNode node in babylonScene.CamerasList)
                    {
                        node.animations = null;
                    }
                    foreach (BabylonSkeleton skel in babylonScene.SkeletonsList)
                    {
                        foreach (BabylonBone bone in skel.bones)
                        {
                            bone.animation = null;
                        }
                    }
                }

                // setup a default skybox for the scene for .Babylon export.
                var sourcePath = exportParameters.pbrEnvironment;
                if (!string.IsNullOrEmpty(sourcePath))
                {
                    var fileName = Path.GetFileName(sourcePath);

                    // Allow only dds file format
                    if (!fileName.EndsWith(".dds"))
                    {
                        RaiseWarning("Failed to export defauenvironment texture: only .dds format is supported.");
                    }
                    else
                    {
                        RaiseMessage($"texture id = Max_Babylon_Default_Environment");
                        babylonScene.environmentTexture = fileName;

                        if (exportParameters.writeTextures)
                        {
                            try
                            {
                                var destPath = Path.Combine(babylonScene.OutputPath, fileName);
                                if (File.Exists(sourcePath) && sourcePath != destPath)
                                {
                                    File.Copy(sourcePath, destPath, true);
                                }
                            }
                            catch
                            {
                                // silently fails
                                RaiseMessage($"Fail to export the default env texture", 3);
                            }
                        }
                    }
                }
            }


            // Output
            babylonScene.Prepare(false, false);
            if (isBabylonExported)
            {
                RaiseMessage("Saving to output file");

                var outputFile = Path.Combine(outputBabylonDirectory, outputFileName);

                var jsonSerializer = JsonSerializer.Create(new JsonSerializerSettings());
                var sb             = new StringBuilder();
                var sw             = new StringWriter(sb, CultureInfo.InvariantCulture);
                using (var jsonWriter = new JsonTextWriterOptimized(sw))
                {
                    jsonWriter.Formatting = Formatting.None;
                    jsonSerializer.Serialize(jsonWriter, babylonScene);
                }
                File.WriteAllText(outputFile, sb.ToString());

                if (exportParameters.generateManifest)
                {
                    File.WriteAllText(outputFile + ".manifest",
                                      "{\r\n\"version\" : 1,\r\n\"enableSceneOffline\" : true,\r\n\"enableTexturesOffline\" : true\r\n}");
                }

                // Binary
                if (outputFormat == "binary babylon")
                {
                    RaiseMessage("Generating binary files");
                    BabylonFileConverter.BinaryConverter.Convert(outputFile, outputBabylonDirectory + "\\Binary",
                                                                 message => RaiseMessage(message, 1),
                                                                 error => RaiseError(error, 1));
                }
            }

            ReportProgressChanged(100);

            // Export glTF
            if (isGltfExported)
            {
                bool generateBinary = outputFormat == "glb";

                GLTFExporter gltfExporter = new GLTFExporter();
                exportParameters.customGLTFMaterialExporter = new MaxGLTFMaterialExporter(exportParameters, gltfExporter, this);
                gltfExporter.ExportGltf(this.exportParameters, babylonScene, tempOutputDirectory, outputFileName, generateBinary, this);
            }
            // Move files to output directory
            var filePaths = Directory.GetFiles(tempOutputDirectory);
            if (outputFormat == "binary babylon")
            {
                var tempBinaryOutputDirectory = Path.Combine(tempOutputDirectory, "Binary");
                var binaryFilePaths           = Directory.GetFiles(tempBinaryOutputDirectory);
                foreach (var filePath in binaryFilePaths)
                {
                    if (filePath.EndsWith(".binary.babylon"))
                    {
                        var file         = Path.GetFileName(filePath);
                        var tempFilePath = Path.Combine(tempBinaryOutputDirectory, file);
                        var outputFile   = Path.Combine(outputDirectory, file);

                        IUTF8Str maxNotification = GlobalInterface.Instance.UTF8Str.Create(outputFile);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, maxNotification);
                        moveFileToOutputDirectory(tempFilePath, outputFile, exportParameters);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PostExport, maxNotification);
                    }
                    else if (filePath.EndsWith(".babylonbinarymeshdata"))
                    {
                        var file         = Path.GetFileName(filePath);
                        var tempFilePath = Path.Combine(tempBinaryOutputDirectory, file);
                        var outputFile   = Path.Combine(outputDirectory, file);

                        IUTF8Str maxNotification = GlobalInterface.Instance.UTF8Str.Create(outputFile);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, maxNotification);
                        moveFileToOutputDirectory(tempFilePath, outputFile, exportParameters);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PostExport, maxNotification);
                    }
                }
            }
            if (outputFormat == "glb")
            {
                foreach (var file_path in filePaths)
                {
                    if (Path.GetExtension(file_path) == ".glb")
                    {
                        var file         = Path.GetFileName(file_path);
                        var tempFilePath = Path.Combine(tempOutputDirectory, file);
                        var outputFile   = Path.Combine(outputDirectory, file);


                        IUTF8Str maxNotification = GlobalInterface.Instance.UTF8Str.Create(outputFile);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, maxNotification);
                        moveFileToOutputDirectory(tempFilePath, outputFile, exportParameters);
                        Loader.Global.BroadcastNotification(SystemNotificationCode.PostExport, maxNotification);

                        break;
                    }
                }
            }
            else
            {
                foreach (var filePath in filePaths)
                {
                    var    file         = Path.GetFileName(filePath);
                    string ext          = Path.GetExtension(file);
                    var    tempFilePath = Path.Combine(tempOutputDirectory, file);
                    var    outputPath   = Path.Combine(outputDirectory, file);
                    if (!string.IsNullOrWhiteSpace(exportParameters.textureFolder) && TextureUtilities.ExtensionIsValidGLTFTexture(ext))
                    {
                        outputPath = Path.Combine(exportParameters.textureFolder, file);
                    }

                    IUTF8Str maxNotification = GlobalInterface.Instance.UTF8Str.Create(outputPath);
                    Loader.Global.BroadcastNotification(SystemNotificationCode.PreExport, maxNotification);
                    moveFileToOutputDirectory(tempFilePath, outputPath, exportParameters);
                    Loader.Global.BroadcastNotification(SystemNotificationCode.PostExport, maxNotification);
                }
            }
            Directory.Delete(tempOutputDirectory, true);
            watch.Stop();

            RaiseMessage(string.Format("Exportation done in {0:0.00}s: {1}", watch.ElapsedMilliseconds / 1000.0, fileExportString), Color.Blue);
            IUTF8Str max_notification = Autodesk.Max.GlobalInterface.Instance.UTF8Str.Create("BabylonExportComplete");
            Loader.Global.BroadcastNotification(SystemNotificationCode.PostExport, max_notification);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Export to file
        /// </summary>
        /// <param name="outputDirectory">The directory to store the generated files</param>
        /// <param name="outputFileName">The filename to use for the generated files</param>
        /// <param name="outputFormat">The format to use for the generated files</param>
        /// <param name="generateManifest">Specifies if a manifest file should be generated</param>
        /// <param name="onlySelected">Specifies if only the selected objects should be exported</param>
        /// <param name="autoSaveMayaFile">Specifies if the Maya scene should be auto-saved</param>
        /// <param name="exportHiddenObjects">Specifies if hidden objects should be exported</param>
        /// <param name="copyTexturesToOutput">Specifies if textures should be copied to the output directory</param>
        /// <param name="optimizeVertices">Specifies if vertices should be optimized on export</param>
        /// <param name="exportTangents">Specifies if tangents should be exported</param>
        /// <param name="scaleFactor">Scales the scene by this factor</param>
        /// <param name="exportSkin">Specifies if skins should be exported</param>
        /// <param name="quality">The texture quality</param>
        /// <param name="dracoCompression">Specifies if draco compression should be used</param>
        /// <param name="exportMorphNormal">Specifies if normals should be exported for morph targets</param>
        /// <param name="exportMorphTangent">Specifies if tangents should be exported for morph targets</param>
        /// <param name="exportKHRLightsPunctual">Specifies if the KHR_lights_punctual extension should be enabled</param>
        /// <param name="exportKHRTextureTransform">Specifies if the KHR_texture_transform extension should be enabled</param>
        /// <param name="bakeAnimationFrames">Specifies if animations should be exporting keyframes directly or should manually bake out animations frame by frame</param>
        public void Export(ExportParameters exportParameters)
        {
            this.exportParameters = exportParameters;

            // Check if the animation is running
            MGlobal.executeCommand("play -q - state", out int isPlayed);
            if (isPlayed == 1)
            {
                RaiseError("Stop the animation before exporting.");
                return;
            }

            RaiseMessage("Export started", Color.Blue);
            var progression = 0.0f;

            ReportProgressChanged(progression);

            // Store export options
            this.isBabylonExported = exportParameters.outputFormat == "babylon" || exportParameters.outputFormat == "binary babylon";

            var outputBabylonDirectory = Path.GetDirectoryName(exportParameters.outputPath);

            // Check directory exists
            if (!Directory.Exists(outputBabylonDirectory))
            {
                RaiseError("Export stopped: Output folder does not exist");
                ReportProgressChanged(100);
                return;
            }

            var watch = new Stopwatch();

            watch.Start();


            var babylonScene = new BabylonScene(outputBabylonDirectory);

            // Save scene
            if (exportParameters.autoSaveSceneFile)
            {
                RaiseMessage("Saving Maya file");

                // Query expand file name
                string fileName = MGlobal.executeCommandStringResult($@"file -q -exn;");

                // If scene has already been saved previously
                if (fileName.EndsWith(".ma") || fileName.EndsWith(".mb"))
                {
                    // Name is already specified and this line will not fail
                    MFileIO.save();
                }
                else
                {
                    // Open SaveAs dialog window
                    MGlobal.executeCommand($@"fileDialog2;");
                }
            }

            // Force output file extension to be babylon
            var outputFileName = Path.ChangeExtension(Path.GetFileName(exportParameters.outputPath), "babylon");

            // Store selected nodes
            MSelectionList selectedNodes = new MSelectionList();

            MGlobal.getActiveSelectionList(selectedNodes);
            selectedNodeFullPaths = new List <string>();
            MItSelectionList mItSelectionList = new MItSelectionList(selectedNodes);

            while (!mItSelectionList.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                try
                {
                    mItSelectionList.getDagPath(mDagPath);
                    selectedNodeFullPaths.Add(mDagPath.fullPathName);
                } catch
                {
                    // selected object is not a DAG object
                    // fail silently
                }

                mItSelectionList.next();
            }
            if (selectedNodeFullPaths.Count > 0)
            {
                RaiseMessage("Selected nodes full path");
                foreach (string selectedNodeFullPath in selectedNodeFullPaths)
                {
                    RaiseMessage(selectedNodeFullPath, 1);
                }
            }

            // Producer
            babylonScene.producer = new BabylonProducer
            {
                name             = "Maya",
                version          = "2018",
                exporter_version = exporterVersion,
                file             = outputFileName
            };

            // Global
            babylonScene.autoClear = true;
            // TODO - Retreive colors from Maya
            //babylonScene.clearColor = Loader.Core.GetBackGround(0, Tools.Forever).ToArray();
            //babylonScene.ambientColor = Loader.Core.GetAmbient(0, Tools.Forever).ToArray();

            babylonScene.TimelineStartFrame      = Loader.GetMinTime();
            babylonScene.TimelineEndFrame        = Loader.GetMaxTime();
            babylonScene.TimelineFramesPerSecond = Loader.GetFPS();

            // TODO - Add custom properties
            _exportQuaternionsInsteadOfEulers = true;

            PrintDAG(true);
            PrintDAG(false);

            // Store the current frame. It can be change to find a proper one for the node/bone export
            double currentTime = Loader.GetCurrentTime();

            // --------------------
            // ------ Nodes -------
            // --------------------
            RaiseMessage("Exporting nodes");

            // It makes each morph target manager export starts from id = 0.
            BabylonMorphTargetManager.Reset();

            // Clear materials
            referencedMaterials.Clear();
            multiMaterials.Clear();

            // Get all nodes
            var             dagIterator = new MItDag(MItDag.TraversalType.kDepthFirst, MFn.Type.kTransform);
            List <MDagPath> nodes       = new List <MDagPath>();

            while (!dagIterator.isDone)
            {
                MDagPath mDagPath = new MDagPath();
                dagIterator.getPath(mDagPath);

                // Check if one of its descendant (direct or not) is a mesh/camera/light/locator
                if (isNodeRelevantToExportRec(mDagPath)
                    // Ensure it's not one of the default cameras used as viewports in Maya
                    && defaultCameraNames.Contains(mDagPath.partialPathName) == false)
                {
                    nodes.Add(mDagPath);
                }
                else
                {
                    // Skip descendants
                    dagIterator.prune();
                }

                dagIterator.next();
            }
            // Export all nodes
            var progressionStep = 100.0f / nodes.Count;

            foreach (MDagPath mDagPath in nodes)
            {
                BabylonNode babylonNode = null;

                try
                {
                    switch (getApiTypeOfDirectDescendants(mDagPath))
                    {
                    case MFn.Type.kMesh:
                        babylonNode = ExportMesh(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kCamera:
                        babylonNode = ExportCamera(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kLight:     // Lights api type are actually kPointLight, kSpotLight...
                        babylonNode = ExportLight(mDagPath, babylonScene);
                        break;

                    case MFn.Type.kLocator:     // Camera target
                        babylonNode = ExportDummy(mDagPath, babylonScene);
                        break;
                    }
                }
                catch (Exception e)
                {
                    this.RaiseWarning(String.Format("Exception raised during export. Node will be exported as dummy node. \r\nMessage: \r\n{0} \r\n{1}", e.Message, e.InnerException), 2);
                }

                // If node is not exported successfully
                if (babylonNode == null)
                {
                    // Create a dummy (empty mesh)
                    babylonNode = ExportDummy(mDagPath, babylonScene);
                }
                ;

                // Update progress bar
                progression += progressionStep;
                ReportProgressChanged(progression);

                CheckCancelled();
            }
            RaiseMessage(string.Format("Total meshes: {0}", babylonScene.MeshesList.Count), Color.Gray, 1);


            // if nothing is enlightened, exclude all meshes
            foreach (BabylonLight light in babylonScene.LightsList)
            {
                if (light.includedOnlyMeshesIds.Length == 0)
                {
                    light.excludedMeshesIds = babylonScene.MeshesList.Select(m => m.id).ToArray();
                }
            }

            /*
             * Switch coordinate system at global level
             *
             * Add a root node with negative scaling
             * Pros - It's safer to use a root node
             * Cons - It's cleaner to switch at object level (as it is done now)
             * Use root node method when you want to be 100% sure of the output
             * Don't forget to also inverse winding order of mesh indices
             */
            //// Switch from right to left handed coordinate system
            //MUuid mUuid = new MUuid();
            //mUuid.generate();
            //var rootNode = new BabylonMesh
            //{
            //    name = "root",
            //    id = mUuid.asString(),
            //    scaling = new float[] { 1, 1, -1 }
            //};
            //foreach(var babylonMesh in babylonScene.MeshesList)
            //{
            //    // Add root meshes as child to root node
            //    if (babylonMesh.parentId == null)
            //    {
            //        babylonMesh.parentId = rootNode.id;
            //    }
            //}
            //babylonScene.MeshesList.Add(rootNode);

            // Main camera
            BabylonCamera babylonMainCamera = null;

            if (babylonScene.CamerasList.Count > 0)
            {
                // Set first camera as main one
                babylonMainCamera           = babylonScene.CamerasList[0];
                babylonScene.activeCameraID = babylonMainCamera.id;
                RaiseMessage("Active camera set to " + babylonMainCamera.name, Color.Green, 1, true);
            }

            if (babylonMainCamera == null)
            {
                RaiseWarning("No camera defined", 1);
            }
            else
            {
                RaiseMessage(string.Format("Total cameras: {0}", babylonScene.CamerasList.Count), Color.Gray, 1);
            }

            // Default light
            if (!exportParameters.pbrNoLight && babylonScene.LightsList.Count == 0)
            {
                RaiseWarning("No light defined", 1);
                RaiseWarning("A default ambient light was added for your convenience", 1);
                ExportDefaultLight(babylonScene);
            }
            else
            {
                RaiseMessage(string.Format("Total lights: {0}", babylonScene.LightsList.Count), Color.Gray, 1);
            }

            var sceneScaleFactor = exportParameters.scaleFactor;

            if (exportParameters.scaleFactor != 1.0f)
            {
                RaiseMessage(String.Format("A root node is added to globally scale the scene by {0}", sceneScaleFactor), 1);

                // Create root node for scaling
                BabylonMesh rootNode = new BabylonMesh {
                    name = "root", id = Tools.GenerateUUID()
                };
                rootNode.isDummy = true;
                float rootNodeScale = sceneScaleFactor;
                rootNode.scaling = new float[3] {
                    rootNodeScale, rootNodeScale, rootNodeScale
                };

                if (ExportQuaternionsInsteadOfEulers)
                {
                    rootNode.rotationQuaternion = new float[] { 0, 0, 0, 1 };
                }
                else
                {
                    rootNode.rotation = new float[] { 0, 0, 0 };
                }

                // Update all top nodes
                var babylonNodes = new List <BabylonNode>();
                babylonNodes.AddRange(babylonScene.MeshesList);
                babylonNodes.AddRange(babylonScene.CamerasList);
                babylonNodes.AddRange(babylonScene.LightsList);
                foreach (BabylonNode babylonNode in babylonNodes)
                {
                    if (babylonNode.parentId == null)
                    {
                        babylonNode.parentId = rootNode.id;
                    }
                }

                // Store root node
                babylonScene.MeshesList.Add(rootNode);
            }

            // --------------------
            // ----- Materials ----
            // --------------------
            RaiseMessage("Exporting materials");
            GenerateMaterialDuplicationDatas(babylonScene);
            foreach (var mat in referencedMaterials)
            {
                ExportMaterial(mat, babylonScene, exportParameters.pbrFull);
                CheckCancelled();
            }
            foreach (var mat in multiMaterials)
            {
                ExportMultiMaterial(mat.Key, mat.Value, babylonScene, exportParameters.pbrFull);
                CheckCancelled();
            }
            UpdateMeshesMaterialId(babylonScene);
            RaiseMessage(string.Format("Total: {0}", babylonScene.MaterialsList.Count + babylonScene.MultiMaterialsList.Count), Color.Gray, 1);


            // Export skeletons
            if (exportParameters.exportSkins && skins.Count > 0)
            {
                progressSkin     = 0;
                progressSkinStep = 100 / skins.Count;
                ReportProgressChanged(progressSkin);
                RaiseMessage("Exporting skeletons");
                foreach (var skin in skins)
                {
                    ExportSkin(skin, babylonScene);
                }
            }

            // set back the frame
            Loader.SetCurrentTime(currentTime);

            // ----------------------------
            // ----- Animation groups -----
            // ----------------------------
            RaiseMessage("Export animation groups");
            // add animation groups to the scene
            babylonScene.animationGroups = ExportAnimationGroups(babylonScene);


            if (isBabylonExported)
            {
                // if we are exporting to .Babylon then remove then remove animations from nodes if there are animation groups.
                if (babylonScene.animationGroups.Count > 0)
                {
                    // add animations of each nodes in the animGroup
                    List <BabylonNode> babylonNodes = new List <BabylonNode>();
                    babylonNodes.AddRange(babylonScene.MeshesList);
                    babylonNodes.AddRange(babylonScene.CamerasList);
                    babylonNodes.AddRange(babylonScene.LightsList);

                    foreach (BabylonNode node in babylonNodes)
                    {
                        node.animations = null;
                    }
                    foreach (BabylonSkeleton skel in babylonScene.SkeletonsList)
                    {
                        foreach (BabylonBone bone in skel.bones)
                        {
                            bone.animation = null;
                        }
                    }
                }

                // setup a default skybox for the scene for .Babylon export.
                var sourcePath = exportParameters.pbrEnvironment;
                if (!string.IsNullOrEmpty(sourcePath))
                {
                    babylonScene.createDefaultSkybox = exportParameters.createDefaultSkybox;
                    var fileName = Path.GetFileName(sourcePath);

                    // Allow only dds file format
                    if (!fileName.EndsWith(".dds"))
                    {
                        RaiseWarning("Failed to export defauenvironment texture: only .dds format is supported.");
                    }
                    else
                    {
                        RaiseMessage($"texture id = Max_Babylon_Default_Environment");
                        babylonScene.environmentTexture = fileName;

                        if (exportParameters.writeTextures)
                        {
                            try
                            {
                                var destPath = Path.Combine(babylonScene.OutputPath, fileName);
                                if (File.Exists(sourcePath) && sourcePath != destPath)
                                {
                                    File.Copy(sourcePath, destPath, true);
                                }
                            }
                            catch
                            {
                                // silently fails
                                RaiseMessage($"Fail to export the default env texture", 3);
                            }
                        }
                    }
                }
            }

            // Output
            babylonScene.Prepare(false, false);

            if (isBabylonExported)
            {
                Write(babylonScene, outputBabylonDirectory, outputFileName, exportParameters.outputFormat, exportParameters.generateManifest);
            }

            ReportProgressChanged(100);

            // Export glTF
            if (exportParameters.outputFormat == "gltf" || exportParameters.outputFormat == "glb")
            {
                bool generateBinary = exportParameters.outputFormat == "glb";

                GLTFExporter gltfExporter = new GLTFExporter();
                gltfExporter.ExportGltf(this.exportParameters, babylonScene, outputBabylonDirectory, outputFileName, generateBinary, this);
            }

            watch.Stop();
            RaiseMessage(string.Format("Export done in {0:0.00}s", watch.ElapsedMilliseconds / 1000.0), Color.Blue);
        }
Exemplo n.º 10
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo info)
        {
            var babylonCamera = babylonObject as BabylonCamera;
            var gltfAnimation = gltfObject as GLTFAnimation;
            AnimationExtensionInfo animationExtensionInfo = info as AnimationExtensionInfo;

            if (babylonCamera == null)
            {
                return(null);
            }

            Guid guid = Guid.Empty;

            Guid.TryParse(babylonCamera.id, out guid);
            IINode camNode = Tools.GetINodeByGuid(guid);

            var maxCamera = CameraUtilities.GetGenCameraFromNode(camNode, exporter.logger);

            if (maxCamera == null)
            {
                exporter.logger.RaiseError($"Impossible to export {FlightSimAsoboPropertyAnimationExtension.SerializedName} for {camNode.Name}, camera node must be a TargetCamera type");
                return(null);
            }

            if (babylonCamera != null && gltfAnimation != null && FlightSimCameraUtilities.class_ID.Equals(new MaterialUtilities.ClassIDWrapper(maxCamera.ClassID)))
            {
                GLTFNode   gltfNode   = null;
                GLTFCamera gltfCamera = null;
                if (!exporter.nodeToGltfNodeMap.TryGetValue(babylonCamera, out gltfNode))
                {
                    return(gltfObject);
                }
                if (gltfNode != null && gltfNode.camera >= 0)
                {
                    gltfCamera = gltf.CamerasList[gltfNode.camera.GetValueOrDefault()];
                }

                int samplerIndex = AddParameterSamplerAnimation(babylonCamera, gltfAnimation, exporter, gltf, animationExtensionInfo.startFrame, animationExtensionInfo.endFrame);
                if (samplerIndex > -1)
                {
                    GLTFExtensionAsoboPropertyAnimation gltfExtension             = new GLTFExtensionAsoboPropertyAnimation();
                    List <GLTFAnimationPropertyChannel> animationPropertyChannels = new List <GLTFAnimationPropertyChannel>();

                    //TODO: for each animated property in the camera
                    //TODO: this should be generated based on the property itself
                    GLTFAnimationPropertyChannel propertyChannel = new GLTFAnimationPropertyChannel();
                    propertyChannel.sampler = samplerIndex;

                    propertyChannel.target = $"cameras/{gltfCamera.index}/perspective/yfov";

                    animationPropertyChannels.Add(propertyChannel);

                    gltfExtension.channels = animationPropertyChannels.ToArray();
                    return(gltfExtension);
                }
            }

            return(null);
        }
Exemplo n.º 11
0
        private int AddParameterSamplerAnimation(BabylonCamera babylonCamera, GLTFAnimation gltfAnimation, GLTFExporter exporter, GLTF gltf, int startFrame, int endFrame)
        {
            var samplerList = gltfAnimation.SamplerList;
            // Combine babylon animations from .babylon file and cached ones
            var babylonAnimations = new List <BabylonAnimation>();

            if (babylonCamera.animations != null)
            {
                IEnumerable <BabylonAnimation> extendedAnimations = babylonCamera.animations.Where(anim => anim.name == "fov animation");
                babylonAnimations.AddRange(extendedAnimations);
            }

            if (babylonAnimations.Count > 0)
            {
                if (babylonAnimations.Count > 0)
                {
                    exporter.logger.RaiseMessage("GLTFExporter.Animation | Export animations of node named: " + babylonCamera.name, 2);
                }


                foreach (BabylonAnimation babylonAnimation in babylonAnimations)
                {
                    var babylonAnimationKeysInRange = babylonAnimation.keys.Where(key => key.frame >= startFrame && key.frame <= endFrame);
                    if (babylonAnimationKeysInRange.Count() <= 0)
                    {
                        continue;
                    }

                    string target_path = babylonAnimation.property;

                    // --- Input ---
                    var accessorInput = exporter._createAndPopulateInput(gltf, babylonAnimation, startFrame, endFrame);
                    if (accessorInput == null)
                    {
                        continue;
                    }

                    // --- Output ---
                    GLTFAccessor accessorOutput = FlightSimAsoboPropertyAnimationExtension._createAccessorOfProperty(target_path, gltf);
                    if (accessorOutput == null)
                    {
                        continue;
                    }

                    // Populate accessor
                    int numKeys = 0;
                    foreach (var babylonAnimationKey in babylonAnimationKeysInRange)
                    {
                        numKeys++;

                        // copy data before changing it in case animation groups overlap
                        float[] outputValues = new float[babylonAnimationKey.values.Length];
                        babylonAnimationKey.values.CopyTo(outputValues, 0);

                        // Store values as bytes
                        foreach (var outputValue in outputValues)
                        {
                            accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue));
                        }
                    }
                    ;
                    accessorOutput.count = numKeys;
                    if (accessorOutput.count == 0)
                    {
                        exporter.logger.RaiseWarning(String.Format("GLTFExporter.Animation | No frames to export in material animation \"{1}\" of node named \"{0}\". This will cause an error in the output gltf.", babylonCamera.name, babylonAnimation.name));
                    }

                    // Animation sampler
                    var gltfAnimationSampler = new GLTFAnimationSampler
                    {
                        input  = accessorInput.index,
                        output = accessorOutput.index
                    };
                    gltfAnimationSampler.index = samplerList.Count;
                    samplerList.Add(gltfAnimationSampler);
                }
            }
            else
            {
                return(-1);
            }

            return(samplerList.Count - 1);
        }
Exemplo n.º 12
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo extInfo)
        {
            var babylonMesh = babylonObject as BabylonMesh;

            if (babylonMesh != null)
            {
                GLTFExtensionAsoboFade   fade        = new GLTFExtensionAsoboFade();
                List <GLTFExtensionFade> fadeObjects = new List <GLTFExtensionFade>();
                fade.fades = fadeObjects;
                Guid guid = Guid.Empty;
                Guid.TryParse(babylonMesh.id, out guid);
                IINode maxNode = Tools.GetINodeByGuid(guid);
                foreach (IINode node in maxNode.DirectChildren())
                {
                    IObject obj = node.ObjectRef;
                    if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(SphereFadeClassID))
                    {
                        GLTFExtensionFade fadeSphere = new GLTFExtensionFade();
                        GLTFExtensionAsoboFadeSphereParams sphereParams = new GLTFExtensionAsoboFadeSphereParams();
                        float radius = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "SphereGizmo", "radius");
                        fadeSphere.Translation = FlightSimExtensionUtility.GetTranslation(node, maxNode);
                        sphereParams.radius    = radius;
                        fadeSphere.Type        = "sphere";
                        fadeSphere.Params      = sphereParams;
                        fadeObjects.Add(fadeSphere);
                    }
                }
                if (fadeObjects.Count > 0)
                {
                    return(fade);
                }
            }
            return(null);
        }
Exemplo n.º 13
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo extInfo)
        {
            var babylonLight = babylonObject as BabylonNode;

            if (babylonLight != null)
            {
                GLTFExtensionAsoboMacroLight macroLightExt = new GLTFExtensionAsoboMacroLight();

                Guid guid = Guid.Empty;
                Guid.TryParse(babylonLight.id, out guid);
                IINode maxNode = Tools.GetINodeByGuid(guid);
                if (maxNode != null)
                {
                    IObject obj = maxNode.ObjectRef;
                    if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(MacroLightOmniClassID))
                    {
                        exporter.logger?.RaiseCriticalError($"{maxNode.NodeName} is type of MacroLightOmni and it is DEPRECATED, use FlightSimLight");
                        return(null);
                    }
                    else if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(MacroLightSpotClassID))
                    {
                        exporter.logger?.RaiseCriticalError($"{maxNode.NodeName} is type of MacroLightSpot and it is DEPRECATED, use FlightSimLight");
                        return(null);
                    }
                    else if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(FlightSimLightClassID))
                    {
                        macroLightExt.color          = GetColor(maxNode);
                        macroLightExt.intensity      = GetIntensity(maxNode);
                        macroLightExt.coneAngle      = GetConeAngle(maxNode);
                        macroLightExt.hasSimmetry    = GetHasSimmetry(maxNode);
                        macroLightExt.flashFrequency = GetFlashFrequency(maxNode);
                        macroLightExt.dayNightCycle  = GetDayNightCycle(maxNode);
                        macroLightExt.flashDuration  = GetFlashDuration(maxNode);
                        macroLightExt.flashPhase     = GetFlashPhase(maxNode);
                        macroLightExt.rotationSpeed  = GetRotationSpeed(maxNode);
                        return(macroLightExt);
                    }
                }
            }
            return(null);
        }
Exemplo n.º 14
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo extInfo)
        {
            var babylonMesh = babylonObject as BabylonMesh;

            if (babylonMesh != null)
            {
                GLTFExtensionAsoboGizmo   gltfExtensionAsoboGizmo = new GLTFExtensionAsoboGizmo();
                List <GLTFExtensionGizmo> collisions = new List <GLTFExtensionGizmo>();
                gltfExtensionAsoboGizmo.gizmos = collisions;

                Guid guid = Guid.Empty;
                Guid.TryParse(babylonMesh.id, out guid);
                IINode maxNode = Tools.GetINodeByGuid(guid);
                foreach (IINode node in maxNode.DirectChildren())
                {
                    IObject            obj   = node.ObjectRef;
                    List <AsoboTag>    tags  = new List <AsoboTag>();
                    GLTFExtensionGizmo gizmo = new GLTFExtensionGizmo();;
                    if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(BoxColliderClassID))
                    {
                        GLTFExtensionAsoboBoxParams boxParams = new GLTFExtensionAsoboBoxParams();
                        float height = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "BoxGizmo", "height");
                        float width  = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "BoxGizmo", "width");
                        float length = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "BoxGizmo", "length");
                        gizmo.Translation = FlightSimExtensionUtility.GetTranslation(node, maxNode);
                        float[] rotation = FlightSimExtensionUtility.GetRotation(node, maxNode);
                        if (!FlightSimExtensionUtility.IsDefaultRotation(rotation))
                        {
                            gizmo.Rotation = rotation;
                        }

                        boxParams.width  = width;
                        boxParams.height = height;
                        boxParams.length = length;

                        gizmo.Params = boxParams;
                        gizmo.Type   = "box";

                        bool isRoad      = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "BoxCollider", "IsRoad", IsSubClass: false);
                        bool isCollision = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "BoxCollider", "IsCollider", IsSubClass: false);

                        if (isCollision)
                        {
                            tags.Add(AsoboTag.Collision);
                        }
                        if (isRoad)
                        {
                            tags.Add(AsoboTag.Road);
                        }

                        ParseTags(ref gizmo, ref gltf, ref tags);
                        collisions.Add(gizmo);
                    }
                    else if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(CylinderColliderClassID))
                    {
                        GLTFExtensionAsoboCylinderParams cylinderParams = new GLTFExtensionAsoboCylinderParams();
                        float radius = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "CylGizmo", "radius");
                        float height = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "CylGizmo", "height");
                        gizmo.Translation = FlightSimExtensionUtility.GetTranslation(node, maxNode);
                        float[] rotation = FlightSimExtensionUtility.GetRotation(node, maxNode);
                        if (!FlightSimExtensionUtility.IsDefaultRotation(rotation))
                        {
                            gizmo.Rotation = rotation;
                        }
                        cylinderParams.height = height;
                        cylinderParams.radius = radius;
                        gizmo.Params          = cylinderParams;
                        gizmo.Type            = "cylinder";

                        bool isRoad      = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "CylCollider", "IsRoad", IsSubClass: false);
                        bool isCollision = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "CylCollider", "IsCollider", IsSubClass: false);

                        if (isCollision)
                        {
                            tags.Add(AsoboTag.Collision);
                        }
                        if (isRoad)
                        {
                            tags.Add(AsoboTag.Road);
                        }

                        ParseTags(ref gizmo, ref gltf, ref tags);
                        collisions.Add(gizmo);
                    }
                    else if (new MaterialUtilities.ClassIDWrapper(obj.ClassID).Equals(SphereColliderClassID))
                    {
                        GLTFExtensionAsoboSphereParams sphereParams = new GLTFExtensionAsoboSphereParams();
                        float radius = FlightSimExtensionUtility.GetGizmoParameterFloat(node, "SphereGizmo", "radius");
                        gizmo.Translation   = FlightSimExtensionUtility.GetTranslation(node, maxNode);
                        sphereParams.radius = radius;
                        gizmo.Type          = "sphere";
                        gizmo.Params        = sphereParams;

                        bool isRoad      = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "SphereCollider", "IsRoad", IsSubClass: false);
                        bool isCollision = FlightSimExtensionUtility.GetGizmoParameterBoolean(node, "SphereCollider", "IsCollider", IsSubClass: false);

                        if (isCollision)
                        {
                            tags.Add(AsoboTag.Collision);
                        }
                        if (isRoad)
                        {
                            tags.Add(AsoboTag.Road);
                        }

                        ParseTags(ref gizmo, ref gltf, ref tags);
                        collisions.Add(gizmo);
                    }
                }
                if (collisions.Count > 0)
                {
                    return(gltfExtensionAsoboGizmo);
                }
            }
            return(null);
        }
Exemplo n.º 15
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo info)
        {
            var babylonMaterial = babylonObject as BabylonMaterial;
            var gltfAnimation   = gltfObject as GLTFAnimation;
            AnimationExtensionInfo animationExtensionInfo = info as AnimationExtensionInfo;

            if (babylonMaterial == null)
            {
                return(null);
            }

            if (gltfAnimation != null && FlightSimMaterialUtilities.class_ID.Equals(new MaterialUtilities.ClassIDWrapper(babylonMaterial.maxGameMaterial.MaxMaterial.ClassID)))
            {
                GLTFMaterial gltfMaterial;
                if (!exporter.materialToGltfMaterialMap.TryGetValue(babylonMaterial, out gltfMaterial))
                {
                    return(gltfObject);
                }

                int samlerIndex = gltfAnimation.SamplerList.Count;

                AddParameterSamplerAnimation(babylonMaterial, gltfAnimation, exporter, gltf, animationExtensionInfo.startFrame, animationExtensionInfo.endFrame);


                GLTFExtensionAsoboPropertyAnimation gltfExtension = new GLTFExtensionAsoboPropertyAnimation();

                //in case more material are animated in the same animation group
                // the extension used on the animation need to be stored
                if (gltfAnimation.extensions != null && gltfAnimation.extensions.Count > 0)
                {
                    foreach (KeyValuePair <string, object> ext in gltfAnimation.extensions)
                    {
                        if (ext.Key == FlightSimAsoboPropertyAnimationExtension.SerializedName)
                        {
                            gltfExtension = (GLTFExtensionAsoboPropertyAnimation)ext.Value;
                        }
                    }
                }

                List <GLTFAnimationPropertyChannel> matAnimationsPropertyChannels = new List <GLTFAnimationPropertyChannel>();

                if (gltfExtension.channels != null)
                {
                    matAnimationsPropertyChannels.AddRange(gltfExtension.channels);
                }

                IIGameProperty property = babylonMaterial.maxGameMaterial.IPropertyContainer.QueryProperty("materialType");

                int material_value = 0;
                if (!property.GetPropertyValue(ref material_value, 0))
                {
                    return(null);
                }

                MaterialType materialType = FlightSimMaterialHelper.GetMaterialType(material_value);

                foreach (BabylonAnimation anim in babylonMaterial.animations)
                {
                    GLTFAnimationPropertyChannel propertyChannel = new GLTFAnimationPropertyChannel();
                    propertyChannel.sampler = samlerIndex;

                    if (materialType == MaterialType.Windshield && anim.property == "wiperAnimState1")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboWindshield.SerializedName}/wiper1State";
                    }
                    else if (materialType == MaterialType.Windshield && anim.property == "wiperAnimState2")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboWindshield.SerializedName}/wiper2State";
                    }
                    else if (materialType == MaterialType.Windshield && anim.property == "wiperAnimState3")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboWindshield.SerializedName}/wiper3State";
                    }
                    else if (materialType == MaterialType.Windshield && anim.property == "wiperAnimState4")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboWindshield.SerializedName}/wiper4State";
                    }
                    else if (materialType == MaterialType.Standard && anim.property == "emissive")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/emissiveFactor";
                    }
                    else if (materialType == MaterialType.Standard && anim.property == "baseColor")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/pbrMetallicRoughness/baseColorFactor";
                    }
                    else if (materialType == MaterialType.Standard && anim.property == "roughness")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/pbrMetallicRoughness/roughnessFactor";
                    }
                    else if (materialType == MaterialType.Standard && anim.property == "metallic")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/pbrMetallicRoughness/metallicFactor";
                    }
                    else if (materialType != MaterialType.EnvironmentOccluder && anim.property == "UVOffsetU")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboMaterialUVOptions.SerializedName}/UVOffsetU";
                    }
                    else if (materialType != MaterialType.EnvironmentOccluder && anim.property == "UVOffsetV")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboMaterialUVOptions.SerializedName}/UVOffsetV";
                    }
                    else if (materialType != MaterialType.EnvironmentOccluder && anim.property == "UVTilingU")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboMaterialUVOptions.SerializedName}/UVTilingU";
                    }
                    else if (materialType != MaterialType.EnvironmentOccluder && anim.property == "UVTilingV")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboMaterialUVOptions.SerializedName}/UVTilingV";
                    }
                    else if (materialType != MaterialType.EnvironmentOccluder && anim.property == "UVRotation")
                    {
                        propertyChannel.target = $"materials/{gltfMaterial.index}/extensions/{GLTFExtensionAsoboMaterialUVOptions.SerializedName}/UVRotation";
                    }

                    if (propertyChannel.isValid())
                    {
                        matAnimationsPropertyChannels.Add(propertyChannel);
                        samlerIndex += 1;
                    }
                }

                gltfExtension.channels = matAnimationsPropertyChannels.ToArray();

                return(gltfExtension);
            }

            return(null);
        }
Exemplo n.º 16
0
        public object ExportGLTFExtension <T1, T2>(T1 babylonObject, ref T2 gltfObject, ref GLTF gltf, GLTFExporter exporter, ExtensionInfo extInfo)
        {
            var babylonScene = babylonObject as BabylonScene;

            if (babylonScene != null)
            {
                GLTFExtensionGlobalFadeScale fadeScale = new GLTFExtensionGlobalFadeScale();
                float fadeGlobalScale = Loader.Core.RootNode.GetFloatProperty("flightsim_fade_globalscale", 1);
                fadeScale.scale = fadeGlobalScale;

                if (fadeScale.scale != 1.0f)
                {
                    return(fadeScale);
                }
            }
            return(null);
        }