浏览代码

Renamed Frame Processor to Processing Node

/main
Thomas ICHÉ 5 年前
当前提交
baf245a1
共有 20 个文件被更改,包括 466 次插入466 次删除
  1. 22
      ImageSequencer/Editor/FilterPopup/ProcessorDataProvider.cs
  2. 16
      ImageSequencer/Editor/ImageSequencer.Export.cs
  3. 46
      ImageSequencer/Editor/ImageSequencer.GUI.cs
  4. 26
      ImageSequencer/Editor/ImageSequencer.InputFrames.cs
  5. 68
      ImageSequencer/Editor/ImageSequencer.Processors.cs
  6. 66
      ImageSequencer/Editor/ImageSequencer.cs
  7. 10
      ImageSequencer/Editor/ImageSequencerCanvas.cs
  8. 22
      ImageSequencer/Editor/ProcessingFrame.cs
  9. 34
      ImageSequencer/Editor/ProcessingFrameSequence.cs
  10. 4
      ImageSequencer/Editor/Serialization/ProcessorBase.cs
  11. 2
      ImageSequencer/Editor/Serialization/Processors/CropProcessor.cs
  12. 24
      ImageSequencer/Editor/ProcessingNode.cs
  13. 157
      ImageSequencer/Editor/ProcessingNodeStack.Serialization.cs
  14. 139
      ImageSequencer/Editor/ProcessingNodeStack.cs
  15. 157
      ImageSequencer/Editor/FrameProcessorStack.Serialization.cs
  16. 139
      ImageSequencer/Editor/FrameProcessorStack.cs
  17. 0
      /ImageSequencer/Editor/ProcessingNode.cs.meta
  18. 0
      /ImageSequencer/Editor/ProcessingNodeStack.Serialization.cs.meta
  19. 0
      /ImageSequencer/Editor/ProcessingNodeStack.cs.meta
  20. 0
      /ImageSequencer/Editor/ProcessingNode.cs

22
ImageSequencer/Editor/FilterPopup/ProcessorDataProvider.cs


{
internal class ProcessorDataProvider : IProvider
{
private Dictionary<Type, ProcessorAttribute> m_dataSource;
private FrameProcessorStack m_processorStack;
private Dictionary<Type, ProcessorAttribute> m_DataSource;
private ProcessingNodeStack m_ProcessingNodeStack;
private ImageSequence m_CurrentAsset;
public class ProcessorElement : FilterPopupWindow.Element

}
}
internal ProcessorDataProvider(FrameProcessorStack stack, ImageSequence asset)
internal ProcessorDataProvider(ProcessingNodeStack stack, ImageSequence asset)
m_dataSource = stack.settingsDefinitions;
m_processorStack = stack;
m_DataSource = stack.settingsDefinitions;
m_ProcessingNodeStack = stack;
m_CurrentAsset = asset;
}

var processors = m_dataSource.ToList();
var processors = m_DataSource.ToList();
processors.Sort((processorA, processorB) => {
int res = processorA.Value.category.CompareTo(processorB.Value.category);
return res != 0 ? res : processorA.Value.name.CompareTo(processorB.Value.name);

// Add Element
Undo.RecordObject(m_CurrentAsset, "Add Processor");
FrameProcessor processor = null;
ProcessingNode processor = null;
ProcessorAttribute attribute = m_processorStack.settingsDefinitions[settingType];
ProcessorAttribute attribute = m_ProcessingNodeStack.settingsDefinitions[settingType];
processor = (FrameProcessor)Activator.CreateInstance(typeof(FrameProcessor), m_processorStack, info);
processor = (ProcessingNode)Activator.CreateInstance(typeof(ProcessingNode), m_ProcessingNodeStack, info);
m_processorStack.AddProcessor(processor, m_CurrentAsset);
m_processorStack.InvalidateAll();
m_ProcessingNodeStack.AddProcessor(processor, m_CurrentAsset);
m_ProcessingNodeStack.InvalidateAll();
}
}

16
ImageSequencer/Editor/ImageSequencer.Export.cs


string title = "Save Texture, use # for frame numbering.";
string defaultFileName, extension;
int count = m_processorStack.outputSequence.frames.Count;
int numU = m_processorStack.outputSequence.numU;
int numV = m_processorStack.outputSequence.numV;
int count = m_ProcessingNodeStack.outputSequence.frames.Count;
int numU = m_ProcessingNodeStack.outputSequence.numU;
int numV = m_ProcessingNodeStack.outputSequence.numV;
string defaultDir = Path.GetDirectoryName(AssetDatabase.GetAssetPath(m_CurrentAsset));

