Esempio n. 1
0
//----------------------------------------------------------------------------------------------------------------------

        private void DrawUpdateRenderCacheGUI()
        {
            ShortcutBinding updateRenderCacheShortcut
                = ShortcutManager.instance.GetShortcutBinding(SISEditorConstants.SHORTCUT_UPDATE_RENDER_CACHE);

            using (new EditorGUILayout.VerticalScope(GUI.skin.box)) {
                RenderCachePlayableAssetEditorConfig editorConfig = m_asset.GetEditorConfig();

                bool captureAllFrames = EditorGUILayout.Toggle("Capture All Frames", editorConfig.GetCaptureAllFrames());
                editorConfig.SetCaptureAllFrames(captureAllFrames);

                EditorGUI.BeginDisabledGroup(captureAllFrames);
                ++EditorGUI.indentLevel;


                int captureStartFrame = Math.Max(0, editorConfig.GetCaptureStartFrame());
                int captureEndFrame   = editorConfig.GetCaptureEndFrame();
                if (captureEndFrame < 0)
                {
                    captureEndFrame = TimelineUtility.CalculateNumFrames(TimelineEditor.selectedClip);
                }

                editorConfig.SetCaptureStartFrame(EditorGUILayout.IntField("From", captureStartFrame));
                editorConfig.SetCaptureEndFrame(EditorGUILayout.IntField("To", captureEndFrame));
                --EditorGUI.indentLevel;
                EditorGUI.EndDisabledGroup();

                GUILayout.Space(10);

                if (GUILayout.Button($"Update Render Cache ({updateRenderCacheShortcut})"))
                {
                    PlayableDirector director = TimelineEditor.inspectedDirector;
                    if (null == director)
                    {
                        EditorUtility.DisplayDialog("Streaming Image Sequence",
                                                    "PlayableAsset is not loaded in scene. Please load the correct scene before doing this operation.",
                                                    "Ok");
                        return;
                    }

                    //Loop time
                    EditorCoroutineUtility.StartCoroutine(UpdateRenderCacheCoroutine(director, m_asset), this);
                }
            }
        }
