Files
KopMap/Assets/FImpossible Creations/Editor/Editor Tools/F Texture Tools/RGBA Channel Tools/FChannelInserter.cs

199 lines
8.0 KiB
C#
Raw Normal View History

2025-09-02 18:55:19 +08:00
using FIMSpace.FTextureTools;
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
namespace FIMSpace.FEditor
{
public class FChannelInserter : EditorWindow
{
public Texture2D From;
public enum EChannelSelect { R, G, B, A, RGB }
public EChannelSelect ChannelFrom = EChannelSelect.R;
public EChannelSelect ApplyTo = EChannelSelect.A;
public static void Init()
{
FChannelInserter window = (FChannelInserter)GetWindow(typeof(FChannelInserter));
window.minSize = new Vector2(270f, 225f);
window.titleContent = new GUIContent("Channel Insert", FTextureToolsGUIUtilities.FindIcon("SPR_Channels"));
window.position = new Rect(200, 100, 270, 225);
window.Show();
}
void OnGUI()
{
Texture2D texture = null;
if (Selection.objects.Length > 0)
{
for (int i = 0; i < Selection.objects.Length; i++)
{
texture = AssetDatabase.LoadAssetAtPath<Texture2D>(AssetDatabase.GetAssetPath(Selection.objects[i]));
if (texture != null) break;
}
}
if (texture == null)
{
EditorGUILayout.HelpBox("You must select at least one texture file!", MessageType.Warning);
return;
}
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Texture to edit: " + texture.name);
if (texture)
{
GUILayout.FlexibleSpace();
var texRect = GUILayoutUtility.GetRect(40, 40);
GUI.DrawTexture(texRect, texture, ScaleMode.ScaleToFit);
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(6);
EditorGUIUtility.labelWidth = 190;
From = (Texture2D)EditorGUILayout.ObjectField(From == null ? "Get Channel From:" : "Get Channel From: " + From.name, From, typeof(Texture2D), false);
EditorGUIUtility.labelWidth = 0;
GUILayout.Space(6);
ChannelFrom = (EChannelSelect)EditorGUILayout.EnumPopup("Get channel:", ChannelFrom);
ApplyTo = (EChannelSelect)EditorGUILayout.EnumPopup("Apply it to:", ApplyTo);
if (From != null && texture != null)
{
EditorGUILayout.BeginHorizontal();
EditorGUIUtility.labelWidth = 50;
EditorGUILayout.LabelField("Will Paste this: ");
var rect = GUILayoutUtility.GetRect(40, 40);
EditorGUI.DrawPreviewTexture(rect, From, null, ScaleMode.ScaleToFit, 1f, 0, EChannelToWriteChannel(ChannelFrom));
EditorGUILayout.LabelField("Replacing this: ");
rect = GUILayoutUtility.GetRect(40, 40);
EditorGUI.DrawPreviewTexture(rect, texture, null, ScaleMode.ScaleToFit, 1f, 0, EChannelToWriteChannel(ApplyTo));
EditorGUILayout.EndHorizontal();
EditorGUIUtility.labelWidth = 0;
}
FTextureToolsGUIUtilities.DrawUILine(Color.white * 0.35f, 2, 5);
if (From != null)
{
bool dimensionsDiffer = false;
Texture2D tfrom = From;
if (From.width != texture.width || From.height != texture.height)
{
dimensionsDiffer = true;
EditorGUILayout.HelpBox("Dimensions of the textures are not equal. Algorithm will generate copy of texture and scale it to fit target texture.", MessageType.Info);
}
if (GUILayout.Button((ApplyTo == EChannelSelect.A ? "(Requires A channel) " : "") + "Insert '" + ChannelFrom + "' to '" + ApplyTo + "' channel of " + texture.name))
{
if (dimensionsDiffer) FTextureEditorToolsMethods.ScaleTextureFile(From, tfrom, new Vector2(texture.width, texture.height));
ProcessChanneling(tfrom, texture);
}
if (GUILayout.Button("Duplicate (png) and Insert Channel (" + texture.name + ")"))
{
if (dimensionsDiffer)
tfrom = FTextureEditorToolsMethods.GenerateScaledTexture2DReference(From, new Vector2(texture.width, texture.height), 4, true);
Texture2D duplicated = FTextureEditorToolsMethods.DuplicateAsPNG(texture, "-PNG", true, ApplyTo == EChannelSelect.A);
if (duplicated != null) ProcessChanneling(tfrom, duplicated);
}
}
else
{
EditorGUILayout.HelpBox("You must select 'From' texture", MessageType.Info);
}
}
UnityEngine.Rendering.ColorWriteMask EChannelToWriteChannel(EChannelSelect channel)
{
switch (channel)
{
case EChannelSelect.R: return UnityEngine.Rendering.ColorWriteMask.Red;
case EChannelSelect.G: return UnityEngine.Rendering.ColorWriteMask.Green;
case EChannelSelect.B: return UnityEngine.Rendering.ColorWriteMask.Blue;
case EChannelSelect.A: return UnityEngine.Rendering.ColorWriteMask.Alpha;
}
return UnityEngine.Rendering.ColorWriteMask.All;
}
public void ProcessChanneling(Texture2D source, Texture2D target)
{
TextureImporter srcImporter = FTextureEditorToolsMethods.GetTextureAsset(source);
var srcInfo = FTextureEditorToolsMethods.GetTextureInfo(srcImporter, source);
TextureImporter tgtImporter = FTextureEditorToolsMethods.GetTextureAsset(target);
var tgtInfo = FTextureEditorToolsMethods.GetTextureInfo(tgtImporter, target);
try
{
EditorUtility.DisplayProgressBar("Channeling textures...", "Scaling texture " + target.name, 0.2f);
FTextureEditorToolsMethods.StartEditingTextureAsset(srcImporter, source, srcInfo);
FTextureEditorToolsMethods.StartEditingTextureAsset(tgtImporter, target, tgtInfo);
Color32[] srcPixels = source.GetPixels32();
Color32[] newPixels = target.GetPixels32();
for (int i = 0; i < newPixels.Length; i++)
newPixels[i] = SwapChannel(srcPixels[i], newPixels[i], ChannelFrom, ApplyTo);
FTextureEditorToolsMethods.EndEditingTextureAsset(srcPixels, srcInfo, srcImporter, source);
FTextureEditorToolsMethods.EndEditingTextureAsset(newPixels, tgtInfo, tgtImporter, target);
EditorUtility.ClearProgressBar();
}
catch (System.Exception exc)
{
srcInfo.RestoreOn(srcImporter, source, false);
tgtInfo.RestoreOn(tgtImporter, source, false);
EditorUtility.ClearProgressBar();
UnityEngine.Debug.LogError("[Fimpo Image Tools Something went wrong when channeling textures! " + exc);
}
}
public Color32 SwapChannel(Color32 source, Color32 target, EChannelSelect from, EChannelSelect to)
{
Color32 newC = target;
byte tgt = target.r;
switch (from)
{
case EChannelSelect.R: tgt = source.r; break;
case EChannelSelect.G: tgt = source.g; break;
case EChannelSelect.B: tgt = source.b; break;
case EChannelSelect.A: tgt = source.a; break;
case EChannelSelect.RGB: tgt = (byte)(Mathf.Min((source.r + source.g + source.b) / 3, byte.MaxValue)); break;
}
switch (to)
{
case EChannelSelect.R: newC.r = tgt; break;
case EChannelSelect.G: newC.g = tgt; break;
case EChannelSelect.B: newC.b = tgt; break;
case EChannelSelect.A: newC.a = tgt; break;
case EChannelSelect.RGB: newC.r = tgt; newC.g = tgt; newC.b = tgt; break;
}
return newC;
}
}
}