Debug.LogWarning("VFX Toolbox Warning : Saving a texture outside the project's scope. Import Settings will not be applied");
}
int frameCount = m_processorStack.outputSequence.length;
int frameCount = m_ProcessingNodeStack.outputSequence.length;
if(frameCount > 1 && !Path.GetFileNameWithoutExtension(path).Contains("#"))
{

try
{
int i = 1;
foreach (ProcessingFrame frame in m_processorStack.outputSequence.frames)
foreach (ProcessingFrame frame in m_ProcessingNodeStack.outputSequence.frames)
{
if(VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Exporting Frame #" + i + "/" + frameCount, (float)i / frameCount, 0, true))
{

case ImageSequence.DataContents.Sprite:
importer.textureType = TextureImporterType.Sprite;
importer.spriteImportMode = SpriteImportMode.Multiple;
importer.spritesheet = GetSpriteMetaData(frame, m_processorStack.outputSequence.numU, m_processorStack.outputSequence.numV );
importer.spritesheet = GetSpriteMetaData(frame, m_ProcessingNodeStack.outputSequence.numU, m_ProcessingNodeStack.outputSequence.numV );
break;
}
importer.mipmapEnabled = m_CurrentAsset.exportSettings.generateMipMaps;

{
alphaImporter.textureType = TextureImporterType.Sprite;
alphaImporter.spriteImportMode = SpriteImportMode.Multiple;
alphaImporter.spritesheet = GetSpriteMetaData(frame, m_processorStack.outputSequence.numU, m_processorStack.outputSequence.numV);
alphaImporter.spritesheet = GetSpriteMetaData(frame, m_ProcessingNodeStack.outputSequence.numU, m_ProcessingNodeStack.outputSequence.numV);
alphaImporter.alphaSource = TextureImporterAlphaSource.None;
}
else

private void UpdateExportedAssets()
{
if (ExportToFile(true) != "")
m_CurrentAsset.exportSettings.frameCount = (ushort)m_processorStack.outputSequence.frames.Count;
m_CurrentAsset.exportSettings.frameCount = (ushort)m_ProcessingNodeStack.outputSequence.frames.Count;
else
m_CurrentAsset.exportSettings.frameCount = 0;
}

46
ImageSequencer/Editor/ImageSequencer.GUI.cs


Invalidate();
m_NeedRedraw = false;
}
else if((m_AutoCook && m_CurrentProcessor != null))
else if((m_AutoCook && m_CurrentProcessingNode != null))
m_CurrentProcessor.RequestProcessOneFrame(previewCanvas.currentFrameIndex);
m_CurrentProcessingNode.RequestProcessOneFrame(previewCanvas.currentFrameIndex);
Invalidate();
}
}

private void DrawTabbedPanelSelector()
{
SidePanelMode prevMode = m_SidePanelViewMode;
bool hasInputFrames = m_processorStack.inputSequence.frames.Count > 0;
bool hasInputFrames = m_ProcessingNodeStack.inputSequence.frames.Count > 0;
SidePanelMode newMode = (SidePanelMode)VFXToolboxGUIUtility.TabbedButtonsGUILayout(
(int)prevMode,
new string[] { "Input Frames", "Processors", "Export"},

{
case SidePanelMode.InputFrames:
m_PreviewCanvas.sequence = m_processorStack.inputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
break;

m_PreviewCanvas.sequence = m_LockedPreviewProcessor.OutputSequence;
else
{
if(m_CurrentProcessor != null)
m_PreviewCanvas.sequence = m_CurrentProcessor.OutputSequence;
if(m_CurrentProcessingNode != null)
m_PreviewCanvas.sequence = m_CurrentProcessingNode.OutputSequence;
if (m_processorStack.processors.Count > 0)
m_PreviewCanvas.sequence = m_processorStack.processors[m_processorStack.processors.Count - 1].OutputSequence;
if (m_ProcessingNodeStack.nodes.Count > 0)
m_PreviewCanvas.sequence = m_ProcessingNodeStack.nodes[m_ProcessingNodeStack.nodes.Count - 1].OutputSequence;
m_PreviewCanvas.sequence = m_processorStack.inputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
}
}

m_PreviewCanvas.sequence = m_processorStack.outputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.outputSequence;
break;
}

GUILayout.Space(8);
m_InputFramesReorderableList.DoLayoutList();
if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && m_processorStack.inputSequence.length > 0)
if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && m_ProcessingNodeStack.inputSequence.length > 0)
{
RemoveInputFrame(m_InputFramesReorderableList);
Event.current.Use();

{
// Delete everything
Undo.RecordObject(m_CurrentAsset, "Clear All Processors");
m_processorStack.RemoveAllProcessors(m_CurrentAsset);
m_ProcessingNodeStack.RemoveAllProcessors(m_CurrentAsset);
m_CurrentProcessor = null;
m_CurrentProcessingNode = null;
m_PreviewCanvas.sequence = m_processorStack.inputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
EditorUtility.SetDirty(m_CurrentAsset);
// Request Repaint
Invalidate();

GUILayout.Space(10);
// Draw inspector and Invalidates whatever needs to.
for(int i = 0; i < m_processorStack.processors.Count; i++)
for(int i = 0; i < m_ProcessingNodeStack.nodes.Count; i++)
bool changed = m_processorStack.processors[i].OnSidePanelGUI(m_CurrentAsset,i);
bool changed = m_ProcessingNodeStack.nodes[i].OnSidePanelGUI(m_CurrentAsset,i);
m_processorStack.processors[i].Invalidate();
m_ProcessingNodeStack.nodes[i].Invalidate();
UpdateViewport();
}
m_Dirty = m_Dirty || changed;

// Handle final keyboard events (delete)
if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && m_processorStack.processors.Count > 0)
if(Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Delete && m_ProcessingNodeStack.nodes.Count > 0)
{
MenuRemoveProcessor(m_ProcessorsReorderableList);
Event.current.Use();

private void DrawExportPanelContent()
{
int length = m_processorStack.outputSequence.length;
int length = m_ProcessingNodeStack.outputSequence.length;
if(length > 0)
{

m_CurrentAsset.exportSettings.dataContents = (ImageSequence.DataContents)EditorGUILayout.EnumPopup(VFXToolboxGUIUtility.Get("Import as|Sets the importer mode"), m_CurrentAsset.exportSettings.dataContents);
if(m_CurrentAsset.exportSettings.dataContents == ImageSequence.DataContents.Sprite)
{
FrameProcessor p = m_processorStack.processors[m_processorStack.processors.Count - 1];
if (((float)p.OutputWidth % p.NumU) != 0 || ((float)p.OutputHeight % p.NumV) != 0)
EditorGUILayout.HelpBox("Warning : texture size is not a multiplier of rows ("+p.NumU+") and columns ("+p.NumV+") count, this will lead to incorrect rendering of the sprite animation", MessageType.Warning);
ProcessingNode n = m_ProcessingNodeStack.nodes[m_ProcessingNodeStack.nodes.Count - 1];
if (((float)n.OutputWidth % n.NumU) != 0 || ((float)n.OutputHeight % n.NumV) != 0)
EditorGUILayout.HelpBox("Warning : texture size is not a multiplier of rows ("+n.NumU+") and columns ("+n.NumV+") count, this will lead to incorrect rendering of the sprite animation", MessageType.Warning);
}
switch(m_CurrentAsset.exportSettings.dataContents)

if (fileName != "")
{
m_CurrentAsset.exportSettings.fileName = fileName;
m_CurrentAsset.exportSettings.frameCount = (ushort)m_processorStack.outputSequence.frames.Count;
m_CurrentAsset.exportSettings.frameCount = (ushort)m_ProcessingNodeStack.outputSequence.frames.Count;
}
}
// Export Again

26
ImageSequencer/Editor/ImageSequencer.InputFrames.cs


foreach (string s in names)
{
Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(s);
if(t != null) m_processorStack.inputSequence.frames.Add(new ProcessingFrame(t));
if(t != null) m_ProcessingNodeStack.inputSequence.frames.Add(new ProcessingFrame(t));
m_processorStack.InvalidateAll();
m_ProcessingNodeStack.InvalidateAll();
m_processorStack.SyncFramesToAsset(m_CurrentAsset);
m_ProcessingNodeStack.SyncFramesToAsset(m_CurrentAsset);
UpdateInputTexturesHash();
}
}

{
Undo.RecordObject(m_CurrentAsset, "Reorder Input Frames");
UpdateViewport();
m_processorStack.SyncFramesToAsset(m_CurrentAsset);
m_ProcessingNodeStack.SyncFramesToAsset(m_CurrentAsset);
UpdateInputTexturesHash();
}

}
}
Undo.RecordObject(m_CurrentAsset, "Remove Input Frames");
m_processorStack.SyncFramesToAsset(m_CurrentAsset);
m_ProcessingNodeStack.SyncFramesToAsset(m_CurrentAsset);
if(m_processorStack.inputSequence.length > 0)
m_processorStack.InvalidateAll();
if(m_ProcessingNodeStack.inputSequence.length > 0)
m_ProcessingNodeStack.InvalidateAll();
}
public void DrawInputFrameRListElement(Rect rect, int index, bool isActive, bool isFocused)

