您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
230 行
9.3 KiB
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;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|