Browse Source

Ignore invisible frames

Krzysztof Krysiński 4 months ago
parent
commit
82d11c75bd

+ 1 - 1
src/PixiEditor/Models/Files/VideoFileType.cs

@@ -21,7 +21,7 @@ internal abstract class VideoFileType : IoFileType
         job?.Report(0, new LocalizedString("WARMING_UP"));
         job?.Report(0, new LocalizedString("WARMING_UP"));
 
 
         int frameRendered = 0;
         int frameRendered = 0;
-        int totalFrames = document.AnimationDataViewModel.FramesCount;
+        int totalFrames = document.AnimationDataViewModel.GetVisibleFramesCount();
 
 
         document.RenderFrames(frames, surface =>
         document.RenderFrames(frames, surface =>
         {
         {

+ 18 - 0
src/PixiEditor/Models/Rendering/SceneRenderer.cs

@@ -25,6 +25,7 @@ internal class SceneRenderer
     private bool lastHighResRendering = true;
     private bool lastHighResRendering = true;
     private int lastGraphCacheHash = -1;
     private int lastGraphCacheHash = -1;
     private KeyFrameTime lastFrameTime;
     private KeyFrameTime lastFrameTime;
+    private Dictionary<Guid, bool> lastFramesVisibility = new();
 
 
     public SceneRenderer(IReadOnlyDocument trackerDocument, IDocument documentViewModel)
     public SceneRenderer(IReadOnlyDocument trackerDocument, IDocument documentViewModel)
     {
     {
@@ -138,6 +139,23 @@ internal class SceneRenderer
             return true;
             return true;
         }
         }
 
 
+        foreach (var frame in DocumentViewModel.AnimationHandler.KeyFrames)
+        {
+            if (lastFramesVisibility.TryGetValue(frame.Id, out var lastVisibility))
+            {
+                if (frame.IsVisible != lastVisibility)
+                {
+                    lastFramesVisibility[frame.Id] = frame.IsVisible;
+                    return true;
+                }
+            }
+            else
+            {
+                lastFramesVisibility[frame.Id] = frame.IsVisible;
+                return true;
+            }
+        }
+
         if (!renderInDocumentSize)
         if (!renderInDocumentSize)
         {
         {
             double lengthDiff = target.LocalClipBounds.Size.Length - cachedTexture.DrawingSurface.LocalClipBounds.Size.Length;
             double lengthDiff = target.LocalClipBounds.Size.Length - cachedTexture.DrawingSurface.LocalClipBounds.Size.Length;

+ 15 - 0
src/PixiEditor/ViewModels/Document/AnimationDataViewModel.cs

@@ -421,4 +421,19 @@ internal class AnimationDataViewModel : ObservableObject, IAnimationHandler
         this.keyFrames = new KeyFrameCollection(layerKeyFrames);
         this.keyFrames = new KeyFrameCollection(layerKeyFrames);
         OnPropertyChanged(nameof(KeyFrames));
         OnPropertyChanged(nameof(KeyFrames));
     }
     }
+
+    public int GetFirstVisibleFrame()
+    {
+        return keyFrames.Count > 0 ? keyFrames.Where(x => x.IsVisible).Min(x => x.StartFrameBindable) : 0;
+    }
+
+    public int GetLastVisibleFrame()
+    {
+        return keyFrames.Count > 0 ? keyFrames.Where(x => x.IsVisible).Max(x => x.StartFrameBindable + x.DurationBindable) : 0;
+    }
+
+    public int GetVisibleFramesCount()
+    {
+        return GetLastVisibleFrame() - GetFirstVisibleFrame();
+    }
 }
 }

+ 7 - 7
src/PixiEditor/ViewModels/Document/DocumentViewModel.cs

@@ -978,8 +978,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         if (token.IsCancellationRequested)
         if (token.IsCancellationRequested)
             return [];
             return [];
 
 
-        int firstFrame = AnimationDataViewModel.FirstFrame;
-        int lastFrame = AnimationDataViewModel.LastFrame;
+        int firstFrame = AnimationDataViewModel.GetFirstVisibleFrame();
+        int lastFrame = AnimationDataViewModel.GetLastVisibleFrame();
 
 
         int framesCount = lastFrame - firstFrame;
         int framesCount = lastFrame - firstFrame;
 
 
@@ -1021,8 +1021,8 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
         if (AnimationDataViewModel.KeyFrames.Count == 0)
         if (AnimationDataViewModel.KeyFrames.Count == 0)
             return;
             return;
 
 
-        int firstFrame = AnimationDataViewModel.FirstFrame;
-        int framesCount = AnimationDataViewModel.FramesCount;
+        int firstFrame = AnimationDataViewModel.GetFirstVisibleFrame();
+        int framesCount = AnimationDataViewModel.GetLastVisibleFrame();
         int lastFrame = firstFrame + framesCount;
         int lastFrame = firstFrame + framesCount;
 
 
         int activeFrame = AnimationDataViewModel.ActiveFrameBindable;
         int activeFrame = AnimationDataViewModel.ActiveFrameBindable;
@@ -1049,12 +1049,12 @@ internal partial class DocumentViewModel : PixiObservableObject, IDocument
     {
     {
         var keyFrames = AnimationDataViewModel.KeyFrames;
         var keyFrames = AnimationDataViewModel.KeyFrames;
         int firstFrame = 0;
         int firstFrame = 0;
-        int lastFrame = AnimationDataViewModel.FramesCount;
+        int lastFrame = AnimationDataViewModel.GetVisibleFramesCount();
 
 
         if (keyFrames.Count > 0)
         if (keyFrames.Count > 0)
         {
         {
-            firstFrame = keyFrames.Min(x => x.StartFrameBindable);
-            lastFrame = keyFrames.Max(x => x.StartFrameBindable + x.DurationBindable);
+            firstFrame = AnimationDataViewModel.GetFirstVisibleFrame();
+            lastFrame = AnimationDataViewModel.GetLastVisibleFrame();
         }
         }
 
 
         for (int i = firstFrame; i < lastFrame; i++)
         for (int i = firstFrame; i < lastFrame; i++)

+ 2 - 0
src/PixiEditor/Views/Dialogs/ExportFilePopup.axaml

@@ -44,9 +44,11 @@
                             </Grid.RowDefinitions>
                             </Grid.RowDefinitions>
                             <TextBlock ui1:Translator.Key="ROWS" Grid.Row="0" Grid.Column="0"/>
                             <TextBlock ui1:Translator.Key="ROWS" Grid.Row="0" Grid.Column="0"/>
                             <input:NumberInput Min="0" Width="50" Grid.Column="1" Grid.Row="0"
                             <input:NumberInput Min="0" Width="50" Grid.Column="1" Grid.Row="0"
+                                               Decimals="0"
                                                Value="{Binding ElementName=saveFilePopup, Path=SpriteSheetRows, Mode=TwoWay}" />
                                                Value="{Binding ElementName=saveFilePopup, Path=SpriteSheetRows, Mode=TwoWay}" />
                             <TextBlock ui1:Translator.Key="COLUMNS" Grid.Row="1" Grid.Column="0"/>
                             <TextBlock ui1:Translator.Key="COLUMNS" Grid.Row="1" Grid.Column="0"/>
                             <input:NumberInput Min="0" Width="50" Grid.Column="1" Grid.Row="1"
                             <input:NumberInput Min="0" Width="50" Grid.Column="1" Grid.Row="1"
+                                               Decimals="0"
                                                Value="{Binding ElementName=saveFilePopup, Path=SpriteSheetColumns, Mode=TwoWay}" />
                                                Value="{Binding ElementName=saveFilePopup, Path=SpriteSheetColumns, Mode=TwoWay}" />
                         </Grid>
                         </Grid>
                     </TabItem>
                     </TabItem>

+ 1 - 1
src/PixiEditor/Views/Dialogs/ExportFilePopup.axaml.cs

@@ -178,7 +178,7 @@ internal partial class ExportFilePopup : PixiEditorPopup
         };
         };
         videoPreviewTimer.Tick += OnVideoPreviewTimerOnTick;
         videoPreviewTimer.Tick += OnVideoPreviewTimerOnTick;
 
 
-        int framesCount = document.AnimationDataViewModel.FramesCount;
+        int framesCount = document.AnimationDataViewModel.GetVisibleFramesCount();
 
 
         var (rows, columns) = SpriteSheetUtility.CalculateGridDimensionsAuto(framesCount);
         var (rows, columns) = SpriteSheetUtility.CalculateGridDimensionsAuto(framesCount);
         SpriteSheetColumns = columns;
         SpriteSheetColumns = columns;