{
Undo.RecordObject(m_CurrentAsset, "Clear All Input Frames");
// Remove frames and update hash
m_processorStack.RemoveAllInputFrames(m_CurrentAsset);
m_processorStack.SyncFramesToAsset(m_CurrentAsset);
m_ProcessingNodeStack.RemoveAllInputFrames(m_CurrentAsset);
m_ProcessingNodeStack.SyncFramesToAsset(m_CurrentAsset);
m_CurrentProcessor = null;
m_CurrentProcessingNode = null;
m_PreviewCanvas.sequence = m_processorStack.inputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
// Request an update
Invalidate();
RefreshCanvas();

{
Undo.RecordObject(m_CurrentAsset, "Sort All Input Frames");
// Sort frames and update hash
m_processorStack.SortAllInputFrames(m_CurrentAsset);
m_ProcessingNodeStack.SortAllInputFrames(m_CurrentAsset);
m_InputFramesHashCode = GetInputTexturesHashCode();
LoadAsset(m_CurrentAsset);

{
Undo.RecordObject(m_CurrentAsset, "Reverse Input Frames Order");
// Inverse frame order and update hash
m_processorStack.ReverseAllInputFrames(m_CurrentAsset);
m_ProcessingNodeStack.ReverseAllInputFrames(m_CurrentAsset);
m_InputFramesHashCode = GetInputTexturesHashCode();
LoadAsset(m_CurrentAsset);

68
ImageSequencer/Editor/ImageSequencer.Processors.cs


{
if(m_ProcessorDataProvider == null)
{
m_ProcessorDataProvider = new ProcessorDataProvider(m_processorStack, m_CurrentAsset);
m_ProcessorDataProvider = new ProcessorDataProvider(m_ProcessingNodeStack, m_CurrentAsset);
}
FilterPopupWindow.Show(Event.current.mousePosition, m_ProcessorDataProvider);

if (list.count > 0 && list.index != -1)
{
SetCurrentFrameProcessor(m_processorStack.processors[list.index], false);
SetCurrentFrameProcessor(m_ProcessingNodeStack.nodes[list.index], false);
}
else
SetCurrentFrameProcessor(null, false);

{
Undo.RecordObject(m_CurrentAsset, "Reorder Processors");
m_processorStack.ReorderProcessors(m_CurrentAsset);
m_processorStack.InvalidateAll();
m_ProcessingNodeStack.ReorderProcessors(m_CurrentAsset);
m_ProcessingNodeStack.InvalidateAll();
m_CurrentAsset.editSettings.lockedProcessor = m_processorStack.processors.IndexOf(m_LockedPreviewProcessor);
m_CurrentAsset.editSettings.lockedProcessor = m_ProcessingNodeStack.nodes.IndexOf(m_LockedPreviewProcessor);
EditorUtility.SetDirty(m_CurrentAsset);
}

{
int idx = list.index;
Undo.RecordObject(m_CurrentAsset, "Remove Processor : " + m_processorStack.processors[idx].GetName());
m_processorStack.RemoveProcessor(idx,m_CurrentAsset);
Undo.RecordObject(m_CurrentAsset, "Remove Processor : " + m_ProcessingNodeStack.nodes[idx].GetName());
m_ProcessingNodeStack.RemoveProcessor(idx,m_CurrentAsset);
// If was locked, unlock beforehand
if (idx == m_CurrentAsset.editSettings.lockedProcessor)

if(m_processorStack.processors.Count > 0)
if(m_ProcessingNodeStack.nodes.Count > 0)
int newIdx = Mathf.Clamp(idx - 1, 0, m_processorStack.processors.Count - 1);
int newIdx = Mathf.Clamp(idx - 1, 0, m_ProcessingNodeStack.nodes.Count - 1);
SetCurrentFrameProcessor(m_processorStack.processors[newIdx], false);
SetCurrentFrameProcessor(m_ProcessingNodeStack.nodes[newIdx], false);
list.index = newIdx;
}
else

}
previewCanvas.currentFrameIndex = 0;
m_processorStack.InvalidateAll();
m_ProcessingNodeStack.InvalidateAll();
if(m_CurrentProcessor != null)
previewCanvas.sequence = m_CurrentProcessor.OutputSequence;
if(m_CurrentProcessingNode != null)
previewCanvas.sequence = m_CurrentProcessingNode.OutputSequence;
previewCanvas.sequence = m_processorStack.inputSequence;
previewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
previewCanvas.currentFrameIndex = Mathf.Clamp(previewCanvas.currentFrameIndex, 0, previewCanvas.sequence.length - 1);

public void SetCurrentFrameProcessor(FrameProcessor processor, bool wantLock)
public void SetCurrentFrameProcessor(ProcessingNode node, bool wantLock)
m_LockedPreviewProcessor = processor;
if(processor != null)
m_LockedPreviewProcessor = node;
if(node != null)
m_CurrentProcessor = processor;
m_CurrentAsset.editSettings.lockedProcessor = m_processorStack.processors.IndexOf(processor);
m_CurrentProcessingNode = node;
m_CurrentAsset.editSettings.lockedProcessor = m_ProcessingNodeStack.nodes.IndexOf(node);
m_CurrentProcessor = m_processorStack.processors[Mathf.Min(m_ProcessorsReorderableList.index, m_processorStack.processors.Count-1)];
m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[Mathf.Min(m_ProcessorsReorderableList.index, m_ProcessingNodeStack.nodes.Count-1)];
bool needChange = (m_CurrentProcessor != processor);
bool needChange = (m_CurrentProcessingNode != node);
m_CurrentProcessor = processor;
m_CurrentProcessingNode = node;
m_CurrentProcessor = m_LockedPreviewProcessor;
m_CurrentProcessingNode = m_LockedPreviewProcessor;
m_CurrentAsset.editSettings.selectedProcessor = m_processorStack.processors.IndexOf(processor);
m_CurrentAsset.editSettings.selectedProcessor = m_ProcessingNodeStack.nodes.IndexOf(node);
RefreshCanvas();
EditorUtility.SetDirty(m_CurrentAsset);
}

using (new EditorGUI.DisabledScope(true))
{
GUI.Toggle(toggle_rect, m_processorStack.processors[index].Enabled, "");
GUI.Toggle(toggle_rect, m_ProcessingNodeStack.nodes[index].Enabled, "");
GUI.Label( label_rect, string.Format("#{0} - {1} ",index+1, m_processorStack.processors[index].ToString()), VFXToolboxStyles.RListLabel);
GUI.Label( label_rect, string.Format("#{0} - {1} ",index+1, m_ProcessingNodeStack.nodes[index].ToString()), VFXToolboxStyles.RListLabel);
}

Rect view_rect = new Rect(rect.x + rect.width - 37, rect.y+2, 16, 16);
Rect lock_rect = new Rect(rect.x + rect.width - 16, rect.y+2, 16, 14);
bool enabled = GUI.Toggle(toggle_rect, m_processorStack.processors[index].Enabled,"");
if(enabled != m_processorStack.processors[index].Enabled)
bool enabled = GUI.Toggle(toggle_rect, m_ProcessingNodeStack.nodes[index].Enabled,"");
if(enabled != m_ProcessingNodeStack.nodes[index].Enabled)
m_processorStack.processors[index].Enabled = enabled;
m_processorStack.processors[index].Invalidate();
m_ProcessingNodeStack.nodes[index].Enabled = enabled;
m_ProcessingNodeStack.nodes[index].Invalidate();
GUI.Label( label_rect, string.Format("#{0} - {1} ",index+1, m_processorStack.processors[index].ToString()), VFXToolboxStyles.RListLabel);
GUI.Label( label_rect, string.Format("#{0} - {1} ",index+1, m_ProcessingNodeStack.nodes[index].ToString()), VFXToolboxStyles.RListLabel);
if((m_LockedPreviewProcessor == null && isActive) || m_processorStack.processors.IndexOf(m_LockedPreviewProcessor) == index)
if((m_LockedPreviewProcessor == null && isActive) || m_ProcessingNodeStack.nodes.IndexOf(m_LockedPreviewProcessor) == index)
bool locked = (m_LockedPreviewProcessor != null) && index == m_processorStack.processors.IndexOf(m_LockedPreviewProcessor);
bool locked = (m_LockedPreviewProcessor != null) && index == m_ProcessingNodeStack.nodes.IndexOf(m_LockedPreviewProcessor);
if(isActive || locked)
{

if(b)
SetCurrentFrameProcessor(m_processorStack.processors[index],true);
SetCurrentFrameProcessor(m_ProcessingNodeStack.nodes[index],true);
else
SetCurrentFrameProcessor(null, true);
}

66
ImageSequencer/Editor/ImageSequencer.cs


}
}
public FrameProcessor currentProcessor
public ProcessingNode currentProcessingNode
return m_CurrentProcessor;
return m_CurrentProcessingNode;
}
}

