private void Tick() { switch (_state) { case States.Warmup: _warmUpTimeLeft -= _dt; if (_warmUpTimeLeft <= 0.0f) { // Render first frame _player.Play(); if (!_player.IsPlaying) { Editor.LogError("Scene Animation Player failed to start playing."); CancelRendering(); } _warmUpTimeLeft = -1; _state = States.Render; } break; case States.Update: // Update scene animation with a fixed delta-time if (!_player.IsStopped) { var speed = _player.Speed * (_window?._timeline.Player?.Speed ?? 1.0f); if (speed <= 0.001f) { Editor.LogError("Scene Animation Player speed was nearly zero. Cannot continue rendering."); CancelRendering(); break; } var dt = _dt * speed; _player.Tick(dt); _animationFrame++; Editor.Log("Tick anim by " + dt + " to frame " + _animationFrame + " into time " + _player.Time); _progress.Update((_player.Time - _options.StartTime) / (_options.EndTime - _options.StartTime), _animationFrame); } if (_player.IsStopped || _player.Time >= _options.EndTime) { // End rendering but perform remaining copies of the staging textures so all data is captured (from GPU to CPU) _state = States.Staging; break; } // Now wait for the next frame to be rendered _state = States.Render; break; } }
private void StartRendering() { if (_isRendering) { return; } var editor = Editor.Instance; // Check if save the asset before rendering if (_window.IsEdited) { var result = MessageBox.Show("Save scene animation asset to file before rendering?", "Save?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result == DialogResult.Yes) { _window.Save(); } else if (result != DialogResult.No) { return; } } // Update UI _isRendering = true; _presenter.Panel.Enabled = false; _presenter.BuildLayoutOnUpdate(); // Start rendering Editor.Log("Starting scene animation rendering " + _options.Animation); _dt = 1.0f / _options.FrameRate; _player = new SceneAnimationPlayer { Animation = _options.Animation, HideFlags = HideFlags.FullyHidden, RestoreStateOnStop = true, PlayOnStart = false, RandomStartTime = false, StartTime = _options.StartTime, UpdateMode = SceneAnimationPlayer.UpdateModes.Manual, }; FlaxEngine.Scripting.Update += Tick; _wasGamePaused = Time.GamePaused; Time.GamePaused = false; Time.SetFixedDeltaTime(true, _dt); Time.UpdateFPS = Time.DrawFPS = _options.FrameRate; if (!Editor.IsPlayMode) { Time.PhysicsFPS = 0; } Level.SpawnActor(_player); var gameWin = editor.Windows.GameWin; var resolution = _options.GetResolution(); gameWin.Viewport.CustomResolution = resolution; gameWin.Viewport.BackgroundColor = Color.Black; gameWin.Viewport.KeepAspectRatio = true; gameWin.Viewport.Task.PostRender += OnPostRender; if (!gameWin.Visible) { gameWin.Show(); } else if (!gameWin.IsFocused) { gameWin.Focus(); } _gameWindow = gameWin; _warmUpTimeLeft = _options.WarmUpTime; _animationFrame = 0; var stagingTextureDesc = GPUTextureDescription.New2D(resolution.X, resolution.Y, gameWin.Viewport.Task.Output.Format, GPUTextureFlags.None); stagingTextureDesc.Usage = GPUResourceUsage.StagingReadback; for (int i = 0; i < _stagingTextures.Length; i++) { _stagingTextures[i].Texture = new GPUTexture(); _stagingTextures[i].Texture.Init(ref stagingTextureDesc); _stagingTextures[i].AnimationFrame = -1; _stagingTextures[i].TaskFrame = -1; } _player.Play(); if (!_player.IsPlaying) { Editor.LogError("Scene Animation Player failed to start playing."); CancelRendering(); return; } if (_warmUpTimeLeft > 0.0f) { // Start warmup time _player.Tick(0.0f); _player.Pause(); _state = States.Warmup; } else { // Render first frame _state = States.Render; } if (!Editor.IsPlayMode) { _editorState = new RenderEditorState(editor, this); editor.StateMachine.AddState(_editorState); editor.StateMachine.GoToState(_editorState); } _progress = new RenderProgress(); editor.ProgressReporting.RegisterHandler(_progress); _progress.Start(); }