Esempio n. 2
0
//----------------------------------------------------------------------------------------------------------------------
        internal static IEnumerator UpdateRenderCacheCoroutine(PlayableDirector director, RenderCachePlayableAsset renderCachePlayableAsset)
        {
            Assert.IsNotNull(director);
            Assert.IsNotNull(renderCachePlayableAsset);

            PlayableFrameClipData clipData = renderCachePlayableAsset.GetBoundClipData();

            if (null == clipData)
            {
                EditorUtility.DisplayDialog("Streaming Image Sequence",
                                            "RenderCachePlayableAsset is not ready",
                                            "Ok");
                yield break;
            }

            TrackAsset         track          = renderCachePlayableAsset.GetBoundClipData().GetOwner().GetParentTrack();
            BaseRenderCapturer renderCapturer = director.GetGenericBinding(track) as BaseRenderCapturer;

            if (null == renderCapturer)
            {
                EditorUtility.DisplayDialog("Streaming Image Sequence",
                                            "Please bind an appropriate RenderCapturer component to the track.",
                                            "Ok");
                yield break;
            }

            //Check output folder
            string outputFolder = renderCachePlayableAsset.GetFolder();

            if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder))
            {
                EditorUtility.DisplayDialog("Streaming Image Sequence",
                                            "Invalid output folder",
                                            "Ok");
                yield break;
            }

            //Check if we can capture
            bool canCapture = renderCapturer.CanCaptureV();

            if (!canCapture)
            {
                EditorUtility.DisplayDialog("Streaming Image Sequence",
                                            renderCapturer.GetLastErrorMessage(),
                                            "Ok");
                yield break;
            }

            //begin capture
            IEnumerator beginCapture = renderCapturer.BeginCaptureV();

            while (beginCapture.MoveNext())
            {
                yield return(beginCapture.Current);
            }

            //Show progress in game view
            Texture capturerTex = renderCapturer.GetInternalTexture();
            RenderCachePlayableAssetEditorConfig editorConfig = renderCachePlayableAsset.GetEditorConfig();
            BaseTextureBlitter blitter         = CreateBlitter(capturerTex);
            Material           blitToScreenMat = renderCapturer.GetOrCreateBlitToScreenEditorMaterialV();

            if (!blitToScreenMat.IsNullRef())
            {
                blitToScreenMat.SetColor(m_bgColorProperty, editorConfig.GetUpdateBGColor());
                blitter.SetBlitMaterial(blitToScreenMat);
            }

            GameObject blitterGO = blitter.gameObject;



            TimelineClip timelineClip = clipData.GetOwner();
            double       timePerFrame = 1.0f / track.timelineAsset.editorSettings.GetFPS();

            //initial calculation of loop vars
            bool captureAllFrames = editorConfig.GetCaptureAllFrames();
            int  fileCounter      = 0;
            int  numFiles         = (int)Math.Ceiling(timelineClip.duration / timePerFrame) + 1;
            int  numDigits        = MathUtility.GetNumDigits(numFiles);

            if (!captureAllFrames)
            {
                fileCounter = editorConfig.GetCaptureStartFrame();
                numFiles    = (editorConfig.GetCaptureEndFrame() - fileCounter) + 1;
                if (numFiles <= 0)
                {
                    EditorUtility.DisplayDialog("Streaming Image Sequence", "Invalid Start/End Frame Settings", "Ok");
                    yield break;
                }
            }
            int captureStartFrame = fileCounter;

            string prefix = $"{timelineClip.displayName}_";
            List <WatchedFileInfo> imageFiles = new List <WatchedFileInfo>(numFiles);

            //Store old files that has the same pattern
            string[]         existingFiles = Directory.GetFiles(outputFolder, $"*.png");
            HashSet <string> filesToDelete = new HashSet <string>(existingFiles);

            RenderCacheOutputFormat outputFormat = renderCachePlayableAsset.GetOutputFormat();
            string outputExt = null;

            switch (outputFormat)
            {
            case RenderCacheOutputFormat.EXR: outputExt = "exr"; break;

            default:                          outputExt = "png"; break;;
            }

            bool cancelled = false;

            while (!cancelled)
            {
                //Always recalculate from start to avoid floating point errors
                double directorTime = timelineClip.start + (fileCounter * timePerFrame);
                if (directorTime > timelineClip.end)
                {
                    break;
                }

                if (!captureAllFrames && fileCounter > editorConfig.GetCaptureEndFrame())
                {
                    break;
                }

                string fileName       = $"{prefix}{fileCounter.ToString($"D{numDigits}")}.{outputExt}";
                string outputFilePath = Path.Combine(outputFolder, fileName);

                SISPlayableFrame playableFrame = clipData.GetPlayableFrame(fileCounter);
                bool             captureFrame  = (!clipData.AreFrameMarkersRequested() || //if markers are not requested, capture
                                                  !File.Exists(outputFilePath) || //if file doesn't exist, capture
                                                  (null != playableFrame && playableFrame.IsUsed() && !playableFrame.IsLocked())
                                                  );

                if (filesToDelete.Contains(outputFilePath))
                {
                    filesToDelete.Remove(outputFilePath);
                }


                if (captureFrame)
                {
                    SetDirectorTime(director, directorTime);

                    //Need at least two frames in order to wait for the TimelineWindow to be updated ?
                    yield return(null);

                    yield return(null);

                    yield return(null);

                    //Unload texture because it may be overwritten
                    StreamingImageSequencePlugin.UnloadImageAndNotify(outputFilePath);
                    renderCapturer.CaptureToFile(outputFilePath, outputFormat);
                }
                Assert.IsTrue(File.Exists(outputFilePath));
                FileInfo fileInfo = new FileInfo(outputFilePath);

                imageFiles.Add(new WatchedFileInfo(fileName, fileInfo.Length));

                ++fileCounter;
                cancelled = EditorUtility.DisplayCancelableProgressBar(
                    "StreamingImageSequence", "Caching render results", ((float)(fileCounter - captureStartFrame) / numFiles));
            }

            if (!cancelled)
            {
                //Delete old files
                if (AssetDatabase.IsValidFolder(outputFolder))
                {
                    foreach (string oldFile in filesToDelete)
                    {
                        AssetDatabase.DeleteAsset(oldFile);
                    }
                }
                else
                {
                    foreach (string oldFile in filesToDelete)
                    {
                        File.Delete(oldFile);
                    }
                }
            }

            //Notify
            FolderContentsChangedNotifier.GetInstance().Notify(outputFolder);

            //Cleanup
            EditorUtility.ClearProgressBar();
            renderCapturer.EndCaptureV();
            ObjectUtility.Destroy(blitterGO);
            AssetDatabase.Refresh();
            renderCachePlayableAsset.Reload();;



            yield return(null);
        }