private bool m_IgnoreInheritSettings;
private ImageSequencerCanvas m_PreviewCanvas;
private FrameProcessorStack m_processorStack;
private ProcessingNodeStack m_ProcessingNodeStack;
private FrameProcessor m_CurrentProcessor;
private FrameProcessor m_LockedPreviewProcessor;
private ProcessingNode m_CurrentProcessingNode;
private ProcessingNode m_LockedPreviewProcessor;
private GraphicsDeviceType m_CurrentGraphicsAPI;
private ColorSpace m_CurrentColorSpace;

if (m_InputFramesHashCode != hash || m_CurrentAsset.inheritSettingsReference != null)
LoadAsset(m_CurrentAsset);
m_processorStack.LoadProcessorsFromAsset(m_CurrentAsset);
m_ProcessingNodeStack.LoadProcessorsFromAsset(m_CurrentAsset);
RestoreProcessorView();
if (m_CurrentAsset.inputFrameGUIDs.Count > 0)

foreach (FrameProcessor p in m_processorStack.processors)
foreach (ProcessingNode n in m_ProcessingNodeStack.nodes)
p.Refresh();
p.Invalidate();
n.Refresh();
n.Invalidate();
}
Repaint();

m_InputFramesReorderableList = null;
m_ProcessorsReorderableList = null;
m_LockedPreviewProcessor = null;
m_CurrentProcessor = null;
m_CurrentProcessingNode = null;
if(m_processorStack != null)
m_processorStack.Dispose();
if(m_ProcessingNodeStack != null)
m_ProcessingNodeStack.Dispose();
m_processorStack = new FrameProcessorStack(new ProcessingFrameSequence(null), this);
m_ProcessingNodeStack = new ProcessingNodeStack(new ProcessingFrameSequence(null), this);
m_CurrentAssetSerializedObject = new SerializedObject(m_CurrentAsset);

VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Frames", 0.333333f);
m_processorStack.LoadFramesFromAsset(m_CurrentAsset);
m_ProcessingNodeStack.LoadFramesFromAsset(m_CurrentAsset);
m_InputFramesReorderableList = new ReorderableList(m_processorStack.inputSequence.frames, typeof(Texture2D),true,false,true,true);
m_InputFramesReorderableList = new ReorderableList(m_ProcessingNodeStack.inputSequence.frames, typeof(Texture2D),true,false,true,true);
m_InputFramesReorderableList.onAddCallback = AddInputFrame;
m_InputFramesReorderableList.onRemoveCallback = RemoveInputFrame;
m_InputFramesReorderableList.onReorderCallback = ReorderInputFrame;

}
}
m_processorStack.LoadProcessorsFromAsset(inheritedSettingReference);
m_ProcessorDataProvider = new ProcessorDataProvider(m_processorStack, m_CurrentAsset);
m_ProcessingNodeStack.LoadProcessorsFromAsset(inheritedSettingReference);
m_ProcessorDataProvider = new ProcessorDataProvider(m_ProcessingNodeStack, m_CurrentAsset);
// Construct the RList
if (m_CurrentAsset.inheritSettingsReference == null)

m_ProcessorsReorderableList.onSelectCallback = MenuSelectProcessor;
}
m_PreviewCanvas.sequence = m_processorStack.inputSequence;
m_PreviewCanvas.sequence = m_ProcessingNodeStack.inputSequence;
if(m_PreviewCanvas.sequence.length > 0)
m_PreviewCanvas.currentFrameIndex = 0;
else

m_processorStack.InvalidateAll();
m_ProcessingNodeStack.InvalidateAll();
RestoreProcessorView();
EditorUtility.ClearProgressBar();

