您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

230 行
9.3 KiB

using UnityEngine;
namespace UnityEditor.Experimental.VFX.Toolbox.ImageSequencer
{
[Processor("Common","Crop")]
internal class CropProcessor : ProcessorBase
{
public uint Crop_Top;
public uint Crop_Bottom;
public uint Crop_Left;
public uint Crop_Right;
public float AutoCropThreshold = 0.003f;
public override string shaderPath => "Packages/com.unity.vfx-toolbox/Editor/ImageSequencer/Shaders/Crop.shader";
public override string processorName => "Crop";
public override void UpdateOutputSize()
{
int width = (inputSequenceWidth - (int)Crop_Left) - (int)Crop_Right;
int height = (inputSequenceHeight - (int)Crop_Top) - (int)Crop_Bottom;
SetOutputSize(width, height);
}
public override void Default()
{
Crop_Top = 0;
Crop_Bottom = 0;
Crop_Left = 0;
Crop_Right = 0;
AutoCropThreshold = 0.003f;
}
public override bool Process(int frame)
{
UpdateOutputSize();
Texture texture = RequestInputTexture(frame);
material.SetTexture("_MainTex", texture);
material.SetVector("_CropFactors", new Vector4(
(float)Crop_Left / texture.width,
(float)Crop_Right / texture.width,
(float)Crop_Top / texture.height,
(float)Crop_Bottom / texture.height
));
ProcessFrame(frame, texture);
return true;
}
public override bool OnInspectorGUI(bool changed, SerializedObject serializedObject)
{
int sourceWidth = inputSequenceWidth;
int sourceHeight = inputSequenceHeight;
var crop_top = serializedObject.FindProperty("Crop_Top");
var crop_bottom = serializedObject.FindProperty("Crop_Bottom");
var crop_left = serializedObject.FindProperty("Crop_Left");
var crop_right = serializedObject.FindProperty("Crop_Right");
var threshold = serializedObject.FindProperty("AutoCropThreshold");
EditorGUI.BeginChangeCheck();
EditorGUILayout.IntSlider(crop_top, 0, (sourceHeight / 2) - 1, VFXToolboxGUIUtility.Get("Top"));
EditorGUILayout.IntSlider(crop_bottom, 0, (sourceHeight / 2) - 1, VFXToolboxGUIUtility.Get("Bottom"));
EditorGUILayout.IntSlider(crop_left, 0, (sourceWidth / 2) - 1, VFXToolboxGUIUtility.Get("Left"));
EditorGUILayout.IntSlider(crop_right, 0, (sourceWidth / 2) - 1, VFXToolboxGUIUtility.Get("Right"));
GUILayout.Space(20);
GUILayout.Label(VFXToolboxGUIUtility.Get("Automatic Crop Values"), EditorStyles.boldLabel);
EditorGUI.indentLevel += 2;
using (new EditorGUILayout.HorizontalScope())
{
EditorGUILayout.Slider(threshold, 0.0f, 1.0f, VFXToolboxGUIUtility.Get("Alpha Threshold"));
if (GUILayout.Button(VFXToolboxGUIUtility.Get("Find")))
{
FindProperValues(threshold.floatValue, ref crop_top, ref crop_bottom, ref crop_left, ref crop_right);
GUI.changed = true;
}
}
EditorGUI.indentLevel -= 2;
GUILayout.Space(20);
Rect preview_rect;
using (new GUILayout.HorizontalScope())
{
GUILayout.FlexibleSpace();
preview_rect = GUILayoutUtility.GetRect(200, 200);
GUILayout.FlexibleSpace();
}
EditorGUI.DrawRect(preview_rect, new Color(0, 0, 0, 0.1f));
GUI.BeginClip(preview_rect);
GUI.Label(new Rect(0, 0, 200, 16), "Preview");
int top = 40;
int left = 40;
int right = 160;
int bottom = 160;
Handles.color = Color.green;
Handles.DrawLine(new Vector3(left, top), new Vector3(left, bottom));
Handles.DrawLine(new Vector3(left, bottom), new Vector3(right, bottom));
Handles.DrawLine(new Vector3(right, bottom), new Vector3(right, top));
Handles.DrawLine(new Vector3(right, top), new Vector3(left, top));
top = (int)(40 + 120 * (float)crop_top.intValue / sourceHeight);
bottom = (int)(160 - 120 * (float)crop_bottom.intValue / sourceHeight);
left = (int)(40 + 120 * (float)crop_left.intValue / sourceWidth);
right = (int)(160 - 120 * (float)crop_right.intValue / sourceWidth);
Handles.color = Color.red;
Handles.DrawLine(new Vector3(left, top), new Vector3(left, bottom));
Handles.DrawLine(new Vector3(left, bottom), new Vector3(right, bottom));
Handles.DrawLine(new Vector3(right, bottom), new Vector3(right, top));
Handles.DrawLine(new Vector3(right, top), new Vector3(left, top));
GUI.EndClip();
if (EditorGUI.EndChangeCheck())
{
UpdateOutputSize();
Invalidate();
changed = true;
}
return changed;
}
private void FindProperValues(float threshold, ref SerializedProperty top, ref SerializedProperty bottom, ref SerializedProperty left, ref SerializedProperty right)
{
int width = inputSequenceWidth;
int height = inputSequenceHeight;
int minX = width;
int maxX = 0;
int minY = height;
int maxY = 0;
Color[] colors;
RenderTexture tempRT = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
for (int i = 0; i < inputSequenceLength; i++)
{
Texture t = RequestInputTexture(i);
VFXToolboxGUIUtility.DisplayProgressBar("Crop processor", "Evaluating closest bound (Frame #" + i + " on " + inputSequenceLength + "...)", (float)i / inputSequenceLength);
if (!isInputFrameSequence)
{
colors = VFXToolboxUtility.ReadBack(t as RenderTexture);
}
else
{
Graphics.Blit(t, tempRT);
colors = VFXToolboxUtility.ReadBack(tempRT);
}
// Check frame
for (int j = 0; j < colors.Length; j++)
{
int x = j % width;
int y = j / width;
if (colors[j].a >= threshold)
{
minX = Mathf.Min(minX, x);
maxX = Mathf.Max(maxX, x);
minY = Mathf.Min(minY, y);
maxY = Mathf.Max(maxY, y);
}
}
}
VFXToolboxGUIUtility.ClearProgressBar();
bottom.intValue = minY;
top.intValue = height - maxY - 1;
left.intValue = minX;
right.intValue = width - maxX - 1;
RenderTexture.ReleaseTemporary(tempRT);
}
public override bool OnCanvasGUI(ImageSequencerCanvas canvas)
{
if (Event.current.type != EventType.Repaint)
return false;
Vector2 center = canvas.CanvasToScreen(Vector2.zero);
Vector2 topRight;
Vector2 bottomLeft;
topRight = canvas.CanvasToScreen(new Vector2(-canvas.currentFrame.texture.width / 2 - Crop_Right, canvas.currentFrame.texture.height / 2 + Crop_Top));
bottomLeft = canvas.CanvasToScreen(new Vector2(canvas.currentFrame.texture.width / 2 + Crop_Left, -canvas.currentFrame.texture.height / 2 - Crop_Bottom));
Handles.DrawSolidRectangleWithOutline(new Rect(topRight, bottomLeft - topRight), Color.clear, canvas.styles.green);
Vector2 topRightCrop;
Vector2 bottomLeftCrop;
topRightCrop = canvas.CanvasToScreen(new Vector2(-canvas.currentFrame.texture.width / 2, canvas.currentFrame.texture.height / 2));
bottomLeftCrop = canvas.CanvasToScreen(new Vector2(canvas.currentFrame.texture.width / 2, -canvas.currentFrame.texture.height / 2));
Handles.DrawSolidRectangleWithOutline(new Rect(topRightCrop, bottomLeftCrop - topRightCrop), Color.clear, canvas.styles.red);
// Arrows
Handles.color = canvas.styles.white;
Handles.DrawLine(new Vector3(center.x, topRight.y), new Vector3(center.x, topRightCrop.y));
Handles.DrawLine(new Vector3(center.x, bottomLeft.y), new Vector3(center.x, bottomLeftCrop.y));
Handles.DrawLine(new Vector3(topRight.x, center.y), new Vector3(topRightCrop.x, center.y));
Handles.DrawLine(new Vector3(bottomLeft.x, center.y), new Vector3(bottomLeftCrop.x, center.y));
Handles.color = Color.white;
// Texts
GUI.Label(new Rect(center.x, topRightCrop.y - 16, 64, 16), Crop_Top.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(center.x, bottomLeftCrop.y, 64, 16), Crop_Bottom.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(topRightCrop.x, center.y, 64, 16), Crop_Right.ToString(), canvas.styles.miniLabel);
GUI.Label(new Rect(bottomLeftCrop.x - 64, center.y, 64, 16), Crop_Left.ToString(), canvas.styles.miniLabelRight);
return false;
}
}
}