private IEnumerator Export(Func <Type.Scene, Module.ExporterSuccessCallback, IEnumerator> exporter, GameObject root, string filename, Module.ExporterSuccessCallback return_callback, Module.ProgressCallback progress_callback = null) { bool success = false; bool waiting; do { lock (this) { if (exporting) { waiting = true; } else { exporting = true; waiting = false; } } if (waiting) { yield return(null); } }while(waiting); if (exporter != null) { int refresh_rate = Screen.currentResolution.refreshRate; float max_frame_duration = 1000.0f * 0.75f * (1.0f / (float)(refresh_rate >= 20 ? refresh_rate : 60)); // In milliseconds. Use only 75% of the available time to avoid missing vsync events // Create timer to break the code that must be executed in unity thread into chunks that will fit into the required target framerate System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); DateTime start = DateTime.Now; Type.Scene scene = null; // Get data from Unity IEnumerator it = Type.Scene.FromUnity(root, s => scene = s, progress_callback); timer.Start(); // Split code executed in unity thread into chunks that allow to maintain targeted framerate, // without loosing unnecessary time by yielding every time possible (because 1 yield <=> 1 frame) while (it.MoveNext()) { if (timer.ElapsedMilliseconds >= max_frame_duration) { yield return(null); timer.Reset(); timer.Start(); } } if (scene != null) { // Export data to final format it = exporter(scene, s => success = s); while (it.MoveNext()) { yield return(it.Current); } DateTime end = DateTime.Now; if (success) { Debug.LogFormat("Export successful: {0}.", end.Subtract(start)); } else { Debug.LogErrorFormat("Export to '{0}' failed.", filename); } } else { Debug.LogErrorFormat("Export to '{0}' failed.", filename); } } else { Debug.LogError("Invalid null exporter."); } // Ready to accept new exports lock (this) { exporting = false; } if (return_callback != null) { return_callback(success); } }
private IEnumerator Import(Func <Module.ImporterReturnCallback, IEnumerator> importer, string filename, ReturnCallback return_callback, Module.ProgressCallback progress_callback = null) { bool waiting; do { lock (this) { if (importing) { waiting = true; } else { importing = true; waiting = false; } } if (waiting) { yield return(null); } }while(waiting); if (importer != null) { int refresh_rate = Screen.currentResolution.refreshRate; float max_frame_duration = 1000.0f * 0.75f * (1.0f / (float)(refresh_rate >= 20 ? refresh_rate : 60)); // In milliseconds. Use only 75% of the available time to avoid missing vsync events // Create timer to break the code that must be executed in unity thread into chunks that will fit into the required target framerate System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); DateTime start = DateTime.Now; Type.Scene scene = null; // Import data IEnumerator it = importer(s => scene = s); while (it.MoveNext()) { yield return(it.Current); } if (scene != null) { // Convert data to Unity format it = scene.ToUnity(progress_callback); timer.Start(); // Split code executed in unity thread into chunks that allow to maintain targeted framerate, // without loosing unnecessary time by yielding every time possible (because 1 yield <=> 1 frame) while (it.MoveNext()) { if (timer.ElapsedMilliseconds >= max_frame_duration) { yield return(null); timer.Reset(); timer.Start(); } } DateTime end = DateTime.Now; // Add diagnostic info if (scene.UnityRoot != null) { int vertices_loaded = 0; int faces_loaded = 0; foreach (Type.Mesh mesh in scene.meshes) { vertices_loaded += mesh.VerticesCount; faces_loaded += mesh.FacesCount; } scene.UnityRoot.AddComponent <Info>().Init(filename, end.Subtract(start), vertices_loaded, faces_loaded, scene.IdMapping.Id2Go); } if (return_callback != null) { return_callback(scene.UnityRoot); } } else { Debug.LogErrorFormat("Import of '{0}' failed.", filename); } } else { Debug.LogError("Invalid null importer."); } // Ready to accept new imports lock (this) { importing = false; } }