/// </summary>
public void DefaultView()
{
if (m_processorStack.processors.Count == 0 || m_processorStack.inputSequence.frames.Count == 0)
if (m_ProcessingNodeStack.nodes.Count == 0 || m_ProcessingNodeStack.inputSequence.frames.Count == 0)
{
m_SidePanelViewMode = SidePanelMode.InputFrames;
m_ProcessorsReorderableList.index = -1;

{
if(m_CurrentAsset.inheritSettingsReference != null && !m_IgnoreInheritSettings)
{
if(m_processorStack.processors.Count > 0)
if(m_ProcessingNodeStack.nodes.Count > 0)
m_CurrentProcessor = m_processorStack.processors[m_CurrentAsset.editSettings.selectedProcessor];
m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.selectedProcessor];
m_ProcessorsReorderableList.index = m_CurrentAsset.editSettings.selectedProcessor;
}
}

// index Checks
m_CurrentAsset.editSettings.lockedProcessor = Mathf.Clamp(m_CurrentAsset.editSettings.lockedProcessor, -1, m_processorStack.processors.Count - 1);
m_CurrentAsset.editSettings.selectedProcessor = Mathf.Clamp(m_CurrentAsset.editSettings.selectedProcessor, -1, m_processorStack.processors.Count - 1);
m_CurrentAsset.editSettings.lockedProcessor = Mathf.Clamp(m_CurrentAsset.editSettings.lockedProcessor, -1, m_ProcessingNodeStack.nodes.Count - 1);
m_CurrentAsset.editSettings.selectedProcessor = Mathf.Clamp(m_CurrentAsset.editSettings.selectedProcessor, -1, m_ProcessingNodeStack.nodes.Count - 1);
m_LockedPreviewProcessor = m_processorStack.processors[m_CurrentAsset.editSettings.lockedProcessor];
m_CurrentProcessor = m_processorStack.processors[m_CurrentAsset.editSettings.lockedProcessor];
m_LockedPreviewProcessor = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
}
else
m_LockedPreviewProcessor = null;

m_ProcessorsReorderableList.index = m_CurrentAsset.editSettings.selectedProcessor;
if (m_CurrentAsset.editSettings.lockedProcessor != -1)
m_CurrentProcessor = m_processorStack.processors[m_CurrentAsset.editSettings.lockedProcessor];
m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.lockedProcessor];
m_CurrentProcessor = m_processorStack.processors[m_CurrentAsset.editSettings.selectedProcessor];
m_CurrentProcessingNode = m_ProcessingNodeStack.nodes[m_CurrentAsset.editSettings.selectedProcessor];
m_processorStack.InvalidateAll();
m_ProcessingNodeStack.InvalidateAll();
RefreshCanvas();
}

if(m_CurrentGraphicsAPI != device)
{
m_CurrentGraphicsAPI = device;
if(m_processorStack != null)
m_processorStack.InvalidateAll();
if(m_ProcessingNodeStack != null)
m_ProcessingNodeStack.InvalidateAll();
Repaint();
}
ColorSpace colorSpace = QualitySettings.activeColorSpace;

if(m_processorStack != null)
m_processorStack.InvalidateAll();
if(m_ProcessingNodeStack != null)
m_ProcessingNodeStack.InvalidateAll();
}
}
}

10
ImageSequencer/Editor/ImageSequencerCanvas.cs


// Processor extra info
GUI.BeginGroup(m_Rect);
if (editor.currentProcessor != null && editor.currentProcessor.Enabled && m_bShowExtraInfo && editor.sidePanelViewMode == ImageSequencer.SidePanelMode.Processors)
editor.currentProcessor.OnCanvasGUI(this);
if (editor.currentProcessingNode != null && editor.currentProcessingNode.Enabled && m_bShowExtraInfo && editor.sidePanelViewMode == ImageSequencer.SidePanelMode.Processors)
editor.currentProcessingNode.OnCanvasGUI(this);
string procName = (editor.sidePanelViewMode == ImageSequencer.SidePanelMode.Export) ? "Export" : (sequence.processor == null ? "Input Frames" : sequence.processor.ToString());
string procName = (editor.sidePanelViewMode == ImageSequencer.SidePanelMode.Export) ? "Export" : (sequence.processingNode == null ? "Input Frames" : sequence.processingNode.ToString());
GUI.Label(new RectOffset(24,24,24,24).Remove(m_Rect), procName , styles.largeLabel);
GUI.Label(new RectOffset(24,24,64,24).Remove(m_Rect), GetDebugInfoString() , styles.label);
//EditorGUI.DrawRect(m_Rect, Color.red);

public void UpdateCanvasSequence()
{
int length;
if (sequence.processor != null)
length = sequence.processor.GetProcessorSequenceLength();
if (sequence.processingNode != null)
length = sequence.processingNode.GetProcessorSequenceLength();
else
length = sequence.length;

22
ImageSequencer/Editor/ProcessingFrame.cs


get {
if (m_Texture == null)
{
if(m_Processor == null) // For input frames, either our input asset has been deleted, or something went wrong with the meta's, let's replace by a dummy
if(m_ProcessingNode == null) // For input frames, either our input asset has been deleted, or something went wrong with the meta's, let's replace by a dummy
{
m_Texture = Missing.texture;
m_Texture.name = @"/!\ MISSING /!\";

public bool isInputFrame
{
get { return m_Processor == null; }
get { return m_ProcessingNode == null; }
}
public int mipmapCount

public bool dirty;
private Texture m_Texture;
private FrameProcessor m_Processor;
private ProcessingNode m_ProcessingNode;
m_Processor = null;
m_ProcessingNode = null;
public ProcessingFrame(FrameProcessor processor)
public ProcessingFrame(ProcessingNode node)
m_Processor = processor;
m_ProcessingNode = node;
if(texture.width != m_Processor.OutputWidth || texture.height != m_Processor.OutputHeight )
if(texture.width != m_ProcessingNode.OutputWidth || texture.height != m_ProcessingNode.OutputHeight )
{
ResetTexture();
}

{
if(m_Texture == null || (m_Processor != null && (m_Texture.width != m_Processor.OutputWidth || m_Texture.height != m_Processor.OutputHeight)))
if(m_Texture == null || (m_ProcessingNode != null && (m_Texture.width != m_ProcessingNode.OutputWidth || m_Texture.height != m_ProcessingNode.OutputHeight)))
m_Texture = new RenderTexture(m_Processor.OutputWidth, m_Processor.OutputHeight, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
m_Texture = new RenderTexture(m_ProcessingNode.OutputWidth, m_ProcessingNode.OutputHeight, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
((RenderTexture)m_Texture).autoGenerateMips = true;
}
}

if(dirty && m_Processor != null)
if(dirty && m_ProcessingNode != null)
if(m_Processor.Process(this))
if(m_ProcessingNode.Process(this))
{
dirty = false;
return true;

34
ImageSequencer/Editor/ProcessingFrameSequence.cs


{
get
{
if (m_Processor != null)
return m_Processor.NumU;
if (m_ProcessingNode != null)
return m_ProcessingNode.NumU;
else
return 1;
}

{
get
{
if (m_Processor != null)
return m_Processor.NumV;
if (m_ProcessingNode != null)
return m_ProcessingNode.NumV;
else
return 1;
}

}
}
public FrameProcessor processor
public ProcessingNode processingNode
return m_Processor;
return m_ProcessingNode;
}
}

{
if (m_Processor == null)
if (m_ProcessingNode == null)
{
if(m_Frames.Count > 0)
return m_Frames[0].texture.width;

else
{
return m_Processor.OutputWidth;
return m_ProcessingNode.OutputWidth;
}
}

{
get
{
if (m_Processor == null)
if (m_ProcessingNode == null)
{
if(m_Frames.Count > 0)
return m_Frames[0].texture.height;

else
{
return m_Processor.OutputHeight;
return m_ProcessingNode.OutputHeight;
}
}

private List<ProcessingFrame> m_Frames;
private FrameProcessor m_Processor;
private ProcessingNode m_ProcessingNode;
public ProcessingFrameSequence(FrameProcessor processor)
public ProcessingFrameSequence(ProcessingNode node)
m_Processor = processor;
m_ProcessingNode = node;
}
public void InvalidateAll()

public ProcessingFrame RequestFrame(int index)
{
if (m_Processor == null)
if (m_ProcessingNode == null)
if(m_Processor.Enabled)
if(m_ProcessingNode.Enabled)
m_Processor.UpdateSequenceLength();
m_ProcessingNode.UpdateSequenceLength();
if (m_Frames[index].dirty)
{

}
else
{
return m_Processor.InputSequence.RequestFrame(index);
return m_ProcessingNode.InputSequence.RequestFrame(index);
}
}

4
ImageSequencer/Editor/Serialization/ProcessorBase.cs


public abstract string processorName { get; }
public virtual string label => processorName;
protected FrameProcessor processor;
protected ProcessingNode processor;
public void AttachTo(FrameProcessor processor)
public void AttachTo(ProcessingNode processor)
{
this.processor = processor;
}

2
ImageSequencer/Editor/Serialization/Processors/CropProcessor.cs


ProcessingFrame f = processor.InputSequence.frames[i];
VFXToolboxGUIUtility.DisplayProgressBar("Crop processor", "Evaluating closest bound (Frame #" + i + " on " + processor.InputSequence.frames.Count + "...)", (float)i / processor.InputSequence.frames.Count);
if (processor.InputSequence.processor != null)
if (processor.InputSequence.processingNode != null)
{
f.Process();
colors = VFXToolboxUtility.ReadBack(f.texture as RenderTexture);

24
ImageSequencer/Editor/ProcessingNode.cs


namespace UnityEditor.VFXToolbox.ImageSequencer
{
internal class FrameProcessor
internal class ProcessingNode
{
public int OutputWidth
{

public ProcessingFrameSequence InputSequence
{
get { return m_ProcessorStack.GetInputSequence(this); }
get { return m_ProcessingNodeStack.GetInputSequence(this); }
}
public ProcessingFrameSequence OutputSequence
{

get { return m_ProcessorInfo; }
}
private FrameProcessorStack m_ProcessorStack;
private ProcessingNodeStack m_ProcessingNodeStack;
private ProcessingFrameSequence m_OutputSequence;
private bool m_bEnabled;

public Shader shader { get; private set; }
public Material material { get; private set; }
public bool isCurrentlyPreviewed => m_ProcessorStack.imageSequencer.previewCanvas.sequence.processor == this;
public int currentPreviewFrame => m_ProcessorStack.imageSequencer.previewCanvas.currentFrameIndex;
public int currentPreviewSequenceLength => m_ProcessorStack.imageSequencer.previewCanvas.numFrames;
public bool isCurrentlyPreviewed => m_ProcessingNodeStack.imageSequencer.previewCanvas.sequence.processingNode == this;
public int currentPreviewFrame => m_ProcessingNodeStack.imageSequencer.previewCanvas.currentFrameIndex;
public int currentPreviewSequenceLength => m_ProcessingNodeStack.imageSequencer.previewCanvas.numFrames;
public FrameProcessor(FrameProcessorStack processorStack, ProcessorInfo info)
public ProcessingNode(ProcessingNodeStack processorStack, ProcessorInfo info)
m_ProcessorStack = processorStack;
m_ProcessingNodeStack = processorStack;
processor = m_ProcessorInfo.Settings;
m_OutputSequence = new ProcessingFrameSequence(this);

}
protected int GetNumU()
{
if (InputSequence.processor == null)
if (InputSequence.processingNode == null)
if (InputSequence.processor == null)
if (InputSequence.processingNode == null)
return 1;
return InputSequence.numV;
}

SerializedObject o = new SerializedObject(m_ProcessorInfo);
o.FindProperty("Enabled").boolValue = Enabled;
o.ApplyModifiedProperties();
m_ProcessorStack.Invalidate(this);
m_ProcessingNodeStack.Invalidate(this);
bHasChanged = true;
}
return bHasChanged;

SetOutputSize(GetOutputWidth(), GetOutputHeight());
m_OutputSequence.InvalidateAll();
FrameProcessor next = m_ProcessorStack.GetNextProcessor(this);
ProcessingNode next = m_ProcessingNodeStack.GetNextProcessor(this);
if(next != null)
next.Invalidate();
}

157
ImageSequencer/Editor/ProcessingNodeStack.Serialization.cs


using UnityEngine;
using System;
using System.Reflection;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.ImageSequencer
{
internal partial class ProcessingNodeStack
{
public void AddSettingsObjectToAsset(ImageSequence asset, ScriptableObject settings)
{
AssetDatabase.AddObjectToAsset(settings,asset);
settings.hideFlags = HideFlags.HideInHierarchy;
}
public void AddProcessorInfoObjectToAsset(ImageSequence asset, ProcessorInfo info)
{
AssetDatabase.AddObjectToAsset(info,asset);
info.hideFlags = HideFlags.HideInHierarchy;
}
public void RemoveAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Clear();
m_InputSequence.frames.Clear();
EditorUtility.SetDirty(asset);
}
public void SortAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Sort((guidA,guidB) => {
return string.Compare(AssetDatabase.GUIDToAssetPath(guidA), AssetDatabase.GUIDToAssetPath(guidB));
});
EditorUtility.SetDirty(asset);
}
public void ReverseAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Reverse();
EditorUtility.SetDirty(asset);
}
public void LoadFramesFromAsset(ImageSequence asset)
{
inputSequence.frames.Clear();
if (asset.inputFrameGUIDs != null && asset.inputFrameGUIDs.Count > 0)
{
int count = asset.inputFrameGUIDs.Count;
int i = 1;
foreach (string guid in asset.inputFrameGUIDs)
{
VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Textures (" + i + "/" + count + ")", (float)i/count, 0.1f);
string path = AssetDatabase.GUIDToAssetPath(guid);
Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
if (t != null)
{
inputSequence.frames.Add(new ProcessingFrame(t));
}
else
{
inputSequence.frames.Add(ProcessingFrame.Missing);
}
i++;
}
VFXToolboxGUIUtility.ClearProgressBar();
}
}
public void SyncFramesToAsset(ImageSequence asset)
{
asset.inputFrameGUIDs.Clear();
foreach(ProcessingFrame f in inputSequence.frames)
{
asset.inputFrameGUIDs.Add(AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(f.texture)));
}
EditorUtility.SetDirty(asset);
}
public void AddProcessor(ProcessingNode node, ImageSequence asset)
{
AddProcessorInfoObjectToAsset(asset, node.ProcessorInfo);
asset.processorInfos.Add(node.ProcessorInfo);
ProcessorBase settings = node.GetSettingsAbstract();
if (settings != null)
{
AddSettingsObjectToAsset(asset, settings);
node.ProcessorInfo.Settings = settings;
}
m_ProcessingNodes.Add(node);
EditorUtility.SetDirty(asset);
}
public void RemoveAllProcessors(ImageSequence asset)
{
asset.processorInfos.Clear();
m_ProcessingNodes.Clear();
EditorUtility.SetDirty(asset);
}
public void RemoveProcessor(int index, ImageSequence asset)
{
asset.processorInfos.RemoveAt(index);
m_ProcessingNodes.RemoveAt(index);
EditorUtility.SetDirty(asset);
}
public void ReorderProcessors(ImageSequence asset)
{
if(m_ProcessingNodes.Count > 0)
{
List<ProcessingNode> old = new List<ProcessingNode>();
foreach(ProcessingNode n in m_ProcessingNodes)
{
old.Add(n);
}
m_ProcessingNodes.Clear();
foreach(ProcessorInfo info in asset.processorInfos)
{
foreach(ProcessingNode p in old)
{
if(p.ProcessorInfo.Equals(info))
{
m_ProcessingNodes.Add(p);
break;
}
}
}
EditorUtility.SetDirty(asset);
}
}
public void LoadProcessorsFromAsset(ImageSequence asset)
{
m_ProcessingNodes.Clear();
var infos = asset.processorInfos;
UpdateProcessorsFromAssembly();
// Creating Runtime
foreach(ProcessorInfo procInfo in infos)
{
var processor = (ProcessingNode)Activator.CreateInstance(typeof(ProcessingNode), this, procInfo);
m_ProcessingNodes.Add(processor);
}
}
}
}

139
ImageSequencer/Editor/ProcessingNodeStack.cs


using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.ImageSequencer
{
internal partial class ProcessingNodeStack
{
public ProcessingFrameSequence inputSequence
{
get
{
return m_InputSequence;
}
}
public ProcessingFrameSequence outputSequence
{
get
{
if (m_ProcessingNodes.Count > 0)
return m_ProcessingNodes[m_ProcessingNodes.Count - 1].OutputSequence;
else
return m_InputSequence;
}
}
public ImageSequencer imageSequencer
{
get { return m_ImageSequencer; }
}
public List<ProcessingNode> nodes
{
get
{
return m_ProcessingNodes;
}
}
private List<ProcessingNode> m_ProcessingNodes;
private ProcessingFrameSequence m_InputSequence;
private ImageSequencer m_ImageSequencer;
public ProcessingNodeStack(ProcessingFrameSequence inputSequence, ImageSequencer imageSequencer)
{
m_InputSequence = inputSequence;
m_ProcessingNodes = new List<ProcessingNode>();
m_ImageSequencer = imageSequencer;
}
public void Dispose()
{
foreach(ProcessingNode p in m_ProcessingNodes)
{
p.Dispose();
}
m_ProcessingNodes.Clear();
}
public ProcessingFrameSequence GetOutputSequence()
{
if(m_ProcessingNodes.Count > 0)
{
return m_ProcessingNodes[m_ProcessingNodes.Count - 1].OutputSequence;
}
else
{
return inputSequence;
}
}
public ProcessingFrameSequence GetInputSequence(ProcessingNode processor)
{
int index = m_ProcessingNodes.IndexOf(processor);
if (index > 0)
{
return m_ProcessingNodes[index - 1].OutputSequence;
}
else
return m_InputSequence;
}
public ProcessingNode GetNextProcessor(ProcessingNode node)
{
int index = m_ProcessingNodes.IndexOf(node);
if(index < m_ProcessingNodes.Count-1)
{
return m_ProcessingNodes[index + 1];
}
return null;
}
public void Invalidate(ProcessingNode node)
{
int index = m_ProcessingNodes.IndexOf(node);
if(index != -1)
m_ProcessingNodes[index].Invalidate();
}
public void InvalidateAll()
{
if (m_ProcessingNodes.Count > 0)
m_ProcessingNodes[0].Invalidate();
}
public Dictionary<Type, ProcessorAttribute> settingsDefinitions { get; private set; }
public void UpdateProcessorsFromAssembly()
{
settingsDefinitions = new Dictionary<Type, ProcessorAttribute>();
var assembly = Assembly.GetAssembly(typeof(ProcessorBase));
var types = assembly.GetTypes();
var processorType = typeof(ProcessorBase);
var attrType = typeof(ProcessorAttribute);
var allProcessorTypes = types
.Where(t => t.IsClass
&& !t.IsAbstract
&& t.IsSubclassOf(processorType)
&& t.IsDefined(attrType, false));
foreach (var type in allProcessorTypes)
{
var attr = (ProcessorAttribute)type.GetCustomAttributes(attrType, false)[0];
settingsDefinitions.Add(type, attr);
}
}
}
}

157
ImageSequencer/Editor/FrameProcessorStack.Serialization.cs


using UnityEngine;
using System;
using System.Reflection;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.ImageSequencer
{
internal partial class FrameProcessorStack
{
public void AddSettingsObjectToAsset(ImageSequence asset, ScriptableObject settings)
{
AssetDatabase.AddObjectToAsset(settings,asset);
settings.hideFlags = HideFlags.HideInHierarchy;
}
public void AddProcessorInfoObjectToAsset(ImageSequence asset, ProcessorInfo info)
{
AssetDatabase.AddObjectToAsset(info,asset);
info.hideFlags = HideFlags.HideInHierarchy;
}
public void RemoveAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Clear();
m_InputSequence.frames.Clear();
EditorUtility.SetDirty(asset);
}
public void SortAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Sort((guidA,guidB) => {
return string.Compare(AssetDatabase.GUIDToAssetPath(guidA), AssetDatabase.GUIDToAssetPath(guidB));
});
EditorUtility.SetDirty(asset);
}
public void ReverseAllInputFrames(ImageSequence asset)
{
asset.inputFrameGUIDs.Reverse();
EditorUtility.SetDirty(asset);
}
public void LoadFramesFromAsset(ImageSequence asset)
{
inputSequence.frames.Clear();
if (asset.inputFrameGUIDs != null && asset.inputFrameGUIDs.Count > 0)
{
int count = asset.inputFrameGUIDs.Count;
int i = 1;
foreach (string guid in asset.inputFrameGUIDs)
{
VFXToolboxGUIUtility.DisplayProgressBar("Image Sequencer", "Loading Textures (" + i + "/" + count + ")", (float)i/count, 0.1f);
string path = AssetDatabase.GUIDToAssetPath(guid);
Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
if (t != null)
{
inputSequence.frames.Add(new ProcessingFrame(t));
}
else
{
inputSequence.frames.Add(ProcessingFrame.Missing);
}
i++;
}
VFXToolboxGUIUtility.ClearProgressBar();
}
}
public void SyncFramesToAsset(ImageSequence asset)
{
asset.inputFrameGUIDs.Clear();
foreach(ProcessingFrame f in inputSequence.frames)
{
asset.inputFrameGUIDs.Add(AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(f.texture)));
}
EditorUtility.SetDirty(asset);
}
public void AddProcessor(FrameProcessor processor, ImageSequence asset)
{
AddProcessorInfoObjectToAsset(asset, processor.ProcessorInfo);
asset.processorInfos.Add(processor.ProcessorInfo);
ProcessorBase settings = processor.GetSettingsAbstract();
if (settings != null)
{
AddSettingsObjectToAsset(asset, settings);
processor.ProcessorInfo.Settings = settings;
}
m_Processors.Add(processor);
EditorUtility.SetDirty(asset);
}
public void RemoveAllProcessors(ImageSequence asset)
{
asset.processorInfos.Clear();
m_Processors.Clear();
EditorUtility.SetDirty(asset);
}
public void RemoveProcessor(int index, ImageSequence asset)
{
asset.processorInfos.RemoveAt(index);
m_Processors.RemoveAt(index);
EditorUtility.SetDirty(asset);
}
public void ReorderProcessors(ImageSequence asset)
{
if(m_Processors.Count > 0)
{
List<FrameProcessor> old = new List<FrameProcessor>();
foreach(FrameProcessor p in m_Processors)
{
old.Add(p);
}
m_Processors.Clear();
foreach(ProcessorInfo info in asset.processorInfos)
{
foreach(FrameProcessor p in old)
{
if(p.ProcessorInfo.Equals(info))
{
m_Processors.Add(p);
break;
}
}
}
EditorUtility.SetDirty(asset);
}
}
public void LoadProcessorsFromAsset(ImageSequence asset)
{
m_Processors.Clear();
var infos = asset.processorInfos;
UpdateProcessorsFromAssembly();
// Creating Runtime
foreach(ProcessorInfo procInfo in infos)
{
var processor = (FrameProcessor)Activator.CreateInstance(typeof(FrameProcessor), this, procInfo);
m_Processors.Add(processor);
}
}
}
}

139
ImageSequencer/Editor/FrameProcessorStack.cs


using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
namespace UnityEditor.VFXToolbox.ImageSequencer
{
internal partial class FrameProcessorStack
{
public ProcessingFrameSequence inputSequence
{
get
{
return m_InputSequence;
}
}
public ProcessingFrameSequence outputSequence
{
get
{
if (m_Processors.Count > 0)
return m_Processors[m_Processors.Count - 1].OutputSequence;
else
return m_InputSequence;
}
}
public ImageSequencer imageSequencer
{
get { return m_ImageSequencer; }
}
public List<FrameProcessor> processors
{
get
{
return m_Processors;
}
}
private List<FrameProcessor> m_Processors;
private ProcessingFrameSequence m_InputSequence;
private ImageSequencer m_ImageSequencer;
public FrameProcessorStack(ProcessingFrameSequence inputSequence, ImageSequencer imageSequencer)
{
m_InputSequence = inputSequence;
m_Processors = new List<FrameProcessor>();
m_ImageSequencer = imageSequencer;
}
public void Dispose()
{
foreach(FrameProcessor p in m_Processors)
{
p.Dispose();
}
m_Processors.Clear();
}
public ProcessingFrameSequence GetOutputSequence()
{
if(m_Processors.Count > 0)
{
return m_Processors[m_Processors.Count - 1].OutputSequence;
}
else
{
return inputSequence;
}
}
public ProcessingFrameSequence GetInputSequence(FrameProcessor processor)
{
int index = m_Processors.IndexOf(processor);
if (index > 0)
{
return m_Processors[index - 1].OutputSequence;
}
else
return m_InputSequence;
}
public FrameProcessor GetNextProcessor(FrameProcessor processor)
{
int index = m_Processors.IndexOf(processor);
if(index < m_Processors.Count-1)
{
return m_Processors[index + 1];
}
return null;
}
public void Invalidate(FrameProcessor processor)
{
int index = m_Processors.IndexOf(processor);
if(index != -1)
m_Processors[index].Invalidate();
}
public void InvalidateAll()
{
if (m_Processors.Count > 0)
m_Processors[0].Invalidate();
}
public Dictionary<Type, ProcessorAttribute> settingsDefinitions { get; private set; }
public void UpdateProcessorsFromAssembly()
{
settingsDefinitions = new Dictionary<Type, ProcessorAttribute>();
var assembly = Assembly.GetAssembly(typeof(ProcessorBase));
var types = assembly.GetTypes();
var processorType = typeof(ProcessorBase);
var attrType = typeof(ProcessorAttribute);
var allProcessorTypes = types
.Where(t => t.IsClass
&& !t.IsAbstract
&& t.IsSubclassOf(processorType)
&& t.IsDefined(attrType, false));
foreach (var type in allProcessorTypes)
{
var attr = (ProcessorAttribute)type.GetCustomAttributes(attrType, false)[0];
settingsDefinitions.Add(type, attr);
}
}
}
}

/ImageSequencer/Editor/FrameProcessor.cs.meta → /ImageSequencer/Editor/ProcessingNode.cs.meta

/ImageSequencer/Editor/FrameProcessorStack.Serialization.cs.meta → /ImageSequencer/Editor/ProcessingNodeStack.Serialization.cs.meta

/ImageSequencer/Editor/FrameProcessorStack.cs.meta → /ImageSequencer/Editor/ProcessingNodeStack.cs.meta

/ImageSequencer/Editor/FrameProcessor.cs → /ImageSequencer/Editor/ProcessingNode.cs

正在加载...
取消
保存