diff --git a/_PoiyomiShaders/Prefabs.meta b/_PoiyomiShaders/Prefabs.meta new file mode 100644 index 00000000..3791acf3 --- /dev/null +++ b/_PoiyomiShaders/Prefabs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4ff2cc567a760f244bfe790065c38719 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Prefabs/DepthGet.prefab b/_PoiyomiShaders/Prefabs/DepthGet.prefab new file mode 100644 index 00000000..ce2bc66d --- /dev/null +++ b/_PoiyomiShaders/Prefabs/DepthGet.prefab @@ -0,0 +1,71 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1259802800977766 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4106851629791990} + - component: {fileID: 108814990146528582} + m_Layer: 0 + m_Name: DepthGet + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &4106851629791990 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1259802800977766} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!108 &108814990146528582 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1259802800977766} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Intensity: 0.001 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 1 + m_Resolution: 0 + m_CustomResolution: -1 + m_Strength: 0 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4 + m_Lightmapping: 4 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 0 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 diff --git a/_PoiyomiShaders/Prefabs/DepthGet.prefab.meta b/_PoiyomiShaders/Prefabs/DepthGet.prefab.meta new file mode 100644 index 00000000..d709ad58 --- /dev/null +++ b/_PoiyomiShaders/Prefabs/DepthGet.prefab.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 23c61f8f4d0a87243a36c937bd3e1393 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts.meta b/_PoiyomiShaders/Scripts.meta index efc55817..9f7d2771 100644 --- a/_PoiyomiShaders/Scripts.meta +++ b/_PoiyomiShaders/Scripts.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: cfc4de536d16ce04fb4f58bf9a796b91 +guid: cb6ee88252fc3a148bd58c622e792642 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Config.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Config.cs index 1898e007..72bf1f4e 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Config.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Config.cs @@ -11,7 +11,7 @@ public class Config { // consts private const string PATH_CONFIG_FILE = "Thry/Config.json"; - private const string VERSION = "2.51.7"; + private const string VERSION = "2.56.5"; // static private static Config config; @@ -44,15 +44,22 @@ public static void OnCompile() } } + private static bool LoadFromFile(ref Config config) + { + if (!File.Exists(PATH_CONFIG_FILE)) return false; + string data = FileHelper.ReadFileIntoString(PATH_CONFIG_FILE); + if (string.IsNullOrWhiteSpace(data)) return false; + config = JsonUtility.FromJson(data); + return true; + } + public static Config Singleton { get { if (config == null) { - if (File.Exists(PATH_CONFIG_FILE)) - config = JsonUtility.FromJson(FileHelper.ReadFileIntoString(PATH_CONFIG_FILE)); - else + if(!LoadFromFile(ref config)) config = new Config().Save(); } return config; @@ -63,6 +70,7 @@ public static Config Singleton public TextureDisplayType default_texture_type = TextureDisplayType.small; public bool showRenderQueue = true; public bool showManualReloadButton = false; + public bool showColorspaceWarnings = true; public bool allowCustomLockingRenaming = false; public bool autoMarkPropertiesAnimated = true; public TextureImporterFormat texturePackerCompressionWithAlphaOverwrite = TextureImporterFormat.Automatic; @@ -191,4 +199,9 @@ public override int GetHashCode() return base.GetHashCode(); } } + + public enum TextureDisplayType + { + small, big, big_basic + } } diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/CrossEditor.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/CrossEditor.cs index 9919a484..fc21a03d 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/CrossEditor.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/CrossEditor.cs @@ -152,10 +152,14 @@ private void OnGUI() EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); // Cursed but makes it render similar to the inspector + EditorGUILayout.BeginHorizontal(); - EditorGUILayout.Space(15); + EditorGUILayout.Space(30); EditorGUILayout.BeginVertical(); + bool wideMode = EditorGUIUtility.wideMode; + EditorGUIUtility.wideMode = true; _shaderEditor.OnGUI(_materialEditor, _materialProperties); + EditorGUIUtility.wideMode = wideMode; EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs deleted file mode 100644 index 86105675..00000000 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs +++ /dev/null @@ -1,822 +0,0 @@ -// Material/Shader Inspector for Unity 2017/2018 -// Copyright (C) 2019 Thryrallo - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEngine; - -namespace Thry -{ - #region Constants - public class PATH - { - public const string TEXTURES_DIR = "Assets/textures"; - public const string RSP_NEEDED_PATH = "Assets/"; - - public const string DELETING_DIR = "Thry/trash"; - - public const string PERSISTENT_DATA = "Thry/persistent_data"; - - public const string GRADIENT_INFO_FILE = "Thry/gradients"; - - public const string LINKED_MATERIALS_FILE = "Thry/linked_materials.json"; - } - - public class URL - { - public const string MODULE_COLLECTION = "https://raw.githubusercontent.com/Thryrallo/ThryEditorStreamedResources/main/packages.json"; - public const string SETTINGS_MESSAGE_URL = "https://raw.githubusercontent.com/Thryrallo/ThryEditorStreamedResources/main/Messages/settingsWindow.json"; - public const string COUNT_PROJECT = "http://thryeditor.thryrallo.de/count_project.php"; - public const string COUNT_USER = "http://thryeditor.thryrallo.de/count_user.php"; - } - - public class DEFINE_SYMBOLS - { - public const string IMAGING_EXISTS = "IMAGING_DLL_EXISTS"; - } - - public class RESOURCE_GUID - { - public const string RECT = "2329f8696fd09a743a5baf2a5f4986af"; - public const string ICON_LINK = "e85fd0a0e4e4fea46bb3fdeab5c3fb07"; - public const string ICON_THRY = "693aa4c2cdc578346a196469a06ddbba"; - } - #endregion - - public class DrawingData - { - public static TextureProperty CurrentTextureProperty; - public static Rect LastGuiObjectRect; - public static Rect LastGuiObjectHeaderRect; - public static Rect TooltipCheckRect; - public static float IconsPositioningHeight; - public static bool LastPropertyUsedCustomDrawer; - public static bool LastPropertyDoesntAllowAnimation; - public static DrawerType LastPropertyDrawerType; - public static MaterialPropertyDrawer LastPropertyDrawer; - public static List LastPropertyDecorators = new List(); - public static bool IsEnabled = true; - public static bool IsCollectingProperties = false; - - public static ShaderPart LastInitiatedPart; - - public static void ResetLastDrawerData() - { - LastPropertyUsedCustomDrawer = false; - LastPropertyDoesntAllowAnimation = false; - LastPropertyDrawer = null; - LastPropertyDrawerType = DrawerType.None; - LastPropertyDecorators.Clear(); - } - - public static void RegisterDecorator(MaterialPropertyDrawer drawer) - { - if(IsCollectingProperties) - { - LastPropertyDecorators.Add(drawer); - } - } - } - - public enum DrawerType - { - None - } - - public class GradientData - { - public Texture PreviewTexture; - public Gradient Gradient; - } - - public enum TextureDisplayType - { - small, big, big_basic - } - - //--------------Shader Data Structs-------------------- - - #region In Shader Data - public class PropertyOptions - { - public int offset = 0; - public string tooltip = ""; - public DefineableAction altClick; - public DefineableAction onClick; - public DefineableCondition condition_show = new DefineableCondition(); - public string condition_showS; - public DefineableCondition condition_enable = null; - public DefineableCondition condition_enable_children = null; - public PropertyValueAction[] on_value_actions; - public string on_value; - public DefineableAction[] actions; - public ButtonData button_help; - public TextureData texture; - public string[] reference_properties; - public string reference_property; - public bool force_texture_options = false; - public bool is_visible_simple = false; - public string file_name; - public string remote_version_url; - public string generic_string; - public bool never_lock; - public float margin_top = 0; - public string[] alts; - public bool persistent_expand = true; - public bool default_expand = false; - public bool ref_float_toggles_expand = true; - - public static PropertyOptions Deserialize(string s) - { - if(s == null) return new PropertyOptions(); - s = s.Replace("''", "\""); - PropertyOptions options = Parser.Deserialize(s); - if (options == null) return new PropertyOptions(); - // The following could be removed since the parser can now handle it. leaving it in for now /shrug - if (options.condition_showS != null) - { - options.condition_show = DefineableCondition.Parse(options.condition_showS); - } - if (options.on_value != null) - { - options.on_value_actions = PropertyValueAction.ParseToArray(options.on_value); - } - return options; - } - } - - public class ButtonData - { - public string text = ""; - public TextureData texture = null; - public DefineableAction action = new DefineableAction(); - public string hover = ""; - public bool center_position = false; - public DefineableCondition condition_show = new DefineableCondition(); - } - - public class TextureData - { - public string name = null; - public string guid = null; - public int width = 128; - public int height = 128; - - public char channel = 'r'; - - public int ansioLevel = 1; - public FilterMode filterMode = FilterMode.Bilinear; - public TextureWrapMode wrapMode = TextureWrapMode.Repeat; - public bool center_position = false; - bool _isLoading; - - public void ApplyModes(Texture texture) - { - texture.filterMode = filterMode; - texture.wrapMode = wrapMode; - texture.anisoLevel = ansioLevel; - } - public void ApplyModes(string path) - { - TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(path); - importer.filterMode = filterMode; - importer.wrapMode = wrapMode; - importer.anisoLevel = ansioLevel; - importer.SaveAndReimport(); - } - - static Dictionary s_loaded_textures = new Dictionary(); - public Texture loaded_texture - { - get - { - if(guid != null) - { - if(!s_loaded_textures.ContainsKey(guid) || s_loaded_textures[guid] == null) - { - string path = AssetDatabase.GUIDToAssetPath(guid); - if (path != null) - s_loaded_textures[guid] = AssetDatabase.LoadAssetAtPath(path); - else - s_loaded_textures[guid] = Texture2D.whiteTexture; - } - return s_loaded_textures[guid]; - }else if(name != null) - { - if(!s_loaded_textures.ContainsKey(name) || s_loaded_textures[name] == null) - { - // Retrieve downloaded image from sessionstate (base64 encoded) - if(SessionState.GetString(name, "") != "") - { - s_loaded_textures[name] = new Texture2D(1,1, TextureFormat.ARGB32, false); - ImageConversion.LoadImage((Texture2D)s_loaded_textures[name], Convert.FromBase64String(SessionState.GetString(name, "")), false); - return s_loaded_textures[name]; - } - - if(IsUrl()) - { - if(!_isLoading) - { - s_loaded_textures[name] = Texture2D.whiteTexture; - WebHelper.DownloadBytesASync(name, (byte[] b) => - { - _isLoading = false; - Texture2D tex = new Texture2D(1,1, TextureFormat.ARGB32, false); - ImageConversion.LoadImage(tex, b, false); - s_loaded_textures[name] = tex; - SessionState.SetString(name, Convert.ToBase64String(((Texture2D)s_loaded_textures[name]).EncodeToPNG())); - }); - _isLoading = true; - } - }else - { - string path = FileHelper.FindFile(name, "texture"); - if (path != null) - s_loaded_textures[name] = AssetDatabase.LoadAssetAtPath(path); - else - s_loaded_textures[name] = Texture2D.whiteTexture; - } - } - return s_loaded_textures[name]; - } - return Texture2D.whiteTexture; - } - } - - private static TextureData ParseForThryParser(string s) - { - if(s.StartsWith("{") == false) - { - return new TextureData() - { - name = s - }; - } - return Parser.Deserialize(s); - } - - bool IsUrl() - { - return name.StartsWith("http") && (name.EndsWith(".jpg") || name.EndsWith(".png")); - } - } - - public class PropertyValueAction - { - public string value; - public DefineableAction[] actions; - - public bool Execute(MaterialProperty p, Material[] targets) - { - if( - (p.type == MaterialProperty.PropType.Float && p.floatValue.ToString() == value) || -#if UNITY_2022_1_OR_NEWER - (p.type == MaterialProperty.PropType.Int && p.intValue.ToString() == value) || -#endif - (p.type == MaterialProperty.PropType.Range && p.floatValue.ToString() == value) || - (p.type == MaterialProperty.PropType.Color && p.colorValue.ToString() == value) || - (p.type == MaterialProperty.PropType.Vector && p.vectorValue.ToString() == value) || - (p.type == MaterialProperty.PropType.Texture && ((p.textureValue == null) == (value == "0"))) || - (p.type == MaterialProperty.PropType.Texture && ((p.textureValue != null) == (value == "1"))) || - (p.type == MaterialProperty.PropType.Texture && (p.textureValue != null && p.textureValue.name == value)) - ) - {; - foreach (DefineableAction a in actions) - a.Perform(targets); - return true; - } - return false; - } - - private static PropertyValueAction ParseForThryParser(string s) - { - return Parse(s); - } - - // value,property1=value1,property2=value2 - public static PropertyValueAction Parse(string s) - { - s = s.Trim(); - string[] valueAndActions = s.Split(new string[]{"=>"}, System.StringSplitOptions.RemoveEmptyEntries); - if (valueAndActions.Length > 1) - { - PropertyValueAction propaction = new PropertyValueAction(); - propaction.value = valueAndActions[0]; - List actions = new List(); - string[] actionStrings = valueAndActions[1].Split(';'); - for (int i = 0; i < actionStrings.Length; i++) - { - if(string.IsNullOrWhiteSpace(actionStrings[i])) - continue; - actions.Add(DefineableAction.Parse(actionStrings[i])); - } - propaction.actions = actions.ToArray(); - return propaction; - } - return null; - } - - private static PropertyValueAction[] ParseToArrayForThryParser(string s) - { - return ParseToArray(s); - } - - public static PropertyValueAction[] ParseToArray(string s) - { - //s := 0=>p1=v1;p2=v2;1=>p1=v3... - List propactions = new List(); - string[] valueAndActionMatches = Regex.Matches(s, @"[^;]+=>.+?(?=(;[^;]+=>)|$)", RegexOptions.Multiline).Cast().Select(m => m.Value).ToArray(); - foreach (string p in valueAndActionMatches) - { - PropertyValueAction propertyValueAction = PropertyValueAction.Parse(p); - if (propertyValueAction != null) - propactions.Add(propertyValueAction); - } - return propactions.ToArray(); - } - } - - public class DefineableAction - { - public DefineableActionType type = DefineableActionType.NONE; - public string data = ""; - public void Perform(Material[] targets) - { - switch (type) - { - case DefineableActionType.URL: - Application.OpenURL(data); - break; - case DefineableActionType.SET_PROPERTY: - string[] set = Regex.Split(data, @"="); - if (set.Length > 1) - MaterialHelper.SetMaterialValue(set[0].Trim(), set[1].Trim()); - break; - case DefineableActionType.SET_TAG: - string[] keyValue = Regex.Split(data, @"="); - foreach (Material m in targets) - m.SetOverrideTag(keyValue[0].Trim(), keyValue[1].Trim()); - break; - case DefineableActionType.SET_SHADER: - Shader shader = Shader.Find(data); - if (shader != null) - { - foreach (Material m in targets) - m.shader = shader; - } - break; - case DefineableActionType.OPEN_EDITOR: - System.Type t = Helper.FindTypeByFullName(data); - if (t != null) - { - try - { - EditorWindow window = EditorWindow.GetWindow(t); - window.titleContent = new GUIContent("TPS Setup Wizard"); - window.Show(); - }catch(System.Exception e) - { - Debug.LogError("[Thry] Couldn't open Editor Window of type" + data); - Debug.LogException(e); - } - } - break; - } - } - - private static DefineableAction ParseForThryParser(string s) - { - return Parse(s); - } - public static DefineableAction Parse(string s) - { - s = s.Trim(); - DefineableAction action = new DefineableAction(); - if (s.StartsWith("http", StringComparison.Ordinal) || s.StartsWith("www", StringComparison.Ordinal)) - { - action.type = DefineableActionType.URL; - action.data = s; - } - else if (s.StartsWith("tag::", StringComparison.Ordinal)) - { - action.type = DefineableActionType.SET_TAG; - action.data = s.Replace("tag::", ""); - } - else if (s.StartsWith("shader=", StringComparison.Ordinal)) - { - action.type = DefineableActionType.SET_SHADER; - action.data = s.Replace("shader=", ""); - } - else if (s.Contains("=")) - { - action.type = DefineableActionType.SET_PROPERTY; - action.data = s; - } - else if (Regex.IsMatch(s, @"\w+(\.\w+)")) - { - action.type = DefineableActionType.OPEN_EDITOR; - action.data = s; - } - return action; - } - - public static DefineableAction ParseDrawerParameter(string s) - { - s = s.Trim(); - DefineableAction action = new DefineableAction(); - if (s.StartsWith("youtube#", StringComparison.Ordinal)) - { - action.type = DefineableActionType.URL; - action.data = "https://www.youtube.com/watch?v="+s.Substring(8); - } - return action; - } - - public override string ToString() - { - return $"{{{type},{data}}}"; - } - } - - public enum DefineableActionType - { - NONE, - URL, - SET_PROPERTY, - SET_SHADER, - SET_TAG, - OPEN_EDITOR, - } - - public class DefineableCondition - { - public DefineableConditionType type = DefineableConditionType.NONE; - public string data = ""; - public DefineableCondition condition1; - public DefineableCondition condition2; - - CompareType _compareType; - string _obj; - ShaderProperty _propertyObj; - Material _materialInsteadOfEditor; - - string _value; - float _floatValue; - - bool _hasConstantValue; - bool _constantValue; - - bool _isInit = false; - public void Init() - { - if (_isInit) return; - _hasConstantValue = true; - if (type == DefineableConditionType.NONE) { _constantValue = true; } - else if (type == DefineableConditionType.TRUE) { _constantValue = true; } - else if (type == DefineableConditionType.FALSE) { _constantValue = false; } - else - { - var (compareType, compareString) = GetComparetor(); - _compareType = compareType; - - string[] parts = Regex.Split(data, compareString); - _obj = parts[0].Trim(); - _value = parts[parts.Length - 1].Trim(); - - _floatValue = Parser.ParseFloat(_value); - if (ShaderEditor.Active != null && ShaderEditor.Active.PropertyDictionary.ContainsKey(_obj)) - _propertyObj = ShaderEditor.Active.PropertyDictionary[_obj]; - - if (type == DefineableConditionType.EDITOR_VERSION) InitEditorVersion(); - else if (type == DefineableConditionType.VRC_SDK_VERSION) InitVRCSDKVersion(); - else _hasConstantValue = false; - } - - _isInit = true; - } - - void InitEditorVersion() - { - int c_ev = Helper.CompareVersions(Config.Singleton.verion, _value); - if (_compareType == CompareType.EQUAL) _constantValue = c_ev == 0; - if (_compareType == CompareType.NOT_EQUAL) _constantValue = c_ev != 0; - if (_compareType == CompareType.SMALLER) _constantValue = c_ev == 1; - if (_compareType == CompareType.BIGGER) _constantValue = c_ev == -1; - if (_compareType == CompareType.BIGGER_EQ) _constantValue = c_ev == -1 || c_ev == 0; - if (_compareType == CompareType.SMALLER_EQ) _constantValue = c_ev == 1 || c_ev == 0; - } - - void InitVRCSDKVersion() - { - if (VRCInterface.Get().Sdk_information.type == VRCInterface.VRC_SDK_Type.NONE) - { - _constantValue = false; - return; - } - int c_vrc = Helper.CompareVersions(VRCInterface.Get().Sdk_information.installed_version, _value); - if (_compareType == CompareType.EQUAL) _constantValue = c_vrc == 0; - if (_compareType == CompareType.NOT_EQUAL) _constantValue = c_vrc != 0; - if (_compareType == CompareType.SMALLER) _constantValue = c_vrc == 1; - if (_compareType == CompareType.BIGGER) _constantValue = c_vrc == -1; - if (_compareType == CompareType.BIGGER_EQ) _constantValue = c_vrc == -1 || c_vrc == 0; - if (_compareType == CompareType.SMALLER_EQ) _constantValue = c_vrc == 1 || c_vrc == 0; - } - - public bool Test() - { - Init(); - if (_hasConstantValue) return _constantValue; - - MaterialProperty materialProperty = null; - switch (type) - { - case DefineableConditionType.PROPERTY_BOOL: - materialProperty = GetMaterialProperty(); - if (materialProperty == null) return false; - if (_compareType == CompareType.NONE) return materialProperty.GetNumber() == 1; - if (_compareType == CompareType.EQUAL) return materialProperty.GetNumber() == _floatValue; - if (_compareType == CompareType.NOT_EQUAL) return materialProperty.GetNumber() != _floatValue; - if (_compareType == CompareType.SMALLER) return materialProperty.GetNumber() < _floatValue; - if (_compareType == CompareType.BIGGER) return materialProperty.GetNumber() > _floatValue; - if (_compareType == CompareType.BIGGER_EQ) return materialProperty.GetNumber() >= _floatValue; - if (_compareType == CompareType.SMALLER_EQ) return materialProperty.GetNumber() <= _floatValue; - break; - case DefineableConditionType.TEXTURE_SET: - materialProperty = GetMaterialProperty(); - if (materialProperty == null) return false; - return (materialProperty.textureValue == null) == (_compareType == CompareType.EQUAL); - case DefineableConditionType.DROPDOWN: - materialProperty = GetMaterialProperty(); - if (materialProperty == null) return false; - if (_compareType == CompareType.NONE) return materialProperty.GetNumber() == 1; - if (_compareType == CompareType.EQUAL) return "" + materialProperty.GetNumber() == _value; - if (_compareType == CompareType.NOT_EQUAL) return "" + materialProperty.GetNumber() != _value; - break; - case DefineableConditionType.PROPERTY_IS_ANIMATED: - return ShaderOptimizer.IsAnimated(_materialInsteadOfEditor, _obj); - case DefineableConditionType.PROPERTY_IS_NOT_ANIMATED: - return !ShaderOptimizer.IsAnimated(_materialInsteadOfEditor, _obj); - case DefineableConditionType.AND: - if(condition1!=null&&condition2!=null) return condition1.Test() && condition2.Test(); - break; - case DefineableConditionType.OR: - if(condition1 != null && condition2 != null) return condition1.Test() || condition2.Test(); - break; - case DefineableConditionType.NOT: - if(condition1 != null) return !condition1.Test(); - break; - } - - return true; - } - - private MaterialProperty GetMaterialProperty() - { - if(_materialInsteadOfEditor) return MaterialEditor.GetMaterialProperty(new Material[]{_materialInsteadOfEditor}, _obj); - if(_propertyObj != null) return _propertyObj.MaterialProperty; - return null; - } - private (CompareType,string) GetComparetor() - { - if (data.Contains("==")) - return (CompareType.EQUAL,"=="); - if (data.Contains("!=")) - return (CompareType.NOT_EQUAL,"!="); - if (data.Contains(">=")) - return (CompareType.BIGGER_EQ,">="); - if (data.Contains("<=")) - return (CompareType.SMALLER_EQ,"<="); - if (data.Contains(">")) - return (CompareType.BIGGER,">"); - if (data.Contains("<")) - return (CompareType.SMALLER,"<"); - return (CompareType.NONE,"##"); - } - - public override string ToString() - { - switch (type) - { - case DefineableConditionType.PROPERTY_BOOL: - return data; - case DefineableConditionType.EDITOR_VERSION: - return "EDITOR_VERSION" + data; - case DefineableConditionType.VRC_SDK_VERSION: - return "VRC_SDK_VERSION" + data; - case DefineableConditionType.TEXTURE_SET: - return "TEXTURE_SET" + data; - case DefineableConditionType.DROPDOWN: - return "DROPDOWN" + data; - case DefineableConditionType.PROPERTY_IS_ANIMATED: - return $"isAnimated({data})"; - case DefineableConditionType.PROPERTY_IS_NOT_ANIMATED: - return $"isNotAnimated({data})"; - case DefineableConditionType.AND: - if (condition1 != null && condition2 != null) return "("+condition1.ToString() + "&&" + condition2.ToString()+")"; - break; - case DefineableConditionType.OR: - if (condition1 != null && condition2 != null) return "("+condition1.ToString()+"||"+condition2.ToString()+")"; - break; - case DefineableConditionType.NOT: - if (condition1 != null) return "!"+condition1.ToString(); - break; - } - return ""; - } - - private static DefineableCondition ParseForThryParser(string s) - { - return Parse(s); - } - - private static readonly char[] ComparissionLiteralsToCheckFor = "*><=".ToCharArray(); - public static DefineableCondition Parse(string s, Material useThisMaterialInsteadOfOpenEditor = null, int start = 0, int end = -1) - { - if(end == -1) end = s.Length; - DefineableCondition con; - - // Debug.Log("Parsing: " + s.Substring(start, end - start)); - - int depth = 0; - int bracketStart = -1; - int bracketEnd = -1; - for(int i = start; i < end; i++) - { - char c = s[i]; - if(c == '(') - { - depth += 1; - if(depth == 1) - { - bracketStart = i; - } - }else if(c == ')') - { - if(depth == 1) - { - bracketEnd = i; - } - depth -= 1; - }else if(depth == 0) - { - if(c == '&') - { - con = new DefineableCondition(); - con._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; - - con.type = DefineableConditionType.AND; - con.condition1 = Parse(s, useThisMaterialInsteadOfOpenEditor, start, i); - con.condition2 = Parse(s, useThisMaterialInsteadOfOpenEditor, i + (s[i+1] == '&' ? 2 : 1), end); - return con; - }else if(c == '|') - { - - con = new DefineableCondition(); - con._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; - - con.type = DefineableConditionType.OR; - con.condition1 = Parse(s, useThisMaterialInsteadOfOpenEditor, start, i); - con.condition2 = Parse(s, useThisMaterialInsteadOfOpenEditor, i + (s[i + 1] == '|' ? 2 : 1), end); - return con; - } - } - } - - - bool isInverted = IsInverted(s, ref start); - - // if no AND or OR was found, check for brackets - if(bracketStart != -1 && bracketEnd != -1) - { - con = Parse(s, useThisMaterialInsteadOfOpenEditor, bracketStart + 1, bracketEnd); - }else - { - con = ParseSingle(s.Substring(start, end - start), useThisMaterialInsteadOfOpenEditor); - } - - if(isInverted) - { - DefineableCondition inverted = new DefineableCondition(); - inverted._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; - inverted.type = DefineableConditionType.NOT; - inverted.condition1 = con; - return inverted; - } - - return con; - } - - static bool IsInverted(string s, ref int start) - { - for(int i = start; i < s.Length; i++) - { - if(s[i] == '!') - { - start += 1; - return true; - } - if(s[i] != ' ') - return false; - } - return false; - } - - static DefineableCondition ParseSingle(string s, Material useThisMaterialInsteadOfOpenEditor = null) - { - // Debug.Log("Parsing single: " + s); - - DefineableCondition con = new DefineableCondition - { - _materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor - }; - - if (s.IndexOfAny(ComparissionLiteralsToCheckFor) != -1) - { - //is a comparission - con.data = s; - con.type = DefineableConditionType.PROPERTY_BOOL; - if (s.StartsWith("VRCSDK", StringComparison.Ordinal)) - { - con.type = DefineableConditionType.VRC_SDK_VERSION; - con.data = s.Replace("VRCSDK", ""); - }else if (s.StartsWith("ThryEditor", StringComparison.Ordinal)) - { - con.type = DefineableConditionType.EDITOR_VERSION; - con.data = s.Replace("ThryEditor", ""); - }else if(IsTextureNullComparission(s, useThisMaterialInsteadOfOpenEditor)) - { - con.type = DefineableConditionType.TEXTURE_SET; - con.data = s.Replace("TEXTURE_SET", ""); - } - return con; - } - if(s.StartsWith("isNotAnimated(", StringComparison.Ordinal)) - { - con.type = DefineableConditionType.PROPERTY_IS_NOT_ANIMATED; - con.data = s.Replace("isNotAnimated(", "").TrimEnd(')'); - return con; - } - if(s.StartsWith("isAnimated(", StringComparison.Ordinal)) - { - con.type = DefineableConditionType.PROPERTY_IS_ANIMATED; - con.data = s.Replace("isAnimated(", "").TrimEnd(')'); - return con; - } - if(s.Equals("true", StringComparison.OrdinalIgnoreCase)) - { - con.type = DefineableConditionType.TRUE; - return con; - } - if(s.Equals("false", StringComparison.OrdinalIgnoreCase)) - { - con.type = DefineableConditionType.FALSE; - return con; - } - return con; - } - - static bool IsTextureNullComparission(string data, Material useThisMaterialInsteadOfOpenEditor = null) - { - // Check if property is a texture property && is checking for null - Material m = GetReferencedMaterial(useThisMaterialInsteadOfOpenEditor); - if( m == null) return false; - if(data.Length < 7) return false; - if(data.EndsWith("null") == false) return false; - string propertyName = data.Substring(0, data.Length - 6); - if(m.HasProperty(propertyName) == false) return false; - MaterialProperty p = MaterialEditor.GetMaterialProperty(new Material[]{m}, propertyName); - return p.type == MaterialProperty.PropType.Texture; - } - - static Material GetReferencedMaterial(Material useThisMaterialInsteadOfOpenEditor = null) - { - if( useThisMaterialInsteadOfOpenEditor != null ) return useThisMaterialInsteadOfOpenEditor; - if( ShaderEditor.Active != null ) return ShaderEditor.Active.Materials[0]; - return null; - } - } - - enum CompareType { NONE,BIGGER,SMALLER,EQUAL,NOT_EQUAL,BIGGER_EQ,SMALLER_EQ } - - public enum DefineableConditionType - { - NONE, - TRUE, - FALSE, - PROPERTY_BOOL, - PROPERTY_IS_ANIMATED, - PROPERTY_IS_NOT_ANIMATED, - EDITOR_VERSION, - VRC_SDK_VERSION, - TEXTURE_SET, - DROPDOWN, - AND, - OR, - NOT - } - - #endregion -} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.meta new file mode 100644 index 00000000..ca2fd3e2 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 661e622ef0542da48b901c87db9bfd20 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs new file mode 100644 index 00000000..4ef56435 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class ButtonData + { + public string text = ""; + public TextureData texture = null; + public DefineableAction action = new DefineableAction(); + public string hover = ""; + public bool center_position = false; + public DefineableCondition condition_show = new DefineableCondition(); + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs.meta similarity index 83% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs.meta index 9a8cc3c7..3ce16ff6 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs.meta +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/ButtonData.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 02b9c440c777db4458c2284c28736ca0 +guid: 1af5736d4563e2e4cb5db5622907c1e0 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs new file mode 100644 index 00000000..e42f8aa4 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class PATH + { + public const string TEXTURES_DIR = "Assets/textures"; + public const string RSP_NEEDED_PATH = "Assets/"; + + public const string DELETING_DIR = "Thry/trash"; + + public const string PERSISTENT_DATA = "Thry/persistent_data"; + + public const string GRADIENT_INFO_FILE = "Thry/gradients"; + + public const string LINKED_MATERIALS_FILE = "Thry/linked_materials.json"; + } + + public class URL + { + public const string MODULE_COLLECTION = "https://raw.githubusercontent.com/Thryrallo/ThryEditorStreamedResources/main/packages.json"; + public const string SETTINGS_MESSAGE_URL = "https://raw.githubusercontent.com/Thryrallo/ThryEditorStreamedResources/main/Messages/settingsWindow.json"; + public const string COUNT_PROJECT = "http://thryeditor.thryrallo.de/count_project.php"; + public const string COUNT_USER = "http://thryeditor.thryrallo.de/count_user.php"; + } + + public class DEFINE_SYMBOLS + { + public const string IMAGING_EXISTS = "IMAGING_DLL_EXISTS"; + } + + public class RESOURCE_GUID + { + public const string RECT = "2329f8696fd09a743a5baf2a5f4986af"; + public const string ICON_LINK = "e85fd0a0e4e4fea46bb3fdeab5c3fb07"; + public const string ICON_THRY = "693aa4c2cdc578346a196469a06ddbba"; + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs.meta similarity index 83% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs.meta index 16085f5b..ce0c999a 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs.cs.meta +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/Constants.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 42f9390784d11e84bbf6366e794e6b20 +guid: a6ceb1a8c873f3c48876dc3d0d34fb8d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs new file mode 100644 index 00000000..bed480b0 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class DefineableAction + { + public DefineableActionType type = DefineableActionType.NONE; + public string data = ""; + public void Perform(Material[] targets) + { + switch (type) + { + case DefineableActionType.URL: + Application.OpenURL(data); + break; + case DefineableActionType.SET_PROPERTY: + string[] set = Regex.Split(data, @"="); + if (set.Length > 1) + MaterialHelper.SetMaterialValue(set[0].Trim(), set[1].Trim()); + break; + case DefineableActionType.SET_TAG: + string[] keyValue = Regex.Split(data, @"="); + foreach (Material m in targets) + m.SetOverrideTag(keyValue[0].Trim(), keyValue[1].Trim()); + break; + case DefineableActionType.SET_SHADER: + Shader shader = Shader.Find(data); + if (shader != null) + { + foreach (Material m in targets) + m.shader = shader; + } + break; + case DefineableActionType.OPEN_EDITOR: + System.Type t = Helper.FindTypeByFullName(data); + if (t != null) + { + try + { + EditorWindow window = EditorWindow.GetWindow(t); + window.titleContent = new GUIContent("TPS Setup Wizard"); + window.Show(); + } + catch (System.Exception e) + { + Debug.LogError("[Thry] Couldn't open Editor Window of type" + data); + Debug.LogException(e); + } + } + break; + } + } + + private static DefineableAction ParseForThryParser(string s) + { + return Parse(s); + } + public static DefineableAction Parse(string s) + { + s = s.Trim(); + DefineableAction action = new DefineableAction(); + if (s.StartsWith("http", StringComparison.Ordinal) || s.StartsWith("www", StringComparison.Ordinal)) + { + action.type = DefineableActionType.URL; + action.data = s; + } + else if (s.StartsWith("tag::", StringComparison.Ordinal)) + { + action.type = DefineableActionType.SET_TAG; + action.data = s.Replace("tag::", ""); + } + else if (s.StartsWith("shader=", StringComparison.Ordinal)) + { + action.type = DefineableActionType.SET_SHADER; + action.data = s.Replace("shader=", ""); + } + else if (s.Contains("=")) + { + action.type = DefineableActionType.SET_PROPERTY; + action.data = s; + } + else if (Regex.IsMatch(s, @"\w+(\.\w+)")) + { + action.type = DefineableActionType.OPEN_EDITOR; + action.data = s; + } + return action; + } + + public static DefineableAction ParseDrawerParameter(string s) + { + s = s.Trim(); + DefineableAction action = new DefineableAction(); + if (s.StartsWith("youtube#", StringComparison.Ordinal)) + { + action.type = DefineableActionType.URL; + action.data = "https://www.youtube.com/watch?v=" + s.Substring(8); + } + return action; + } + + public override string ToString() + { + return $"{{{type},{data}}}"; + } + } + + public enum DefineableActionType + { + NONE, + URL, + SET_PROPERTY, + SET_SHADER, + SET_TAG, + OPEN_EDITOR, + } + + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs.meta similarity index 83% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs.meta index 56ae27f6..34a61a1d 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs.meta +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableAction.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 86ee0d31fc0c2e740bb6237d6281a257 +guid: ebcfa24162368ab498a0a629447bdd5d MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs new file mode 100644 index 00000000..b93d03e2 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs @@ -0,0 +1,383 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class DefineableCondition + { + public DefineableConditionType type = DefineableConditionType.NONE; + public string data = ""; + public DefineableCondition condition1; + public DefineableCondition condition2; + + CompareType _compareType; + string _obj; + ShaderProperty _propertyObj; + Material _materialInsteadOfEditor; + + string _value; + float _floatValue; + + bool _hasConstantValue; + bool _constantValue; + + bool _isInit = false; + public void Init() + { + if (_isInit) return; + _hasConstantValue = true; + if (type == DefineableConditionType.NONE) { _constantValue = true; } + else if (type == DefineableConditionType.TRUE) { _constantValue = true; } + else if (type == DefineableConditionType.FALSE) { _constantValue = false; } + else + { + var (compareType, compareString) = GetComparetor(); + _compareType = compareType; + + string[] parts = Regex.Split(data, compareString); + _obj = parts[0].Trim(); + _value = parts[parts.Length - 1].Trim(); + + _floatValue = Parser.ParseFloat(_value); + if (ShaderEditor.Active != null && ShaderEditor.Active.PropertyDictionary.ContainsKey(_obj)) + _propertyObj = ShaderEditor.Active.PropertyDictionary[_obj]; + + if (type == DefineableConditionType.EDITOR_VERSION) InitEditorVersion(); + else if (type == DefineableConditionType.VRC_SDK_VERSION) InitVRCSDKVersion(); + else _hasConstantValue = false; + } + + _isInit = true; + } + + void InitEditorVersion() + { + int c_ev = Helper.CompareVersions(Config.Singleton.verion, _value); + if (_compareType == CompareType.EQUAL) _constantValue = c_ev == 0; + if (_compareType == CompareType.NOT_EQUAL) _constantValue = c_ev != 0; + if (_compareType == CompareType.SMALLER) _constantValue = c_ev == 1; + if (_compareType == CompareType.BIGGER) _constantValue = c_ev == -1; + if (_compareType == CompareType.BIGGER_EQ) _constantValue = c_ev == -1 || c_ev == 0; + if (_compareType == CompareType.SMALLER_EQ) _constantValue = c_ev == 1 || c_ev == 0; + } + + void InitVRCSDKVersion() + { + if (VRCInterface.Get().Sdk_information.type == VRCInterface.VRC_SDK_Type.NONE) + { + _constantValue = false; + return; + } + int c_vrc = Helper.CompareVersions(VRCInterface.Get().Sdk_information.installed_version, _value); + if (_compareType == CompareType.EQUAL) _constantValue = c_vrc == 0; + if (_compareType == CompareType.NOT_EQUAL) _constantValue = c_vrc != 0; + if (_compareType == CompareType.SMALLER) _constantValue = c_vrc == 1; + if (_compareType == CompareType.BIGGER) _constantValue = c_vrc == -1; + if (_compareType == CompareType.BIGGER_EQ) _constantValue = c_vrc == -1 || c_vrc == 0; + if (_compareType == CompareType.SMALLER_EQ) _constantValue = c_vrc == 1 || c_vrc == 0; + } + + public bool Test() + { + Init(); + if (_hasConstantValue) return _constantValue; + + MaterialProperty materialProperty = null; + switch (type) + { + case DefineableConditionType.PROPERTY_BOOL: + materialProperty = GetMaterialProperty(); + if (materialProperty == null) return false; + if (_compareType == CompareType.NONE) return materialProperty.GetNumber() == 1; + if (_compareType == CompareType.EQUAL) return materialProperty.GetNumber() == _floatValue; + if (_compareType == CompareType.NOT_EQUAL) return materialProperty.GetNumber() != _floatValue; + if (_compareType == CompareType.SMALLER) return materialProperty.GetNumber() < _floatValue; + if (_compareType == CompareType.BIGGER) return materialProperty.GetNumber() > _floatValue; + if (_compareType == CompareType.BIGGER_EQ) return materialProperty.GetNumber() >= _floatValue; + if (_compareType == CompareType.SMALLER_EQ) return materialProperty.GetNumber() <= _floatValue; + break; + case DefineableConditionType.TEXTURE_SET: + materialProperty = GetMaterialProperty(); + if (materialProperty == null) return false; + return (materialProperty.textureValue == null) == (_compareType == CompareType.EQUAL); + case DefineableConditionType.DROPDOWN: + materialProperty = GetMaterialProperty(); + if (materialProperty == null) return false; + if (_compareType == CompareType.NONE) return materialProperty.GetNumber() == 1; + if (_compareType == CompareType.EQUAL) return "" + materialProperty.GetNumber() == _value; + if (_compareType == CompareType.NOT_EQUAL) return "" + materialProperty.GetNumber() != _value; + break; + case DefineableConditionType.PROPERTY_IS_ANIMATED: + return ShaderOptimizer.IsAnimated(_materialInsteadOfEditor, _obj); + case DefineableConditionType.PROPERTY_IS_NOT_ANIMATED: + return !ShaderOptimizer.IsAnimated(_materialInsteadOfEditor, _obj); + case DefineableConditionType.AND: + if (condition1 != null && condition2 != null) return condition1.Test() && condition2.Test(); + break; + case DefineableConditionType.OR: + if (condition1 != null && condition2 != null) return condition1.Test() || condition2.Test(); + break; + case DefineableConditionType.NOT: + if (condition1 != null) return !condition1.Test(); + break; + } + + return true; + } + + private MaterialProperty GetMaterialProperty() + { + if (_materialInsteadOfEditor) return MaterialEditor.GetMaterialProperty(new Material[] { _materialInsteadOfEditor }, _obj); + if (_propertyObj != null) return _propertyObj.MaterialProperty; + return null; + } + private (CompareType, string) GetComparetor() + { + if (data.Contains("==")) + return (CompareType.EQUAL, "=="); + if (data.Contains("!=")) + return (CompareType.NOT_EQUAL, "!="); + if (data.Contains(">=")) + return (CompareType.BIGGER_EQ, ">="); + if (data.Contains("<=")) + return (CompareType.SMALLER_EQ, "<="); + if (data.Contains(">")) + return (CompareType.BIGGER, ">"); + if (data.Contains("<")) + return (CompareType.SMALLER, "<"); + return (CompareType.NONE, "##"); + } + + public override string ToString() + { + switch (type) + { + case DefineableConditionType.PROPERTY_BOOL: + return data; + case DefineableConditionType.EDITOR_VERSION: + return "EDITOR_VERSION" + data; + case DefineableConditionType.VRC_SDK_VERSION: + return "VRC_SDK_VERSION" + data; + case DefineableConditionType.TEXTURE_SET: + return "TEXTURE_SET" + data; + case DefineableConditionType.DROPDOWN: + return "DROPDOWN" + data; + case DefineableConditionType.PROPERTY_IS_ANIMATED: + return $"isAnimated({data})"; + case DefineableConditionType.PROPERTY_IS_NOT_ANIMATED: + return $"isNotAnimated({data})"; + case DefineableConditionType.AND: + if (condition1 != null && condition2 != null) return "(" + condition1.ToString() + "&&" + condition2.ToString() + ")"; + break; + case DefineableConditionType.OR: + if (condition1 != null && condition2 != null) return "(" + condition1.ToString() + "||" + condition2.ToString() + ")"; + break; + case DefineableConditionType.NOT: + if (condition1 != null) return "!" + condition1.ToString(); + break; + } + return ""; + } + + private static DefineableCondition ParseForThryParser(string s) + { + return Parse(s); + } + + private static readonly char[] ComparissionLiteralsToCheckFor = "*><=".ToCharArray(); + public static DefineableCondition Parse(string s, Material useThisMaterialInsteadOfOpenEditor = null, int start = 0, int end = -1) + { + if (end == -1) end = s.Length; + DefineableCondition con; + + // Debug.Log("Parsing: " + s.Substring(start, end - start)); + + int depth = 0; + int bracketStart = -1; + int bracketEnd = -1; + for (int i = start; i < end; i++) + { + char c = s[i]; + if (c == '(') + { + depth += 1; + if (depth == 1) + { + bracketStart = i; + } + } + else if (c == ')') + { + if (depth == 1) + { + bracketEnd = i; + } + depth -= 1; + } + else if (depth == 0) + { + if (c == '&') + { + con = new DefineableCondition(); + con._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; + + con.type = DefineableConditionType.AND; + con.condition1 = Parse(s, useThisMaterialInsteadOfOpenEditor, start, i); + con.condition2 = Parse(s, useThisMaterialInsteadOfOpenEditor, i + (s[i + 1] == '&' ? 2 : 1), end); + return con; + } + else if (c == '|') + { + + con = new DefineableCondition(); + con._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; + + con.type = DefineableConditionType.OR; + con.condition1 = Parse(s, useThisMaterialInsteadOfOpenEditor, start, i); + con.condition2 = Parse(s, useThisMaterialInsteadOfOpenEditor, i + (s[i + 1] == '|' ? 2 : 1), end); + return con; + } + } + } + + + bool isInverted = IsInverted(s, ref start); + + // if no AND or OR was found, check for brackets + if (bracketStart != -1 && bracketEnd != -1) + { + con = Parse(s, useThisMaterialInsteadOfOpenEditor, bracketStart + 1, bracketEnd); + } + else + { + con = ParseSingle(s.Substring(start, end - start), useThisMaterialInsteadOfOpenEditor); + } + + if (isInverted) + { + DefineableCondition inverted = new DefineableCondition(); + inverted._materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor; + inverted.type = DefineableConditionType.NOT; + inverted.condition1 = con; + return inverted; + } + + return con; + } + + static bool IsInverted(string s, ref int start) + { + for (int i = start; i < s.Length; i++) + { + if (s[i] == '!') + { + start += 1; + return true; + } + if (s[i] != ' ') + return false; + } + return false; + } + + static DefineableCondition ParseSingle(string s, Material useThisMaterialInsteadOfOpenEditor = null) + { + // Debug.Log("Parsing single: " + s); + + DefineableCondition con = new DefineableCondition + { + _materialInsteadOfEditor = useThisMaterialInsteadOfOpenEditor + }; + + if (s.IndexOfAny(ComparissionLiteralsToCheckFor) != -1) + { + //is a comparission + con.data = s; + con.type = DefineableConditionType.PROPERTY_BOOL; + if (s.StartsWith("VRCSDK", StringComparison.Ordinal)) + { + con.type = DefineableConditionType.VRC_SDK_VERSION; + con.data = s.Replace("VRCSDK", ""); + } + else if (s.StartsWith("ThryEditor", StringComparison.Ordinal)) + { + con.type = DefineableConditionType.EDITOR_VERSION; + con.data = s.Replace("ThryEditor", ""); + } + else if (IsTextureNullComparission(s, useThisMaterialInsteadOfOpenEditor)) + { + con.type = DefineableConditionType.TEXTURE_SET; + con.data = s.Replace("TEXTURE_SET", ""); + } + return con; + } + if (s.StartsWith("isNotAnimated(", StringComparison.Ordinal)) + { + con.type = DefineableConditionType.PROPERTY_IS_NOT_ANIMATED; + con.data = s.Replace("isNotAnimated(", "").TrimEnd(')'); + return con; + } + if (s.StartsWith("isAnimated(", StringComparison.Ordinal)) + { + con.type = DefineableConditionType.PROPERTY_IS_ANIMATED; + con.data = s.Replace("isAnimated(", "").TrimEnd(')'); + return con; + } + if (s.Equals("true", StringComparison.OrdinalIgnoreCase)) + { + con.type = DefineableConditionType.TRUE; + return con; + } + if (s.Equals("false", StringComparison.OrdinalIgnoreCase)) + { + con.type = DefineableConditionType.FALSE; + return con; + } + return con; + } + + static bool IsTextureNullComparission(string data, Material useThisMaterialInsteadOfOpenEditor = null) + { + // Check if property is a texture property && is checking for null + Material m = GetReferencedMaterial(useThisMaterialInsteadOfOpenEditor); + if (m == null) return false; + if (data.Length < 7) return false; + if (data.EndsWith("null") == false) return false; + string propertyName = data.Substring(0, data.Length - 6); + if (m.HasProperty(propertyName) == false) return false; + MaterialProperty p = MaterialEditor.GetMaterialProperty(new Material[] { m }, propertyName); + return p.type == MaterialProperty.PropType.Texture; + } + + static Material GetReferencedMaterial(Material useThisMaterialInsteadOfOpenEditor = null) + { + if (useThisMaterialInsteadOfOpenEditor != null) return useThisMaterialInsteadOfOpenEditor; + if (ShaderEditor.Active != null) return ShaderEditor.Active.Materials[0]; + return null; + } + } + + enum CompareType { NONE, BIGGER, SMALLER, EQUAL, NOT_EQUAL, BIGGER_EQ, SMALLER_EQ } + + public enum DefineableConditionType + { + NONE, + TRUE, + FALSE, + PROPERTY_BOOL, + PROPERTY_IS_ANIMATED, + PROPERTY_IS_NOT_ANIMATED, + EDITOR_VERSION, + VRC_SDK_VERSION, + TEXTURE_SET, + DROPDOWN, + AND, + OR, + NOT + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs.meta similarity index 83% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs.meta index b1a60c1c..caf5ded6 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs.meta +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DefineableCondition.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f835e027ceb24bf4b8607004ce304fa7 +guid: 98a174186ec8f814ab727fea67ceaa93 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs new file mode 100644 index 00000000..61493aeb --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class DrawingData + { + public static ShaderTextureProperty CurrentTextureProperty; + public static Rect LastGuiObjectRect; + public static Rect LastGuiObjectHeaderRect; + public static Rect TooltipCheckRect; + public static float[] IconsPositioningHeights = new float[4]; + public static float IconsPositioningCount = 1; + public static bool LastPropertyUsedCustomDrawer; + public static bool LastPropertyDoesntAllowAnimation; + public static MaterialPropertyDrawer LastPropertyDrawer; + public static List LastPropertyDecorators = new List(); + public static bool IsEnabled = true; + public static bool IsCollectingProperties = false; + + public static ShaderPart LastInitiatedPart; + + public static void ResetLastDrawerData() + { + LastPropertyUsedCustomDrawer = false; + LastPropertyDoesntAllowAnimation = false; + LastPropertyDrawer = null; + LastPropertyDecorators.Clear(); + } + + public static void RegisterDecorator(MaterialPropertyDrawer drawer) + { + if (IsCollectingProperties) + { + LastPropertyDecorators.Add(drawer); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs.meta new file mode 100644 index 00000000..6f13118f --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/DrawingData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58a93808da576b64d9fb0a6dfbeab9f1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs new file mode 100644 index 00000000..ea3e298c --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class PropertyOptions + { + public int offset = 0; + public string tooltip = ""; + public DefineableAction altClick; + public DefineableAction onClick; + public DefineableCondition condition_show = new DefineableCondition(); + public string condition_showS; + public DefineableCondition condition_enable = null; + public DefineableCondition condition_enable_children = null; + public PropertyValueAction[] on_value_actions; + public string on_value; + public DefineableAction[] actions; + public ButtonData button_help; + public TextureData texture; + public string[] reference_properties; + public string reference_property; + public bool force_texture_options = false; + public bool is_visible_simple = false; + public string file_name; + public string remote_version_url; + public string generic_string; + public bool never_lock; + public float margin_top = 0; + public string[] alts; + public bool persistent_expand = true; + public bool default_expand = false; + public bool ref_float_toggles_expand = true; + + public static PropertyOptions Deserialize(string s) + { + if (s == null) return new PropertyOptions(); + s = s.Replace("''", "\""); + PropertyOptions options = Parser.Deserialize(s); + if (options == null) return new PropertyOptions(); + // The following could be removed since the parser can now handle it. leaving it in for now /shrug + if (options.condition_showS != null) + { + options.condition_show = DefineableCondition.Parse(options.condition_showS); + } + if (options.on_value != null) + { + options.on_value_actions = PropertyValueAction.ParseToArray(options.on_value); + } + return options; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs.meta new file mode 100644 index 00000000..5da8f7fa --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyOptions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b7a65ee509ebb2740bb0ec6822ab0495 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs new file mode 100644 index 00000000..959baad5 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class PropertyValueAction + { + public string value; + public DefineableAction[] actions; + + public bool Execute(MaterialProperty p, Material[] targets) + { + if ( + (p.type == MaterialProperty.PropType.Float && p.floatValue.ToString() == value) || +#if UNITY_2022_1_OR_NEWER + (p.type == MaterialProperty.PropType.Int && p.intValue.ToString() == value) || +#endif + (p.type == MaterialProperty.PropType.Range && p.floatValue.ToString() == value) || + (p.type == MaterialProperty.PropType.Color && p.colorValue.ToString() == value) || + (p.type == MaterialProperty.PropType.Vector && p.vectorValue.ToString() == value) || + (p.type == MaterialProperty.PropType.Texture && ((p.textureValue == null) == (value == "0"))) || + (p.type == MaterialProperty.PropType.Texture && ((p.textureValue != null) == (value == "1"))) || + (p.type == MaterialProperty.PropType.Texture && (p.textureValue != null && p.textureValue.name == value)) + ) + { + ; + foreach (DefineableAction a in actions) + a.Perform(targets); + return true; + } + return false; + } + + private static PropertyValueAction ParseForThryParser(string s) + { + return Parse(s); + } + + // value,property1=value1,property2=value2 + public static PropertyValueAction Parse(string s) + { + s = s.Trim(); + string[] valueAndActions = s.Split(new string[] { "=>" }, System.StringSplitOptions.RemoveEmptyEntries); + if (valueAndActions.Length > 1) + { + PropertyValueAction propaction = new PropertyValueAction(); + propaction.value = valueAndActions[0]; + List actions = new List(); + string[] actionStrings = valueAndActions[1].Split(';'); + for (int i = 0; i < actionStrings.Length; i++) + { + if (string.IsNullOrWhiteSpace(actionStrings[i])) + continue; + actions.Add(DefineableAction.Parse(actionStrings[i])); + } + propaction.actions = actions.ToArray(); + return propaction; + } + return null; + } + + private static PropertyValueAction[] ParseToArrayForThryParser(string s) + { + return ParseToArray(s); + } + + public static PropertyValueAction[] ParseToArray(string s) + { + //s := 0=>p1=v1;p2=v2;1=>p1=v3... + List propactions = new List(); + string[] valueAndActionMatches = Regex.Matches(s, @"[^;]+=>.+?(?=(;[^;]+=>)|$)", RegexOptions.Multiline).Cast().Select(m => m.Value).ToArray(); + foreach (string p in valueAndActionMatches) + { + PropertyValueAction propertyValueAction = PropertyValueAction.Parse(p); + if (propertyValueAction != null) + propactions.Add(propertyValueAction); + } + return propactions.ToArray(); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs.meta new file mode 100644 index 00000000..6c0ee592 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/PropertyValueAction.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be3d401237c59b1479ca24b62d48d203 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs new file mode 100644 index 00000000..0a3766bf --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; + +namespace Thry +{ + public class TextureData + { + public string name = null; + public string guid = null; + public int width = 128; + public int height = 128; + + public char channel = 'r'; + + public int ansioLevel = 1; + public FilterMode filterMode = FilterMode.Bilinear; + public TextureWrapMode wrapMode = TextureWrapMode.Repeat; + public bool center_position = false; + bool _isLoading; + + public void ApplyModes(Texture texture) + { + texture.filterMode = filterMode; + texture.wrapMode = wrapMode; + texture.anisoLevel = ansioLevel; + } + public void ApplyModes(string path) + { + TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(path); + importer.filterMode = filterMode; + importer.wrapMode = wrapMode; + importer.anisoLevel = ansioLevel; + importer.SaveAndReimport(); + } + + static Dictionary s_loaded_textures = new Dictionary(); + public Texture loaded_texture + { + get + { + if (guid != null) + { + if (!s_loaded_textures.ContainsKey(guid) || s_loaded_textures[guid] == null) + { + string path = AssetDatabase.GUIDToAssetPath(guid); + if (path != null) + s_loaded_textures[guid] = AssetDatabase.LoadAssetAtPath(path); + else + s_loaded_textures[guid] = Texture2D.whiteTexture; + } + return s_loaded_textures[guid]; + } + else if (name != null) + { + if (!s_loaded_textures.ContainsKey(name) || s_loaded_textures[name] == null) + { + // Retrieve downloaded image from sessionstate (base64 encoded) + if (SessionState.GetString(name, "") != "") + { + s_loaded_textures[name] = new Texture2D(1, 1, TextureFormat.ARGB32, false); + ImageConversion.LoadImage((Texture2D)s_loaded_textures[name], Convert.FromBase64String(SessionState.GetString(name, "")), false); + return s_loaded_textures[name]; + } + + if (IsUrl()) + { + if (!_isLoading) + { + s_loaded_textures[name] = Texture2D.whiteTexture; + WebHelper.DownloadBytesASync(name, (byte[] b) => + { + _isLoading = false; + Texture2D tex = new Texture2D(1, 1, TextureFormat.ARGB32, false); + ImageConversion.LoadImage(tex, b, false); + s_loaded_textures[name] = tex; + SessionState.SetString(name, Convert.ToBase64String(((Texture2D)s_loaded_textures[name]).EncodeToPNG())); + }); + _isLoading = true; + } + } + else + { + string path = FileHelper.FindFile(name, "texture"); + if (path != null) + s_loaded_textures[name] = AssetDatabase.LoadAssetAtPath(path); + else + s_loaded_textures[name] = Texture2D.whiteTexture; + } + } + return s_loaded_textures[name]; + } + return Texture2D.whiteTexture; + } + } + + private static TextureData ParseForThryParser(string s) + { + if (s.StartsWith("{") == false) + { + return new TextureData() + { + name = s + }; + } + return Parser.Deserialize(s); + } + + bool IsUrl() + { + return name.StartsWith("http") && (name.EndsWith(".jpg") || name.EndsWith(".png")); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs.meta new file mode 100644 index 00000000..04175903 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DataStructs/TextureData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 30003c406bcbdf54aa677bc138097652 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalSceneTool.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalSceneTool.cs index b123f6e7..ce56cfe0 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalSceneTool.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalSceneTool.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Runtime.Remoting.Messaging; using UnityEditor; using UnityEngine; @@ -17,6 +18,7 @@ public class DecalSceneTool private Mesh _mesh; private Vector2[][] _uvTriangles; private Vector3[][] _worldTriangles; + private Vector3[][] _worldNormals; private bool _isActive; private Mode _mode = Mode.None; private HandleMode _handleMode = HandleMode.Position; @@ -101,10 +103,11 @@ void OnSelectionChange() void Init() { - // EditorUtility.DisplayProgressBar("Decal Tool", "Loading Mesh...", 0.0f); GetMesh(); + _uvTriangles = new Vector2[_mesh.triangles.Length / 3][]; _worldTriangles = new Vector3[_mesh.triangles.Length / 3][]; + _worldNormals = new Vector3[_mesh.triangles.Length / 3][]; int[] triangles = _mesh.triangles; Vector2[] uvs; if(_uvIndex == 1) uvs = _mesh.uv2; @@ -117,20 +120,24 @@ void Init() bool isSMR = _renderer is SkinnedMeshRenderer; for(int i = 0; i < triangles.Length; i += 3) { - // if(i%100 == 0) EditorUtility.DisplayProgressBar("Decal Tool", "Loading Mesh...", (float)i / triangles.Length); _uvTriangles[i / 3] = new Vector2[3]; _worldTriangles[i / 3] = new Vector3[3]; - for(int j = 0; j < 3; j++) + _worldNormals[i / 3] = new Vector3[3]; + for (int j = 0; j < 3; j++) { _uvTriangles[i / 3][j] = uvs[triangles[i + j]]; if(isSMR) + { _worldTriangles[i / 3][j] = root.TransformPoint(Vector3.Scale(vertices[triangles[i + j]], inverseScale)); + _worldNormals[i / 3][j] = root.TransformDirection(_mesh.normals[triangles[i + j]]); + } else + { _worldTriangles[i / 3][j] = root.TransformPoint(vertices[triangles[i + j]]); - // _worldTriangles[i / 3][j] = vertices[triangles[i + j]]; + _worldNormals[i / 3][j] = _mesh.normals[triangles[i + j]]; + } } } - // EditorUtility.ClearProgressBar(); } private void OnSceneGUI(SceneView sceneView) @@ -215,18 +222,20 @@ void PositionMode(SceneView sceneView) { gizmoNormal = -_pivotNormal; } - Quaternion rotation = Quaternion.LookRotation(gizmoNormal, _pivotUp); - if(Tools.pivotRotation == PivotRotation.Local) + Vector3 up = _pivotUp; + if (Tools.pivotRotation == PivotRotation.Local) { - rotation *= Quaternion.Euler(0, 0, -_propRotation.floatValue); + up = Quaternion.AngleAxis(-_propRotation.floatValue, gizmoNormal) * up; } - + + Quaternion rotation = Quaternion.LookRotation(gizmoNormal, up); + Vector3 moved = Handles.PositionHandle(_pivotPoint, rotation); if(moved != _pivotPoint) { Vector2 uv = Vector2.zero; - Ray ray = new Ray(moved - _pivotNormal * 0.1f, _pivotNormal); + Ray ray = new Ray(moved - gizmoNormal * 0.1f, gizmoNormal); if(RaycastToClosestUV(ray, ref uv)) { _propPosition.vectorValue = uv; @@ -317,6 +326,7 @@ void OffsetMode(SceneView sceneView) Vector3 _pivotPoint; Vector3 _pivotNormal; Vector3 _pivotUp; + void GetPivot() { _pivotPoint = Vector3.zero; @@ -327,25 +337,26 @@ void GetPivot() // uv position to world position using renderer mesh for(int i=0; i<_worldTriangles.Length;i++) { - Vector2[] uvTriangle = _uvTriangles[i]; - float a = TriangleArea(uvTriangle[0], uvTriangle[1], uvTriangle[2]); + Vector2[] triUVcoords = _uvTriangles[i]; + float a = TriangleArea(triUVcoords[0], triUVcoords[1], triUVcoords[2]); if(a == 0) continue; // check if uv is inside uvTriangle - float a1 = TriangleArea(uvTriangle[1], uvTriangle[2], uv) / a; + float a1 = TriangleArea(triUVcoords[1], triUVcoords[2], uv) / a; if(a1 < 0) continue; - float a2 = TriangleArea(uvTriangle[2], uvTriangle[0], uv) / a; + float a2 = TriangleArea(triUVcoords[2], triUVcoords[0], uv) / a; if(a2 < 0) continue; - float a3 = TriangleArea(uvTriangle[0], uvTriangle[1], uv) / a; + float a3 = TriangleArea(triUVcoords[0], triUVcoords[1], uv) / a; if(a3 < 0) continue; // get a1, a2, a3 of uv up - float a1Up = TriangleArea(uvTriangle[1], uvTriangle[2], uvUp) / a; - float a2Up = TriangleArea(uvTriangle[2], uvTriangle[0], uvUp) / a; - float a3Up = TriangleArea(uvTriangle[0], uvTriangle[1], uvUp) / a; + float a1Up = TriangleArea(triUVcoords[1], triUVcoords[2], uvUp) / a; + float a2Up = TriangleArea(triUVcoords[2], triUVcoords[0], uvUp) / a; + float a3Up = TriangleArea(triUVcoords[0], triUVcoords[1], uvUp) / a; // point inside the triangle - find mesh position by interpolation - Vector3[] triangle = _worldTriangles[i]; - _pivotPoint = triangle[0] * a1 + triangle[1] * a2 + triangle[2] * a3; - _pivotNormal = Vector3.Cross(triangle[1] - triangle[0], triangle[2] - triangle[0]).normalized; - _pivotUp = (triangle[0] * a1Up + triangle[1] * a2Up + triangle[2] * a3Up - _pivotPoint).normalized; + Vector3[] triVertices = _worldTriangles[i]; + Vector3[] triNormals = _worldNormals[i]; + _pivotPoint = triVertices[0] * a1 + triVertices[1] * a2 + triVertices[2] * a3; + _pivotNormal = triNormals[0] * a1 + triNormals[1] * a2 + triNormals[2] * a3; + _pivotUp = (triVertices[0] * a1Up + triVertices[1] * a2Up + triVertices[2] * a3Up - _pivotPoint).normalized; return; } } diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalTool.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalTool.cs index c20d9ebe..5a52d48e 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalTool.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/DecalTool.cs @@ -37,13 +37,15 @@ public void SetMaterialProperties(MaterialProperty decalProp, MaterialProperty u private void OnGUI() { - if(_propPosition == null) + if(_propPosition == null || _material.mainTexture == null) { return; } HandleInput(); - // EditorGUI.DrawPreviewTexture(new Rect(0, 0, position.width, position.height), _material.mainTexture, _material); - EditorGUI.DrawTextureTransparent(new Rect(0, 0, position.width, position.height), _material.mainTexture, ScaleMode.StretchToFill); + if(_material.mainTexture == null) + EditorGUI.DrawTextureTransparent(new Rect(0, 0, position.width, position.height), Texture2D.grayTexture, ScaleMode.StretchToFill); + else + EditorGUI.DrawTextureTransparent(new Rect(0, 0, position.width, position.height), _material.mainTexture, ScaleMode.StretchToFill); _gizmoMaterial.SetVector("_Position", _propPosition.vectorValue); _gizmoMaterial.SetVector("_Scale", _propScale.vectorValue); _gizmoMaterial.SetFloat("_Rotation", _propRotation.floatValue); diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators.meta new file mode 100644 index 00000000..4285915e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6a4ed387d759fdd4eaaa476b878ebd2c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs new file mode 100644 index 00000000..5a8b75f6 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class DoNotAnimateDecorator : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) { } + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyDoesntAllowAnimation = true; + return 0; + } + } + + // Made an upsi, this existed already when I made [DoNotAnimate] + public class NoAnimateDecorator : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyDoesntAllowAnimation = true; + return 0; + } + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs.meta new file mode 100644 index 00000000..961a957d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/DoNotAnimate.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 95a8bded0e22dee48b4c64b98343dabd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs new file mode 100644 index 00000000..1d8b7df8 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryDecalPositioningDecorator : MaterialPropertyDrawer + { + string _texturePropertyName; + string _uvIndexPropertyName; + string _positionPropertyName; + string _rotationPropertyName; + string _scalePropertyName; + string _offsetPropertyName; + DecalSceneTool _sceneTool; + DecalTool _tool; + + public ThryDecalPositioningDecorator(string textureProp, string uvIndexPropertyName, string positionProp, string rotationProp, string scaleProp, string offsetProp) + { + _texturePropertyName = textureProp; + _uvIndexPropertyName = uvIndexPropertyName; + _positionPropertyName = positionProp; + _rotationPropertyName = rotationProp; + _offsetPropertyName = offsetProp; + _scalePropertyName = scaleProp; + } + + void CreateSceneTool() + { + DiscardSceneTool(); + _sceneTool = DecalSceneTool.Create( + Selection.activeTransform.GetComponent(), + ShaderEditor.Active.Materials[0], + (int)ShaderEditor.Active.PropertyDictionary[_uvIndexPropertyName].MaterialProperty.GetNumber(), + ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); + } + + void DiscardSceneTool() + { + if (_sceneTool != null) + { + _sceneTool.Deactivate(); + _sceneTool = null; + } + } + + public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) + { + position = new RectOffset(0, 0, 0, 3).Remove(EditorGUI.IndentedRect(position)); + bool isInScene = Selection.activeTransform != null && Selection.activeTransform.GetComponent() != null; + if (isInScene) + { + position.width /= 3; + ButtonGUI(position); + position.x += position.width; + ButtonRaycast(position); + position.x += position.width; + ButtonSceneTools(position); + if (_sceneTool != null) + { + _sceneTool.SetMaterialProperties( + ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); + } + } + else + { + ButtonGUI(position); + } + } + + void ButtonGUI(Rect r) + { + if (GUI.Button(r, "Open Positioning Tool")) + { + _tool = DecalTool.OpenDecalTool(ShaderEditor.Active.Materials[0]); + } + // This is done because the tool didnt want to update if the data was changed from the outside + if (_tool != null) + { + _tool.SetMaterialProperties( + ShaderEditor.Active.PropertyDictionary[_texturePropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_uvIndexPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, + ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); + } + } + + void ButtonRaycast(Rect r) + { + if (GUI.Button(r, "Raycast")) + { + if (_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Raycast) + { + DiscardSceneTool(); + } + else + { + CreateSceneTool(); + _sceneTool.StartRaycastMode(); + } + } + if (_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Raycast) + GUI.DrawTexture(r, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f), 0, 3); + } + + void ButtonSceneTools(Rect r) + { + if (GUI.Button(r, "Scene Tools")) + { + if (_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Handles) + { + DiscardSceneTool(); + } + else + { + CreateSceneTool(); + _sceneTool.StartHandleMode(); + } + } + if (_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Handles) + GUI.DrawTexture(r, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f), 0, 3); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + DrawingData.LastPropertyDoesntAllowAnimation = false; + return EditorGUIUtility.singleLineHeight + 6; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs.meta new file mode 100644 index 00000000..d81da566 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryDecalPositioning.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 667b0a04661f4ac438774f7f0037888a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs new file mode 100644 index 00000000..f21d8eb6 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryHeaderLabelDecorator : MaterialPropertyDrawer + { + readonly string _text; + readonly int _size; + GUIStyle _style; + + public ThryHeaderLabelDecorator(string text) : this(text, EditorStyles.standardFont.fontSize) + { + } + public ThryHeaderLabelDecorator(string text, float size) + { + this._text = text; + this._size = (int)size; + } + + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.RegisterDecorator(this); + return _size + 6; + } + + public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) + { + // Done here instead of constructor because else unity throws warnings + if (_style == null) + { + _style = new GUIStyle(EditorStyles.boldLabel); + _style.fontSize = this._size; + } + + float offst = position.height; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, _text, _style); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs.meta new file mode 100644 index 00000000..1e0e4bda --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThryHeaderLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9c2765b9a4096d54aaaf056e543a3876 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs new file mode 100644 index 00000000..79d540f2 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThrySeperatorDecorator : MaterialPropertyDrawer + { + Color _color = Styles.COLOR_FG; + + public ThrySeperatorDecorator() { } + public ThrySeperatorDecorator(string c) + { + ColorUtility.TryParseHtmlString(c, out _color); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.RegisterDecorator(this); + return 1; + } + + public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) + { + position = EditorGUI.IndentedRect(position); + EditorGUI.DrawRect(position, _color); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs.meta new file mode 100644 index 00000000..8dd2b4d9 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/ThrySeperator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 47cc536798dc989489edd36ea458276b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs new file mode 100644 index 00000000..d00d7fe3 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class sRGBWarningDecorator : MaterialPropertyDrawer + { + bool _isSRGB = true; + + public sRGBWarningDecorator() + { + _isSRGB = false; + } + + public sRGBWarningDecorator(string shouldHaveSRGB) + { + this._isSRGB = shouldHaveSRGB.ToLower() == "true"; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + if (Config.Singleton.showColorspaceWarnings) + GUILib.ColorspaceWarning(prop, _isSRGB); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.RegisterDecorator(this); + return 0; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs.meta new file mode 100644 index 00000000..d4988a23 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Decorators/sRGBWarning.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cf1e7e0950d8b7543ab6a3e88afd1332 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs deleted file mode 100644 index fe4f80cc..00000000 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.cs +++ /dev/null @@ -1,2115 +0,0 @@ -// Material/Shader Inspector for Unity 2017/2018 -// Copyright (C) 2019 Thryrallo - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using UnityEditor; -using UnityEngine; - -namespace Thry -{ - #region Texture Drawers - public class ThryTextureDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.ConfigTextureProperty(position, prop, label, editor, ((TextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class SmallTextureDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.SmallTextureProperty(position, prop, label, editor, ((TextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - // For backwards compatibility - public class BigTextureDrawer : SimpleLargeTextureDrawer - { - - } - - // For backwards compatibility - public class StylizedBigTextureDrawer : StylizedLargeTextureDrawer - { - - } - - public class SimpleLargeTextureDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.BigTexturePropertyBasic(position, prop, label, editor, ((TextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class StylizedLargeTextureDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.StylizedBigTextureProperty(position, prop, label, editor, ((TextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - #endregion - - #region Special Texture Drawers - public class CurveDrawer : MaterialPropertyDrawer - { - public AnimationCurve curve; - public EditorWindow window; - public Texture2D texture; - public bool saved = true; - public TextureData imageData; - - public CurveDrawer() - { - curve = new AnimationCurve(); - } - - private void Init() - { - if (imageData == null) - { - if (ShaderEditor.Active.CurrentProperty.Options.texture == null) - imageData = new TextureData(); - else - imageData = ShaderEditor.Active.CurrentProperty.Options.texture; - } - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - Init(); - Rect border_position = new Rect(position.x + EditorGUIUtility.labelWidth - 15, position.y, position.width - EditorGUIUtility.labelWidth + 15 - GuiHelper.GetSmallTextureVRAMWidth(prop), position.height); - - EditorGUI.BeginChangeCheck(); - curve = EditorGUI.CurveField(border_position, curve); - if (EditorGUI.EndChangeCheck()) - { - UpdateCurveTexture(prop); - } - - GuiHelper.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); - - CheckWindowForCurveEditor(); - - if (window == null && !saved) - Save(prop); - } - - private void UpdateCurveTexture(MaterialProperty prop) - { - texture = Converter.CurveToTexture(curve, imageData); - prop.textureValue = texture; - saved = false; - } - - private void CheckWindowForCurveEditor() - { - string windowName = ""; - if (EditorWindow.focusedWindow != null) - windowName = EditorWindow.focusedWindow.titleContent.text; - bool isCurveEditor = windowName == "Curve"; - if (isCurveEditor) - window = EditorWindow.focusedWindow; - } - - private void Save(MaterialProperty prop) - { - Debug.Log(prop.textureValue.ToString()); - Texture saved_texture = TextureHelper.SaveTextureAsPNG(texture, PATH.TEXTURES_DIR + "curves/" + curve.GetHashCode() + ".png", null); - prop.textureValue = saved_texture; - saved = true; - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - public class ThryExternalTextureToolDrawer : MaterialPropertyDrawer - { - string _toolTypeName; - string _toolHeader; - - Type t_ExternalToolType; - MethodInfo _onGui; - object _externalTool; - MaterialProperty _prop; - - bool _isTypeLoaded; - bool _doesExternalTypeExist; - bool _isInit; - bool _showTool; - - public ThryExternalTextureToolDrawer(string toolHeader, string toolTypeName) - { - this._toolTypeName = toolTypeName; - this._toolHeader = toolHeader; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - LoadType(); - if (_doesExternalTypeExist) - { - _prop = prop; - GuiHelper.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties, ExternalGUI); - } - else - { - GuiHelper.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); - } - } - - void ExternalGUI() - { - if (GUI.Button(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), _toolHeader)) _showTool = !_showTool; - if (_showTool) - { - Init(); - - int indent = EditorGUI.indentLevel; - GuiHelper.BeginCustomIndentLevel(0); - GUILayout.BeginHorizontal(); - GUILayout.Space(indent * 15); - GUILayout.BeginVertical(); - _onGui.Invoke(_externalTool, new object[0]); - GUILayout.EndVertical(); - GUILayout.EndHorizontal(); - GuiHelper.EndCustomIndentLevel(); - } - } - - public void LoadType() - { - if (_isTypeLoaded) return; - t_ExternalToolType = AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetType(_toolTypeName)).Where(t => t != null).FirstOrDefault(); - _doesExternalTypeExist = t_ExternalToolType != null; - _isTypeLoaded = true; - } - - public void Init() - { - if (_isInit) return; - if (_isTypeLoaded && _doesExternalTypeExist) - { - _onGui = t_ExternalToolType.GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance); - _externalTool = ScriptableObject.CreateInstance(t_ExternalToolType); - EventInfo eventTextureGenerated = t_ExternalToolType.GetEvent("TextureGenerated"); - if (eventTextureGenerated != null) - eventTextureGenerated.AddEventHandler(_externalTool, new EventHandler(TextureGenerated)); - } - _isInit = true; - } - - void TextureGenerated(object sender, EventArgs args) - { - if (args != null && args.GetType().GetField("generated_texture") != null) - { - Texture2D generated = args.GetType().GetField("generated_texture").GetValue(args) as Texture2D; - _prop.textureValue = generated; - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class ThryRGBAPackerDrawer : MaterialPropertyDrawer - { - // TODO : Load lacale by property name in the future: propname_r, propname_g, propname_b, propname_a - class ThryRGBAPackerData - { - public Texture _previousTexture; - public Texture2D _packedTexture; - - public InlinePackerChannelConfig _input_r; - public InlinePackerChannelConfig _input_g; - public InlinePackerChannelConfig _input_b; - public InlinePackerChannelConfig _input_a; - - public bool _isInit; - public bool _hasConfigChanged; - public bool _hasTextureChanged; - public long _lastConfirmTime; - - public TexturePacker.Connection[] _connections; - public TexturePacker.TextureSource[] _sources; - } - - Dictionary materialPackerData = new Dictionary(); - - MaterialProperty _prop; - ThryRGBAPackerData _current; - - string _label1; - string _label2; - string _label3; - string _label4; - bool _firstTextureIsRGB; - ColorSpace _colorSpace = ColorSpace.Gamma; - bool _alphaIsTransparency = true; - - // for locale changing - // i tried using an array to save the default labels, but the data just got lost somewhere. not sure why - string _defaultLabel1; - string _defaultLabel2; - string _defaultLabel3; - string _defaultLabel4; - int _reloadCount = -1; - static int _reloadCountStatic; - - public static void Reload() - { - _reloadCountStatic++; - } - - void LoadLabels() - { - if (_reloadCount == _reloadCountStatic) return; - // using the string itself as a key for reuse in other places. this might cause issues, if it does in the future - // we can add the class name as a prefix to the key - _label1 = ShaderEditor.Active.Locale.Get(_defaultLabel1, _defaultLabel1); - _label2 = ShaderEditor.Active.Locale.Get(_defaultLabel2, _defaultLabel2); - _label3 = ShaderEditor.Active.Locale.Get(_defaultLabel3, _defaultLabel3); - _label4 = ShaderEditor.Active.Locale.Get(_defaultLabel4, _defaultLabel4); - _reloadCount = _reloadCountStatic; - } - - // end locale changing - - public ThryRGBAPackerDrawer(string label1, string label2, string label3, string label4, string colorspace, string alphaIsTransparency) - { - _label1 = string.IsNullOrWhiteSpace(label1) ? null : label1; - _label2 = string.IsNullOrWhiteSpace(label2) ? null : label2; - _label3 = string.IsNullOrWhiteSpace(label3) ? null : label3; - _label4 = string.IsNullOrWhiteSpace(label4) ? null : label4; - _defaultLabel1 = _label1; - _defaultLabel2 = _label2; - _defaultLabel3 = _label3; - _defaultLabel4 = _label4; - _colorSpace = (colorspace == "linear" || colorspace == "Linear") ? ColorSpace.Linear : ColorSpace.Gamma; - _alphaIsTransparency = alphaIsTransparency == "true" || alphaIsTransparency == "True"; - } - - public ThryRGBAPackerDrawer(string label1, string label2, string colorspace, string alphaIsTransparency) : this(label1, label2, null, null, colorspace, alphaIsTransparency) - { - _firstTextureIsRGB = true; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - _prop = prop; - if (materialPackerData.ContainsKey(_prop.targets[0]) == false) materialPackerData[_prop.targets[0]] = new ThryRGBAPackerData(); - _current = materialPackerData[_prop.targets[0]]; - GuiHelper.SmallTextureProperty(position, prop, label, editor, true, TexturePackerGUI); - if (_prop.textureValue != _current._packedTexture) _current._previousTexture = _prop.textureValue; - } - - bool DidTextureGetEdit(InlinePackerChannelConfig data) - { - if (data.TextureSource.Texture == null) return false; - string path = AssetDatabase.GetAssetPath(data.TextureSource.Texture); - if (System.IO.File.Exists(path) == false) return false; - long lastEditTime = Helper.DatetimeToUnixSeconds(System.IO.File.GetLastWriteTime(path)); - bool hasBeenEdited = lastEditTime > _current._lastConfirmTime && lastEditTime != data.TextureSource.LastHandledTextureEditTime; - data.TextureSource.LastHandledTextureEditTime = lastEditTime; - if (hasBeenEdited) TexturePacker.TextureSource.SetUncompressedTextureDirty(data.TextureSource.Texture); - return hasBeenEdited; - } - - void TexturePackerGUI() - { - Init(); - LoadLabels(); - EditorGUI.BeginChangeCheck(); - _current._input_r = TexturePackerSlotGUI(_current._input_r, _label1); - _current._input_g = TexturePackerSlotGUI(_current._input_g, _label2); - if (_label3 != null) _current._input_b = TexturePackerSlotGUI(_current._input_b, _label3); - if (_label4 != null) _current._input_a = TexturePackerSlotGUI(_current._input_a, _label4); - bool changeCheck = EditorGUI.EndChangeCheck(); - changeCheck |= DidTextureGetEdit(_current._input_r); - changeCheck |= DidTextureGetEdit(_current._input_g); - changeCheck |= DidTextureGetEdit(_current._input_b); - changeCheck |= DidTextureGetEdit(_current._input_a); - if (changeCheck) - { - _current._hasConfigChanged = true; - Save(); - Pack(); - } - - Rect buttonRect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()); - buttonRect.width /= 3; - EditorGUI.BeginDisabledGroup(!_current._hasConfigChanged); - if (GUI.Button(buttonRect, "Confirm Merge")) Confirm(); - buttonRect.x += buttonRect.width; - EditorGUI.EndDisabledGroup(); - EditorGUI.BeginDisabledGroup(!_current._hasTextureChanged); - if (GUI.Button(buttonRect, "Revert")) Revert(); - EditorGUI.EndDisabledGroup(); - buttonRect.x += buttonRect.width; - if (GUI.Button(buttonRect, "Advanced")) OpenFullTexturePacker(); - } - - InlinePackerChannelConfig TexturePackerSlotGUI(InlinePackerChannelConfig input, string label) - { - Rect totalRect = EditorGUILayout.GetControlRect(false); - totalRect = EditorGUI.IndentedRect(totalRect); - Rect r = totalRect; - - int ind = EditorGUI.indentLevel; - EditorGUI.indentLevel = 0; - - float texWidth = Math.Max(50, r.width - 130 - 30) - 5; - r.x = totalRect.x; - r.width = 30; - EditorGUI.BeginChangeCheck(); - Texture2D changed = EditorGUI.ObjectField(r, input.TextureSource.Texture, typeof(Texture2D), false) as Texture2D; - if (EditorGUI.EndChangeCheck()) - { - input.TextureSource.SetTexture(changed); - } - - r.x += r.width + 5; - r.width = texWidth - 5; - EditorGUI.LabelField(r, label); - - if (input.TextureSource.Texture == null) - { - r.width = 70; - r.x = totalRect.x + totalRect.width - r.width; - input.Fallback = EditorGUI.FloatField(r, input.Fallback); - - r.width = 60; - r.x -= r.width; - EditorGUI.LabelField(r, "Fallback:"); - } - else - { - r.width = 50; - r.x = totalRect.x + totalRect.width - r.width; - if (!_firstTextureIsRGB || input != _current._input_r) - input.Channel = (TexturePacker.TextureChannelIn)EditorGUI.EnumPopup(r, input.Channel); - - r.width = 20; - r.x -= r.width; - input.Invert = EditorGUI.Toggle(r, input.Invert); - - r.width = 60; - r.x -= r.width; - EditorGUI.LabelField(r, "Inverted:"); - } - - EditorGUI.indentLevel = ind; - - return input; - } - - void Init() - { - if (_current._isInit) return; - _current._input_r = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "r"); - _current._input_g = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "g"); - _current._input_b = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "b"); - _current._input_a = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "a"); - _current._lastConfirmTime = long.Parse(ShaderEditor.Active.Materials[0].GetTag(_prop.name + "_texPack_lastConfirmTime", false, "" + Helper.DatetimeToUnixSeconds(DateTime.Now))); - _current._previousTexture = _prop.textureValue; - _current._isInit = true; - } - - void Save() - { - SaveForChannel(_current._input_r, _prop.name, "r"); - SaveForChannel(_current._input_g, _prop.name, "g"); - SaveForChannel(_current._input_b, _prop.name, "b"); - SaveForChannel(_current._input_a, _prop.name, "a"); - foreach (Material m in ShaderEditor.Active.Materials) - { - m.SetOverrideTag(_prop.name + "_texPack_lastConfirmTime", "" + _current._lastConfirmTime); - } - } - - void SaveForChannel(InlinePackerChannelConfig input, string id, string channel) - { - foreach (Material m in ShaderEditor.Active.Materials) - { - if (input.TextureSource.Texture != null) m.SetOverrideTag(id + "_texPack_" + channel + "_guid", AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(input.TextureSource.Texture))); - else m.SetOverrideTag(id + "_texPack_" + channel + "_guid", ""); - m.SetOverrideTag(id + "_texPack_" + channel + "_fallback", input.Fallback.ToString()); - m.SetOverrideTag(id + "_texPack_" + channel + "_inverted", input.Invert.ToString()); - m.SetOverrideTag(id + "_texPack_" + channel + "_channel", ((int)input.Channel).ToString()); - } - } - - InlinePackerChannelConfig LoadForChannel(Material m, string id, string channel) - { - InlinePackerChannelConfig packerChannelConfig = new InlinePackerChannelConfig(); - packerChannelConfig.Fallback = float.Parse(m.GetTag(id + "_texPack_" + channel + "_fallback", false, "1")); - packerChannelConfig.Invert = bool.Parse(m.GetTag(id + "_texPack_" + channel + "_inverted", false, "false")); - packerChannelConfig.Channel = (TexturePacker.TextureChannelIn)int.Parse(m.GetTag(id + "_texPack_" + channel + "_channel", false, "4")); - string guid = m.GetTag(id + "_texPack_" + channel + "_guid", false, ""); - if (string.IsNullOrEmpty(guid) == false) - { - string p = AssetDatabase.GUIDToAssetPath(guid); - if (p != null) - packerChannelConfig.TextureSource.SetTexture(AssetDatabase.LoadAssetAtPath(p)); - } - return packerChannelConfig; - } - - void Pack() - { - _current._packedTexture = TexturePacker.Pack(GetTextureSources(), GetOutputConfigs(), GetConnections(), GetFiltermode(), _colorSpace, alphaIsTransparency: _alphaIsTransparency); - _prop.textureValue = _current._packedTexture; - - _current._hasTextureChanged = true; - } - - TexturePacker.TextureSource[] GetTextureSources() - { - // build sources array - return new TexturePacker.TextureSource[4]{ - _current._input_r.TextureSource, _current._input_g.TextureSource, _current._input_b.TextureSource, _current._input_a.TextureSource }; - } - - TexturePacker.OutputConfig[] GetOutputConfigs() - { - // Build OutputConfig Array - TexturePacker.OutputConfig[] outputConfigs = new TexturePacker.OutputConfig[4]; - - if (_firstTextureIsRGB) - { - outputConfigs[0] = _current._input_r.ToOutputConfig(); - outputConfigs[1] = _current._input_r.ToOutputConfig(); - outputConfigs[2] = _current._input_r.ToOutputConfig(); - outputConfigs[3] = _current._input_g.ToOutputConfig(); - } - else - { - outputConfigs[0] = _current._input_r.ToOutputConfig(); - outputConfigs[1] = _current._input_g.ToOutputConfig(); - outputConfigs[2] = _current._input_b.ToOutputConfig(); - outputConfigs[3] = _current._input_a.ToOutputConfig(); - } - return outputConfigs; - } - - TexturePacker.Connection[] GetConnections() - { - // Build connections array - TexturePacker.Connection[] connections = new TexturePacker.Connection[4]; - if (_firstTextureIsRGB) - { - connections[0] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.R, TexturePacker.TextureChannelOut.R); - connections[1] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.G, TexturePacker.TextureChannelOut.G); - connections[2] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.B, TexturePacker.TextureChannelOut.B); - connections[3] = TexturePacker.Connection.CreateFull(1, _current._input_g.Channel, TexturePacker.TextureChannelOut.A); - } - else - { - connections[0] = TexturePacker.Connection.CreateFull(0, _current._input_r.Channel, TexturePacker.TextureChannelOut.R); - connections[1] = TexturePacker.Connection.CreateFull(1, _current._input_g.Channel, TexturePacker.TextureChannelOut.G); - connections[2] = TexturePacker.Connection.CreateFull(2, _current._input_b.Channel, TexturePacker.TextureChannelOut.B); - connections[3] = TexturePacker.Connection.CreateFull(3, _current._input_a.Channel, TexturePacker.TextureChannelOut.A); - } - return connections; - } - - void OpenFullTexturePacker() - { - TexturePacker packer = TexturePacker.ShowWindow(); - packer.InitilizeWithData(GetTextureSources(), GetOutputConfigs(), GetConnections(), GetFiltermode(), _colorSpace, _alphaIsTransparency); - packer.OnChange += FullTexturePackerOnChange; - packer.OnSave += FullTexturePackerOnSave; - } - - void FullTexturePackerOnSave(Texture2D tex) - { - _current._packedTexture = tex; - _prop.textureValue = _current._packedTexture; - _current._hasTextureChanged = false; - } - - void FullTexturePackerOnChange(Texture2D tex, TexturePacker.TextureSource[] sources, TexturePacker.OutputConfig[] configs, TexturePacker.Connection[] connections) - { - _current._input_r.TextureSource = sources[0]; - _current._input_g.TextureSource = sources[1]; - _current._input_b.TextureSource = sources[2]; - _current._input_a.TextureSource = sources[3]; - - _current._input_r.FromOutputConfig(configs[0]); - _current._input_g.FromOutputConfig(configs[1]); - _current._input_b.FromOutputConfig(configs[2]); - _current._input_a.FromOutputConfig(configs[3]); - - _current._input_r.Channel = connections.Length > 0 ? connections[0].FromChannel : TexturePacker.TextureChannelIn.Max; - _current._input_g.Channel = connections.Length > 1 ? connections[1].FromChannel : TexturePacker.TextureChannelIn.Max; - _current._input_b.Channel = connections.Length > 2 ? connections[2].FromChannel : TexturePacker.TextureChannelIn.Max; - _current._input_a.Channel = connections.Length > 3 ? connections[3].FromChannel : TexturePacker.TextureChannelIn.Max; - - _current._packedTexture = tex; - _prop.textureValue = _current._packedTexture; - _current._hasTextureChanged = true; - } - - FilterMode GetFiltermode() - { - if (_current._input_r.GetTexture() != null) return _current._input_r.GetTexture().filterMode; - if (_current._input_g.GetTexture() != null) return _current._input_g.GetTexture().filterMode; - if (_current._input_b.GetTexture() != null) return _current._input_b.GetTexture().filterMode; - if (_current._input_a.GetTexture() != null) return _current._input_a.GetTexture().filterMode; - return FilterMode.Bilinear; - } - - void Confirm() - { - if (_current._packedTexture == null) Pack(); - string path = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(ShaderEditor.Active.Materials[0])); - path = path + "/" + ShaderEditor.Active.Materials[0].name + _prop.name + ".png"; - _prop.textureValue = TextureHelper.SaveTextureAsPNG(_current._packedTexture, path); - TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; - importer.streamingMipmaps = true; - importer.crunchedCompression = true; - importer.sRGBTexture = _colorSpace == ColorSpace.Gamma; - importer.filterMode = GetFiltermode(); - importer.alphaIsTransparency = _current._packedTexture.alphaIsTransparency; - importer.SaveAndReimport(); - - _current._hasConfigChanged = false; - _current._hasTextureChanged = false; - _current._lastConfirmTime = Helper.DatetimeToUnixSeconds(DateTime.Now); - } - - void Revert() - { - _prop.textureValue = _current._previousTexture; - _current._hasTextureChanged = false; - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - - class InlinePackerChannelConfig - { - public TexturePacker.TextureSource TextureSource = new TexturePacker.TextureSource(); - public bool Invert; - public float Fallback; - public TexturePacker.TextureChannelIn Channel = TexturePacker.TextureChannelIn.Max; - - public TexturePacker.OutputConfig ToOutputConfig() - { - TexturePacker.OutputConfig outputConfig = new TexturePacker.OutputConfig(); - outputConfig.BlendMode = TexturePacker.BlendMode.Add; - outputConfig.Invert = Invert ? TexturePacker.InvertMode.Invert : TexturePacker.InvertMode.None; - outputConfig.Fallback = Fallback; - return outputConfig; - } - - public void FromOutputConfig(TexturePacker.OutputConfig config) - { - Invert = config.Invert == TexturePacker.InvertMode.Invert; - Fallback = config.Fallback; - } - - public Texture2D GetTexture() - { - if (TextureSource == null) return null; - return TextureSource.Texture; - } - } - } - - public class GradientDrawer : MaterialPropertyDrawer - { - GradientData data; - - Rect border_position; - Rect gradient_position; - - Dictionary _gradient_data = new Dictionary(); - - private void Init(MaterialProperty prop, bool replace = false) - { - if (!replace && _gradient_data.ContainsKey(prop.targets[0])) - { - data = _gradient_data[prop.targets[0]]; - return; - } - data = new GradientData(); - data.PreviewTexture = prop.textureValue; - _gradient_data[prop.targets[0]] = data; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - Init(prop); - - EditorGUI.BeginChangeCheck(); - if (EditorGUI.EndChangeCheck()) - Init(prop, true); - - if (Config.Singleton.default_texture_type == TextureDisplayType.small) - { - UpdateRects(position, prop); - if (ShaderEditor.Input.Click && border_position.Contains(Event.current.mousePosition)) - Open(prop); - GuiHelper.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); - GradientField(); - } - else - { - position = new RectOffset(-30, 0, 0, 0).Add(position); - Rect top_bg_rect = new Rect(position); - Rect label_rect = new Rect(position); - Rect button_select = new Rect(position); - top_bg_rect = new RectOffset(0, 0, 0, 25).Add(top_bg_rect); - label_rect = new RectOffset(-5, 5, -3, 3).Add(label_rect); - button_select = new RectOffset((int)button_select.width - 120, 20, 2, 0).Remove(button_select); - - GUILayoutUtility.GetRect(position.width, 30); // get space for gradient - border_position = new Rect(position.x, position.y + position.height, position.width, 30); - border_position = new RectOffset(3, 3, 0, 0).Remove(border_position); - gradient_position = new RectOffset(1, 1, 1, 1).Remove(border_position); - if (ShaderEditor.Input.Click && border_position.Contains(Event.current.mousePosition)) - Open(prop); - - GUI.DrawTexture(top_bg_rect, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); - - if (DrawingData.CurrentTextureProperty.hasScaleOffset || DrawingData.CurrentTextureProperty.Options.reference_properties != null) - { - Rect extraPropsBackground = EditorGUILayout.BeginVertical(); - extraPropsBackground.x = position.x; - extraPropsBackground.width = position.width; - extraPropsBackground.y = extraPropsBackground.y - 25; - extraPropsBackground.height = extraPropsBackground.height + 25; - float propertyX = extraPropsBackground.x + 15; - float propertyWidth = extraPropsBackground.width - 30; - GUI.DrawTexture(extraPropsBackground, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); - Rect r; - if (DrawingData.CurrentTextureProperty.hasScaleOffset) - { - r = GUILayoutUtility.GetRect(propertyWidth, 48); - r.x = propertyX; - r.y -= 8; - r.width = propertyWidth; - editor.TextureScaleOffsetProperty(r, prop); - } - if (DrawingData.CurrentTextureProperty.Options.reference_properties != null) - { - float labelWidth = EditorGUIUtility.labelWidth; - EditorGUIUtility.labelWidth = 100; - propertyX -= 30; - foreach (string pName in DrawingData.CurrentTextureProperty.Options.reference_properties) - { - ShaderProperty property = ShaderEditor.Active.PropertyDictionary[pName]; - if (property != null) - { - r = GUILayoutUtility.GetRect(propertyWidth, editor.GetPropertyHeight(property.MaterialProperty, property.Content.text) + 3); - r.x = propertyX; - r.width = propertyWidth; - property.Draw(new CRect(r)); - } - } - EditorGUIUtility.labelWidth = labelWidth; - } - EditorGUILayout.EndVertical(); - } - else - { - GUILayoutUtility.GetRect(0, 5); - Rect backgroundBottom = new RectOffset(3, 3, -5, 10).Add(border_position); - GUI.DrawTexture(backgroundBottom, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); - } - - bool changed = GuiHelper.HandleTexturePicker(prop); - changed |= GuiHelper.AcceptDragAndDrop(border_position, prop); - if (changed) - Init(prop, true); - if (GUI.Button(button_select, "Select", EditorStyles.miniButton)) - { - GuiHelper.OpenTexturePicker(prop); - } - - GradientField(); - GUI.Label(label_rect, label); - - GUILayoutUtility.GetRect(0, 5); - } - } - - private void Open(MaterialProperty prop) - { - ShaderEditor.Input.Use(); - PropertyOptions options = ShaderEditor.Active.CurrentProperty.Options; - GradientEditor.Open(data, prop, options.texture, options.force_texture_options, !options.force_texture_options); - } - - private void UpdateRects(Rect position, MaterialProperty prop) - { - border_position = new Rect(position.x + EditorGUIUtility.labelWidth, position.y, position.width - EditorGUIUtility.labelWidth - GuiHelper.GetSmallTextureVRAMWidth(prop), position.height); - gradient_position = new Rect(border_position.x + 1, border_position.y + 1, border_position.width - 2, border_position.height - 2); - } - - private void GradientField() - { - DrawBackgroundTexture(); - if (data.PreviewTexture != null) - DrawGradientTexture(); - else - GUI.DrawTexture(border_position, Texture2D.whiteTexture, ScaleMode.StretchToFill, false, 0, Color.grey, 1, 1); - } - - private void DrawBackgroundTexture() - { - Texture2D backgroundTexture = TextureHelper.GetBackgroundTexture(); - Rect texCoordsRect = new Rect(0, 0, gradient_position.width / backgroundTexture.width, gradient_position.height / backgroundTexture.height); - GUI.DrawTextureWithTexCoords(gradient_position, backgroundTexture, texCoordsRect, false); - } - - private void DrawGradientTexture() - { - TextureWrapMode wrap_mode = data.PreviewTexture.wrapMode; - data.PreviewTexture.wrapMode = TextureWrapMode.Clamp; - bool vertical = data.PreviewTexture.height > data.PreviewTexture.width; - Vector2 pivot = new Vector2(); - if (vertical) - { - pivot = new Vector2(gradient_position.x, gradient_position.y + gradient_position.height); - GUIUtility.RotateAroundPivot(-90, pivot); - gradient_position.y += gradient_position.height; - float h = gradient_position.width; - gradient_position.width = gradient_position.height; - gradient_position.y += h; - gradient_position.height = -h; - } - GUI.DrawTexture(gradient_position, data.PreviewTexture, ScaleMode.StretchToFill, true); - if (vertical) - { - GUIUtility.RotateAroundPivot(90, pivot); - } - GUI.DrawTexture(border_position, data.PreviewTexture, ScaleMode.StretchToFill, false, 0, Color.grey, 1, 1); - data.PreviewTexture.wrapMode = wrap_mode; - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class TextureArrayDrawer : MaterialPropertyDrawer - { - private string framesProperty; - - public TextureArrayDrawer() { } - - public TextureArrayDrawer(string framesProperty) - { - this.framesProperty = framesProperty; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - ShaderProperty shaderProperty = (ShaderProperty)ShaderEditor.Active.CurrentProperty; - GuiHelper.ConfigTextureProperty(position, prop, label, editor, true, true); - - if ((ShaderEditor.Input.is_drag_drop_event) && position.Contains(ShaderEditor.Input.mouse_position)) - { - DragAndDrop.visualMode = DragAndDropVisualMode.Copy; - if (ShaderEditor.Input.is_drop_event) - { - DragAndDrop.AcceptDrag(); - HanldeDropEvent(prop, shaderProperty); - } - } - if (ShaderEditor.Active.IsFirstCall) - ShaderEditor.Active.TextureArrayProperties.Add(shaderProperty); - } - - public void HanldeDropEvent(MaterialProperty prop, ShaderProperty shaderProperty) - { - string[] paths = DragAndDrop.paths; - Texture2DArray tex; - if (AssetDatabase.GetMainAssetTypeAtPath(paths[0]) != typeof(Texture2DArray)) - tex = Converter.PathsToTexture2DArray(paths); - else - tex = AssetDatabase.LoadAssetAtPath(paths[0]); - prop.textureValue = tex; - UpdateFramesProperty(prop, shaderProperty, tex); - EditorGUIUtility.ExitGUI(); - } - - private void UpdateFramesProperty(MaterialProperty prop, ShaderProperty shaderProperty, Texture2DArray tex) - { - if (framesProperty == null) - framesProperty = shaderProperty.Options.reference_property; - - if (framesProperty != null) - { - if (ShaderEditor.Active.PropertyDictionary.ContainsKey(framesProperty)) - ShaderEditor.Active.PropertyDictionary[framesProperty].MaterialProperty.SetNumber(tex.depth); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - #endregion - - #region Decorators - public class NoAnimateDecorator : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyDoesntAllowAnimation = true; - return 0; - } - } - - public class ThrySeperatorDecorator : MaterialPropertyDrawer - { - Color _color = Styles.COLOR_FG; - - public ThrySeperatorDecorator() { } - public ThrySeperatorDecorator(string c) - { - ColorUtility.TryParseHtmlString(c, out _color); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.RegisterDecorator(this); - return 1; - } - - public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) - { - position = EditorGUI.IndentedRect(position); - EditorGUI.DrawRect(position, _color); - } - } - - public class ThryHeaderLabelDecorator : MaterialPropertyDrawer - { - readonly string _text; - readonly int _size; - GUIStyle _style; - - public ThryHeaderLabelDecorator(string text) : this(text, EditorStyles.standardFont.fontSize) - { - } - public ThryHeaderLabelDecorator(string text, float size) - { - this._text = text; - this._size = (int)size; - } - - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.RegisterDecorator(this); - return _size + 6; - } - - public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) - { - // Done here instead of constructor because else unity throws warnings - if(_style == null) - { - _style = new GUIStyle(EditorStyles.boldLabel); - _style.fontSize = this._size; - } - - float offst = position.height; - position = EditorGUI.IndentedRect(position); - GUI.Label(position, _text, _style); - } - } - - public class ThryRichLabelDrawer : MaterialPropertyDrawer - { - readonly int _size; - GUIStyle _style; - - public ThryRichLabelDrawer(float size) - { - this._size = (int)size; - } - - public ThryRichLabelDrawer() : this(EditorStyles.standardFont.fontSize) { } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - return _size + 4; - } - - public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) - { - // Done here instead of constructor because else unity throws warnings - if(_style == null) - { - _style = new GUIStyle(EditorStyles.boldLabel); - _style.richText = true; - _style.fontSize = this._size; - } - - float offst = position.height; - position = EditorGUI.IndentedRect(position); - GUI.Label(position, label, _style); - } - } - #endregion - - #region Vector Drawers - public class ThryToggleDrawer : MaterialPropertyDrawer - { - public string keyword; - private bool isFirstGUICall = true; - public bool left = false; - private bool hasKeyword = false; - - public ThryToggleDrawer() - { - } - - //the reason for weird string thing here is that you cant have bools as params for drawers - public ThryToggleDrawer(string keywordLeft) - { - if (keywordLeft == "true") left = true; - else if (keywordLeft == "false") left = false; - else keyword = keywordLeft; - hasKeyword = keyword != null; - } - - public ThryToggleDrawer(string keyword, string left) - { - this.keyword = keyword; - this.left = left == "true"; - hasKeyword = keyword != null; - } - - protected void SetKeyword(MaterialProperty prop, bool on) - { - if (ShaderOptimizer.IsMaterialLocked(prop.targets[0] as Material)) return; - SetKeywordInternal(prop, on, "_ON"); - } - - protected void CheckKeyword(MaterialProperty prop) - { - if (ShaderEditor.Active != null && ShaderOptimizer.IsMaterialLocked(prop.targets[0] as Material)) return; - if (prop.hasMixedValue) - { - foreach (Material m in prop.targets) - { - if (m.GetNumber(prop) == 1) - m.EnableKeyword(keyword); - else - m.DisableKeyword(keyword); - } - } - else - { - foreach (Material m in prop.targets) - { - if (prop.GetNumber() == 1) - m.EnableKeyword(keyword); - else - m.DisableKeyword(keyword); - } - } - } - - static bool IsPropertyTypeSuitable(MaterialProperty prop) - { - return prop.type == MaterialProperty.PropType.Float - || prop.type == MaterialProperty.PropType.Range -#if UNITY_2022_1_OR_NEWER - || prop.type == MaterialProperty.PropType.Int; -#endif - ; - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - if (!IsPropertyTypeSuitable(prop)) - { - return EditorGUIUtility.singleLineHeight * 2.5f; - } - if (hasKeyword) - { - CheckKeyword(prop); - DrawingData.LastPropertyDoesntAllowAnimation = true; - } - return base.GetPropertyHeight(prop, label, editor); - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - if (!IsPropertyTypeSuitable(prop)) - { - return; - } - if (isFirstGUICall && !ShaderEditor.Active.IsLockedMaterial) - { - if (hasKeyword) CheckKeyword(prop); - isFirstGUICall = false; - } - //why is this not inFirstGUICall ? cause it seems drawers are kept between different openings of the shader editor, so this needs to be set again every time the shader editor is reopened for that material - (ShaderEditor.Active.PropertyDictionary[prop.name] as ShaderProperty).Keyword = keyword; - - EditorGUI.BeginChangeCheck(); - - bool value = (Math.Abs(prop.GetNumber()) > 0.001f); - EditorGUI.showMixedValue = prop.hasMixedValue; - if (left) value = EditorGUI.ToggleLeft(position, label, value, Styles.style_toggle_left_richtext); - else value = EditorGUI.Toggle(position, label, value); - EditorGUI.showMixedValue = false; - if (EditorGUI.EndChangeCheck()) - { - prop.SetNumber(value ? 1.0f : 0.0f); - if (hasKeyword) SetKeyword(prop, value); - } - } - - public override void Apply(MaterialProperty prop) - { - base.Apply(prop); - if (!IsPropertyTypeSuitable(prop)) - return; - - if (prop.hasMixedValue) - return; - - if (hasKeyword) SetKeyword(prop, (Math.Abs(prop.GetNumber()) > 0.001f)); - } - - protected void SetKeywordInternal(MaterialProperty prop, bool on, string defaultKeywordSuffix) - { - // if no keyword is provided, use + defaultKeywordSuffix - string kw = string.IsNullOrEmpty(keyword) ? prop.name.ToUpperInvariant() + defaultKeywordSuffix : keyword; - // set or clear the keyword - foreach (Material material in prop.targets) - { - if (on) - material.EnableKeyword(kw); - else - material.DisableKeyword(kw); - } - } - } - - //This class only exists for backward compatibility - public class ThryToggleUIDrawer : ThryToggleDrawer - { - public ThryToggleUIDrawer() - { - } - - //the reason for weird string thing here is that you cant have bools as params for drawers - public ThryToggleUIDrawer(string keywordLeft) - { - if (keywordLeft == "true") left = true; - else if (keywordLeft == "false") left = false; - else keyword = keywordLeft; - } - - public ThryToggleUIDrawer(string keyword, string left) - { - this.keyword = keyword; - this.left = left == "true"; - } - } - - public class MultiSliderDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.MinMaxSlider(position, label, prop); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class VectorToSlidersDrawer : MaterialPropertyDrawer - { - class SliderConfig - { - public string Label; - public float Min; - public float Max; - - public SliderConfig(string l, string min, string max) - { - Label = l; - Min = Parse(min); - Max = Parse(max); - } - - public SliderConfig(string l, float min, float max) - { - Label = l; - Min = min; - Max = max; - } - - private float Parse(string s) - { - if(s.StartsWith("n", StringComparison.Ordinal)) - return -float.Parse(s.Substring(1), System.Globalization.CultureInfo.InvariantCulture); - return float.Parse(s.Substring(1), System.Globalization.CultureInfo.InvariantCulture); - } - } - - SliderConfig _slider1; - SliderConfig _slider2; - SliderConfig _slider3; - SliderConfig _slider4; - bool _twoMinMaxDrawers; - - VectorToSlidersDrawer(SliderConfig slider1, SliderConfig slider2, SliderConfig slider3, SliderConfig slider4, float twoMinMaxDrawers) - { - _slider1 = slider1; - _slider2 = slider2; - _slider3 = slider3; - _slider4 = slider4; - _twoMinMaxDrawers = twoMinMaxDrawers == 1; - } - - public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2, string label3, string min3, string max3, string label4, string min4, string max4) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), new SliderConfig(label4, min4, max4), 0) - { } - public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2, string label3, string min3, string max3) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), null, 0) - { } - public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, 0) - { } - public VectorToSlidersDrawer(float twoMinMaxDrawers, string label1, string min1, string max1, string label2, string min2, string max2) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, twoMinMaxDrawers) - { } - - public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2, string label3, float min3, float max3, string label4, float min4, float max4) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), new SliderConfig(label4, min4, max4), 0) - { } - public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2, string label3, float min3, float max3) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), null, 0) - { } - public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, 0) - { } - public VectorToSlidersDrawer(float twoMinMaxDrawers, string label1, float min1, float max1, string label2, float min2, float max2) : - this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, twoMinMaxDrawers) - { } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - Vector4 vector = prop.vectorValue; - EditorGUI.BeginChangeCheck(); - if (_twoMinMaxDrawers) - { - float min1 = vector.x; - float max1 = vector.y; - float min2 = vector.z; - float max2 = vector.w; - EditorGUI.showMixedValue = prop.hasMixedValue; - EditorGUILayout.MinMaxSlider(_slider1.Label, ref min1, ref max1, _slider1.Min, _slider1.Max); - EditorGUI.showMixedValue = prop.hasMixedValue; - EditorGUILayout.MinMaxSlider(_slider2.Label, ref min2, ref max2, _slider2.Min, _slider2.Max); - vector = new Vector4(min1, max1, min2, max2); - } - else - { - EditorGUI.showMixedValue = prop.hasMixedValue; - vector.x = EditorGUILayout.Slider(_slider1.Label, vector.x, _slider1.Min, _slider1.Max); - EditorGUI.showMixedValue = prop.hasMixedValue; - vector.y = EditorGUILayout.Slider(_slider2.Label, vector.y, _slider2.Min, _slider2.Max); - if (_slider3 != null) - { - EditorGUI.showMixedValue = prop.hasMixedValue; - vector.z = EditorGUILayout.Slider(_slider3.Label, vector.z, _slider3.Min, _slider3.Max); - } - if (_slider4 != null) - { - EditorGUI.showMixedValue = prop.hasMixedValue; - vector.w = EditorGUILayout.Slider(_slider4.Label, vector.w, _slider4.Min, _slider4.Max); - } - } - if (EditorGUI.EndChangeCheck()) - prop.vectorValue = vector; - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor) - EditorGUIUtility.singleLineHeight; - } - } - - public class Vector4TogglesDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUI.BeginChangeCheck(); - EditorGUI.showMixedValue = prop.hasMixedValue; - EditorGUI.LabelField(position, label); - position.x += EditorGUIUtility.labelWidth; - position.width = (position.width - EditorGUIUtility.labelWidth) / 4; - bool b1 = GUI.Toggle(position, prop.vectorValue.x == 1, ""); - position.x += position.width; - bool b2 = GUI.Toggle(position, prop.vectorValue.y == 1, ""); - position.x += position.width; - bool b3 = GUI.Toggle(position, prop.vectorValue.z == 1, ""); - position.x += position.width; - bool b4 = GUI.Toggle(position, prop.vectorValue.w == 1, ""); - if (EditorGUI.EndChangeCheck()) - { - prop.vectorValue = new Vector4(b1 ? 1 : 0, b2 ? 1 : 0, b3 ? 1 : 0, b4 ? 1 : 0); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class ThryMultiFloatsDrawer : MaterialPropertyDrawer - { - string[] _otherProperties; - MaterialProperty[] _otherMaterialProps; - bool _displayAsToggles; - - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5, string p6, string p7) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5, p6, p7 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5, string p6) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5, p6 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4) : this(displayAsToggles, new string[] { p1, p2, p3, p4 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3) : this(displayAsToggles, new string[] { p1, p2, p3 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2) : this(displayAsToggles, new string[] { p1, p2 }) { } - public ThryMultiFloatsDrawer(string displayAsToggles, string p1) : this(displayAsToggles, new string[] { p1 }) { } - - public ThryMultiFloatsDrawer(string displayAsToggles, params string[] extraProperties) - { - _displayAsToggles = displayAsToggles.ToLower() == "true" || displayAsToggles == "1"; - _otherProperties = extraProperties; - _otherMaterialProps = new MaterialProperty[extraProperties.Length]; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - Rect labelR = new Rect(position); - labelR.width = EditorGUIUtility.labelWidth; - Rect contentR = new Rect(position); - contentR.width = (contentR.width - labelR.width) / (_otherProperties.Length + 1); - contentR.x += labelR.width; - - for (int i = 0; i < _otherProperties.Length; i++) - _otherMaterialProps[i] = ShaderEditor.Active.PropertyDictionary[_otherProperties[i]].MaterialProperty; - EditorGUI.BeginChangeCheck(); - - EditorGUI.LabelField(labelR, label); - int indentLevel = EditorGUI.indentLevel; //else it double indents - EditorGUI.indentLevel = 0; - PropGUI(prop, contentR, 0); - if (ShaderEditor.Active.IsInAnimationMode) - MaterialEditor.PrepareMaterialPropertiesForAnimationMode(_otherMaterialProps, true); - for (int i = 0; i < _otherProperties.Length; i++) - { - PropGUI(_otherMaterialProps[i], contentR, i + 1); - } - EditorGUI.indentLevel = indentLevel; - - //If edited in animation mode mark as animated (needed cause other properties isnt checked in draw) - if (EditorGUI.EndChangeCheck() && ShaderEditor.Active.IsInAnimationMode && !ShaderEditor.Active.CurrentProperty.IsAnimated) - ShaderEditor.Active.CurrentProperty.SetAnimated(true, false); - //make sure all are animated together - bool animated = ShaderEditor.Active.CurrentProperty.IsAnimated; - bool renamed = ShaderEditor.Active.CurrentProperty.IsRenaming; - for (int i = 0; i < _otherProperties.Length; i++) - ShaderEditor.Active.PropertyDictionary[_otherProperties[i]].SetAnimated(animated, renamed); - } - - void PropGUI(MaterialProperty prop, Rect contentRect, int index) - { - contentRect.x += contentRect.width * index; - contentRect.width -= 5; - - float val = prop.floatValue; - EditorGUI.showMixedValue = prop.hasMixedValue; - EditorGUI.BeginChangeCheck(); - if (_displayAsToggles) val = EditorGUI.Toggle(contentRect, val == 1) ? 1 : 0; - else val = EditorGUI.FloatField(contentRect, val); - if (EditorGUI.EndChangeCheck()) - { - prop.floatValue = val; - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class Vector3Drawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUI.BeginChangeCheck(); - EditorGUI.showMixedValue = prop.hasMixedValue; - Vector4 vec = EditorGUI.Vector3Field(position, label, prop.vectorValue); - if (EditorGUI.EndChangeCheck()) - { - prop.vectorValue = new Vector4(vec.x, vec.y, vec.z, prop.vectorValue.w); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class Vector2Drawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUI.BeginChangeCheck(); - EditorGUI.showMixedValue = prop.hasMixedValue; - Vector4 vec = EditorGUI.Vector2Field(position, label, prop.vectorValue); - if (EditorGUI.EndChangeCheck()) - { - prop.vectorValue = new Vector4(vec.x, vec.y, prop.vectorValue.z, prop.vectorValue.w); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - public class VectorLabelDrawer : MaterialPropertyDrawer - { - string[] _labelStrings = new string[4] { "X", "Y", "Z", "W" }; - int vectorChannels = 0; - - public VectorLabelDrawer(string labelX, string labelY) - { - _labelStrings[0] = labelX; - _labelStrings[1] = labelY; - vectorChannels = 2; - } - - public VectorLabelDrawer(string labelX, string labelY, string labelZ) - { - _labelStrings[0] = labelX; - _labelStrings[1] = labelY; - _labelStrings[2] = labelZ; - vectorChannels = 3; - } - - public VectorLabelDrawer(string labelX, string labelY, string labelZ, string labelW) - { - _labelStrings[0] = labelX; - _labelStrings[1] = labelY; - _labelStrings[2] = labelZ; - _labelStrings[3] = labelW; - vectorChannels = 4; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUI.BeginChangeCheck(); - EditorGUI.showMixedValue = prop.hasMixedValue; - - Rect labelR = new Rect(position.x, position.y, position.width * 0.41f, position.height); - Rect contentR = new Rect(position.x + labelR.width, position.y, position.width - labelR.width, position.height); - - float[] values = new float[vectorChannels]; - GUIContent[] labels = new GUIContent[vectorChannels]; - - for (int i = 0; i < vectorChannels; i++) - { - values[i] = prop.vectorValue[i]; - labels[i] = new GUIContent(_labelStrings[i]); - } - - EditorGUI.LabelField(labelR, label); - EditorGUI.MultiFloatField(contentR, labels, values); - - if (EditorGUI.EndChangeCheck()) - { - switch (vectorChannels) - { - case 2: - prop.vectorValue = new Vector4(values[0], values[1], prop.vectorValue.z, prop.vectorValue.w); - break; - case 3: - prop.vectorValue = new Vector4(values[0], values[1], values[2], prop.vectorValue.w); - break; - case 4: - prop.vectorValue = new Vector4(values[0], values[1], values[2], values[3]); - break; - default: - break; - } - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - // Enum with normal editor width, rather than MaterialEditor Default GUI widths - // Would be nice if Decorators could access Drawers too so this wouldn't be necessary for something to trivial - // Adapted from Unity interal MaterialEnumDrawer https://github.com/Unity-Technologies/UnityCsReference/ - public class ThryWideEnumDrawer : MaterialPropertyDrawer - { - // TODO: Consider Load locale by property name in the future (maybe, could have drawbacks) - private GUIContent[] names; - private readonly string[] defaultNames; - private readonly float[] values; - private int _reloadCount = -1; - private static int _reloadCountStatic; - - // internal Unity AssemblyHelper can't be accessed - private Type[] TypesFromAssembly(Assembly a) - { - if (a == null) - return new Type[0]; - try - { - return a.GetTypes(); - } - catch (ReflectionTypeLoadException) - { - return new Type[0]; - } - } - public ThryWideEnumDrawer(string enumName, int j) - { - var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany( - x => TypesFromAssembly(x)).ToArray(); - try - { - var enumType = types.FirstOrDefault( - x => x.IsEnum && (x.Name == enumName || x.FullName == enumName) - ); - var enumNames = Enum.GetNames(enumType); - names = new GUIContent[enumNames.Length]; - for (int i = 0; i < enumNames.Length; ++i) - names[i] = new GUIContent(enumNames[i]); - - var enumVals = Enum.GetValues(enumType); - values = new float[enumVals.Length]; - for (int i = 0; i < enumVals.Length; ++i) - values[i] = (int)enumVals.GetValue(i); - } - catch (Exception) - { - Debug.LogWarningFormat("Failed to create WideEnum, enum {0} not found", enumName); - throw; - } - - } - - public ThryWideEnumDrawer(string n1, float v1) : this(new[] { n1 }, new[] { v1 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2) : this(new[] { n1, n2 }, new[] { v1, v2 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3) : this(new[] { n1, n2, n3 }, new[] { v1, v2, v3 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4) : this(new[] { n1, n2, n3, n4 }, new[] { v1, v2, v3, v4 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5) : this(new[] { n1, n2, n3, n4, n5 }, new[] { v1, v2, v3, v4, v5 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6) : this(new[] { n1, n2, n3, n4, n5, n6 }, new[] { v1, v2, v3, v4, v5, v6 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7) : this(new[] { n1, n2, n3, n4, n5, n6, n7 }, new[] { v1, v2, v3, v4, v5, v6, v7 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18, string n19, float v19) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19 }) { } - public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18, string n19, float v19, string n20, float v20) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20 }) { } - public ThryWideEnumDrawer(string[] enumNames, float[] vals) - { - defaultNames = enumNames; - - // Init without Locale to prevent errors - names = new GUIContent[enumNames.Length]; - for (int i = 0; i < enumNames.Length; ++i) - names[i] = new GUIContent(enumNames[i]); - - values = new float[vals.Length]; - for (int i = 0; i < vals.Length; ++i) - values[i] = vals[i]; - } - - void LoadNames() - { - names = new GUIContent[defaultNames.Length]; - for (int i = 0; i < defaultNames.Length; ++i) - { - names[i] = new GUIContent(ShaderEditor.Active.Locale.Get(defaultNames[i], defaultNames[i])); - } - } - public static void Reload() - { - _reloadCountStatic++; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUI.showMixedValue = prop.hasMixedValue; - float value = prop.GetNumber(); - int selectedIndex = Array.IndexOf(values, value); - - if (_reloadCount != _reloadCountStatic) - { - _reloadCount = _reloadCountStatic; - LoadNames(); - } - - // Custom Change Check, so it triggers on reselect too - bool wasClickEvent = Event.current.type == EventType.ExecuteCommand; - int selIndex = EditorGUI.Popup(position, label, selectedIndex, names); - EditorGUI.showMixedValue = false; - if (wasClickEvent && Event.current.type == EventType.Used) - { - // Set GUI.changed to true, so it triggers a change event, even on reselection - GUI.changed = true; - prop.SetNumber(values[selIndex]); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - - #endregion - - #region Float Drawers - public class ThryIntRangeDrawer: MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - var range = prop.rangeLimits; - EditorGUI.BeginChangeCheck(); - var value = EditorGUI.IntSlider(position, label, (int)prop.GetNumber(), (int)range.x, (int)range.y); - if (EditorGUI.EndChangeCheck()) - prop.SetNumber(value); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return base.GetPropertyHeight(prop, label, editor); - } - } - #endregion - - #region UI Drawers - public class HelpboxDrawer : MaterialPropertyDrawer - { - readonly MessageType type; - - public HelpboxDrawer() - { - type = MessageType.Info; - } - - public HelpboxDrawer(float f) - { - type = (MessageType)(int)f; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - EditorGUILayout.HelpBox(label.text, type); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return 0; - } - } - - public class sRGBWarningDecorator : MaterialPropertyDrawer - { - bool _isSRGB = true; - - public sRGBWarningDecorator() - { - _isSRGB = false; - } - - public sRGBWarningDecorator(string shouldHaveSRGB) - { - this._isSRGB = shouldHaveSRGB.ToLower() == "true"; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - GuiHelper.ColorspaceWarning(prop, _isSRGB); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.RegisterDecorator(this); - return 0; - } - } - - public class LocalMessageDrawer : MaterialPropertyDrawer - { - protected ButtonData _buttonData; - protected bool _isInit; - protected virtual void Init(string s) - { - if (_isInit) return; - _buttonData = Parser.Deserialize(s); - _isInit = true; - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - Init(prop.displayName); - if (_buttonData == null) return; - if (_buttonData.text.Length > 0) - { - GUILayout.Label(new GUIContent(_buttonData.text, _buttonData.hover), _buttonData.center_position ? Styles.richtext_center : Styles.richtext); - Rect r = GUILayoutUtility.GetLastRect(); - if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition)) - _buttonData.action.Perform(ShaderEditor.Active?.Materials); - } - if (_buttonData.texture != null) - { - if (_buttonData.center_position) GUILayout.Label(new GUIContent(_buttonData.texture.loaded_texture, _buttonData.hover), EditorStyles.centeredGreyMiniLabel, GUILayout.MaxHeight(_buttonData.texture.height)); - else GUILayout.Label(new GUIContent(_buttonData.texture.loaded_texture, _buttonData.hover), GUILayout.MaxHeight(_buttonData.texture.height)); - Rect r = GUILayoutUtility.GetLastRect(); - if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition)) - _buttonData.action.Perform(ShaderEditor.Active?.Materials); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return 0; - } - } - - public class RemoteMessageDrawer : LocalMessageDrawer - { - - protected override void Init(string s) - { - if (_isInit) return; - WebHelper.DownloadStringASync(s, (Action)((string data) => - { - _buttonData = Parser.Deserialize(data); - })); - _isInit = true; - } - } - - public class ThryCustomGUIDrawer : MaterialPropertyDrawer - { - private MethodInfo _method; - public ThryCustomGUIDrawer(string type, string namespaceName,string method) - { - Type t = Type.GetType(type + ", " + namespaceName); - if(t != null) - { - _method = t.GetMethod(method); - } - } - - public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) - { - if (_method != null) - { - _method.Invoke(null, new object[] { position, prop, label, editor, ShaderEditor.Active }); - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - return 0; - } - } - #endregion - - #region enums - public enum ColorMask - { - None, - Alpha, - Blue, - BA, - Green, - GA, - GB, - GBA, - Red, - RA, - RB, - RBA, - RG, - RGA, - RGB, - RGBA - } - - // DX11 only blend operations - public enum BlendOp - { - Add, - Subtract, - ReverseSubtract, - Min, - Max, - LogicalClear, - LogicalSet, - LogicalCopy, - LogicalCopyInverted, - LogicalNoop, - LogicalInvert, - LogicalAnd, - LogicalNand, - LogicalOr, - LogicalNor, - LogicalXor, - LogicalEquivalence, - LogicalAndReverse, - LogicalAndInverted, - LogicalOrReverse, - LogicalOrInverted - } - #endregion - - public class ThryShaderOptimizerLockButtonDrawer : MaterialPropertyDrawer - { - public override void OnGUI(Rect position, MaterialProperty shaderOptimizer, string label, MaterialEditor materialEditor) - { - Material material = shaderOptimizer.targets[0] as Material; - Shader shader = material.shader; - // The GetPropertyDefaultFloatValue is changed from 0 to 1 when the shader is locked in - bool isLocked = shader.name.StartsWith("Hidden/Locked/") || - (shader.name.StartsWith("Hidden/") && material.GetTag("OriginalShader", false, "") != "" && shader.GetPropertyDefaultFloatValue(shader.FindPropertyIndex(shaderOptimizer.name)) == 1); - //this will make sure the button is unlocked if you manually swap to an unlocked shader - //shaders that have the ability to be locked shouldnt really be hidden themself. at least it wouldnt make too much sense - if (shaderOptimizer.hasMixedValue == false && shaderOptimizer.GetNumber() == 1 && isLocked == false) - { - shaderOptimizer.SetNumber(0); - } - else if (shaderOptimizer.hasMixedValue == false && shaderOptimizer.GetNumber() == 0 && isLocked) - { - shaderOptimizer.SetNumber(1); - } - - bool disabled = false; -#if UNITY_2022_1_OR_NEWER - disabled |= ShaderEditor.Active.Materials[0].isVariant; -#endif - EditorGUI.BeginDisabledGroup(disabled); // for variant materials - - // Theoretically this shouldn't ever happen since locked in materials have different shaders. - // But in a case where the material property says its locked in but the material really isn't, this - // will display and allow users to fix the property/lock in - ShaderEditor.Active.IsLockedMaterial = shaderOptimizer.GetNumber() == 1; - if (shaderOptimizer.hasMixedValue) - { - EditorGUI.BeginChangeCheck(); - GUILayout.Button(EditorLocale.editor.Get("lockin_button_multi").ReplaceVariables(materialEditor.targets.Length)); - if (EditorGUI.EndChangeCheck()) - { - SaveChangeStack(); - ShaderOptimizer.SetLockedForAllMaterials(shaderOptimizer.targets.Select(t => t as Material), shaderOptimizer.floatValue == 1 ? 0 : 1, true, false, false, shaderOptimizer); - RestoreChangeStack(); - } - } - else - { - EditorGUI.BeginChangeCheck(); - if (shaderOptimizer.GetNumber() == 0) - { - if (materialEditor.targets.Length == 1) - GUILayout.Button(EditorLocale.editor.Get("lockin_button_single")); - else GUILayout.Button(EditorLocale.editor.Get("lockin_button_multi").ReplaceVariables(materialEditor.targets.Length)); - } - else - { - if (materialEditor.targets.Length == 1) - GUILayout.Button(EditorLocale.editor.Get("unlock_button_single")); - else GUILayout.Button(EditorLocale.editor.Get("unlock_button_multi").ReplaceVariables(materialEditor.targets.Length)); - } - if (EditorGUI.EndChangeCheck()) - { - SaveChangeStack(); - ShaderOptimizer.SetLockedForAllMaterials(shaderOptimizer.targets.Select(t => t as Material), shaderOptimizer.GetNumber() == 1 ? 0 : 1, true, false, false, shaderOptimizer); - RestoreChangeStack(); - } - } - if (Config.Singleton.allowCustomLockingRenaming || ShaderEditor.Active.HasCustomRenameSuffix) - { - EditorGUI.BeginDisabledGroup(!Config.Singleton.allowCustomLockingRenaming || ShaderEditor.Active.IsLockedMaterial); - EditorGUI.BeginChangeCheck(); - EditorGUI.showMixedValue = ShaderEditor.Active.HasMixedCustomPropertySuffix; - ShaderEditor.Active.RenamedPropertySuffix = EditorGUILayout.TextField("Locked property suffix: ", ShaderEditor.Active.RenamedPropertySuffix); - if (EditorGUI.EndChangeCheck()) - { - // Make sure suffix that is saved is valid - ShaderEditor.Active.RenamedPropertySuffix = ShaderOptimizer.CleanStringForPropertyNames(ShaderEditor.Active.RenamedPropertySuffix.Replace(" ", "_")); - foreach (Material m in ShaderEditor.Active.Materials) - m.SetOverrideTag("thry_rename_suffix", ShaderEditor.Active.RenamedPropertySuffix); - if (ShaderEditor.Active.RenamedPropertySuffix == "") - ShaderEditor.Active.RenamedPropertySuffix = ShaderOptimizer.GetRenamedPropertySuffix(ShaderEditor.Active.Materials[0]); - ShaderEditor.Active.HasCustomRenameSuffix = ShaderOptimizer.HasCustomRenameSuffix(ShaderEditor.Active.Materials[0]); - } - if (!Config.Singleton.allowCustomLockingRenaming) - { - EditorGUILayout.HelpBox("This feature is disabled in the config file. You can enable it by setting allowCustomLockingRenaming to true.", MessageType.Info); - } - EditorGUI.EndDisabledGroup(); - } - - EditorGUI.EndDisabledGroup(); // for variant materials - } - - //This code purly exists cause Unity 2019 is a piece of shit that looses it's internal change stack on locking CAUSE FUCK IF I KNOW - static System.Reflection.FieldInfo changeStack = typeof(EditorGUI).GetField("s_ChangedStack", BindingFlags.Static | BindingFlags.NonPublic); - static int preLockStackSize = 0; - private static void SaveChangeStack() - { - if (changeStack != null) - { - Stack stack = (Stack)changeStack.GetValue(null); - if (stack != null) - { - preLockStackSize = stack.Count(); - } - } - } - - private static void RestoreChangeStack() - { - if (changeStack != null) - { - Stack stack = (Stack)changeStack.GetValue(null); - if (stack != null) - { - int postLockStackSize = stack.Count(); - //Restore change stack from before lock / unlocking - for (int i = postLockStackSize; i < preLockStackSize; i++) - { - EditorGUI.BeginChangeCheck(); - } - } - } - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - DrawingData.LastPropertyDoesntAllowAnimation = true; - ShaderEditor.Active.DoUseShaderOptimizer = true; - return -2; - } - } - - public class ThryDecalPositioningDecorator : MaterialPropertyDrawer - { - string _texturePropertyName; - string _uvIndexPropertyName; - string _positionPropertyName; - string _rotationPropertyName; - string _scalePropertyName; - string _offsetPropertyName; - DecalSceneTool _sceneTool; - DecalTool _tool; - - public ThryDecalPositioningDecorator(string textureProp, string uvIndexPropertyName, string positionProp, string rotationProp, string scaleProp, string offsetProp) - { - _texturePropertyName = textureProp; - _uvIndexPropertyName = uvIndexPropertyName; - _positionPropertyName = positionProp; - _rotationPropertyName = rotationProp; - _offsetPropertyName = offsetProp; - _scalePropertyName = scaleProp; - } - - void CreateSceneTool() - { - DiscardSceneTool(); - _sceneTool = DecalSceneTool.Create( - Selection.activeTransform.GetComponent(), - ShaderEditor.Active.Materials[0], - (int)ShaderEditor.Active.PropertyDictionary[_uvIndexPropertyName].MaterialProperty.GetNumber(), - ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); - } - - void DiscardSceneTool() - { - if(_sceneTool != null) - { - _sceneTool.Deactivate(); - _sceneTool = null; - } - } - - public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) - { - position = new RectOffset(0, 0, 0, 3).Remove(EditorGUI.IndentedRect(position)); - bool isInScene = Selection.activeTransform != null && Selection.activeTransform.GetComponent() != null; - if(isInScene) - { - position.width /= 3; - ButtonGUI(position); - position.x += position.width; - ButtonRaycast(position); - position.x += position.width; - ButtonSceneTools(position); - if(_sceneTool != null) - { - _sceneTool.SetMaterialProperties( - ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); - } - }else - { - ButtonGUI(position); - } - } - - void ButtonGUI(Rect r) - { - if(GUI.Button(r, "Open Positioning Tool")) - { - _tool = DecalTool.OpenDecalTool(ShaderEditor.Active.Materials[0]); - } - // This is done because the tool didnt want to update if the data was changed from the outside - if(_tool != null) - { - _tool.SetMaterialProperties( - ShaderEditor.Active.PropertyDictionary[_texturePropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_uvIndexPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_positionPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_rotationPropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_scalePropertyName].MaterialProperty, - ShaderEditor.Active.PropertyDictionary[_offsetPropertyName].MaterialProperty); - } - } - - void ButtonRaycast(Rect r) - { - if (GUI.Button(r, "Raycast")) - { - if(_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Raycast) - { - DiscardSceneTool(); - } - else - { - CreateSceneTool(); - _sceneTool.StartRaycastMode(); - } - } - if(_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Raycast) - GUI.DrawTexture(r, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f), 0, 3); - } - - void ButtonSceneTools(Rect r) - { - if (GUI.Button(r, "Scene Tools")) - { - if(_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Handles) - { - DiscardSceneTool(); - } - else - { - CreateSceneTool(); - _sceneTool.StartHandleMode(); - } - } - if(_sceneTool != null && _sceneTool.GetMode() == DecalSceneTool.Mode.Handles) - GUI.DrawTexture(r, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, new Color(0.5f, 0.5f, 0.5f, 0.5f), 0, 3); - } - - public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) - { - DrawingData.LastPropertyUsedCustomDrawer = true; - DrawingData.LastPropertyDoesntAllowAnimation = false; - return EditorGUIUtility.singleLineHeight + 6; - } - } -} diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.meta new file mode 100644 index 00000000..878a99c0 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 680a8e04fa33401438d8cc9f19fec4dd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs new file mode 100644 index 00000000..f1633646 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class CurveDrawer : MaterialPropertyDrawer + { + public AnimationCurve curve; + public EditorWindow window; + public Texture2D texture; + public bool saved = true; + public TextureData imageData; + + public CurveDrawer() + { + curve = new AnimationCurve(); + } + + private void Init() + { + if (imageData == null) + { + if (ShaderEditor.Active.CurrentProperty.Options.texture == null) + imageData = new TextureData(); + else + imageData = ShaderEditor.Active.CurrentProperty.Options.texture; + } + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + Init(); + Rect border_position = new Rect(position.x + EditorGUIUtility.labelWidth - 15, position.y, position.width - EditorGUIUtility.labelWidth + 15 - GUILib.GetSmallTextureVRAMWidth(prop), position.height); + + EditorGUI.BeginChangeCheck(); + curve = EditorGUI.CurveField(border_position, curve); + if (EditorGUI.EndChangeCheck()) + { + UpdateCurveTexture(prop); + } + + GUILib.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); + + CheckWindowForCurveEditor(); + + if (window == null && !saved) + Save(prop); + } + + private void UpdateCurveTexture(MaterialProperty prop) + { + texture = Converter.CurveToTexture(curve, imageData); + prop.textureValue = texture; + saved = false; + } + + private void CheckWindowForCurveEditor() + { + string windowName = ""; + if (EditorWindow.focusedWindow != null) + windowName = EditorWindow.focusedWindow.titleContent.text; + bool isCurveEditor = windowName == "Curve"; + if (isCurveEditor) + window = EditorWindow.focusedWindow; + } + + private void Save(MaterialProperty prop) + { + Debug.Log(prop.textureValue.ToString()); + Texture saved_texture = TextureHelper.SaveTextureAsPNG(texture, PATH.TEXTURES_DIR + "curves/" + curve.GetHashCode() + ".png", null); + prop.textureValue = saved_texture; + saved = true; + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs.meta new file mode 100644 index 00000000..70994a39 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Curve.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fa564dda4ba86243ba65815cfd4a422 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs new file mode 100644 index 00000000..11b75a1a --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class GradientDrawer : MaterialPropertyDrawer + { + GradientData data; + + Rect border_position; + Rect gradient_position; + + Dictionary _gradient_data = new Dictionary(); + + private void Init(MaterialProperty prop, bool replace = false) + { + if (!replace && _gradient_data.ContainsKey(prop.targets[0])) + { + data = _gradient_data[prop.targets[0]]; + return; + } + data = new GradientData(); + data.PreviewTexture = prop.textureValue; + _gradient_data[prop.targets[0]] = data; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + Init(prop); + ShaderEditor.Active.Editor.EndAnimatedCheck(); // Fixes all dropdoen properties being animated / highlighted + + if (Config.Singleton.default_texture_type == TextureDisplayType.small) + { + UpdateRects(position, prop); + if (ShaderEditor.Input.Click && border_position.Contains(Event.current.mousePosition)) + Open(prop); + GUILib.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); + GradientField(); + } + else + { + position = new RectOffset(-30, 0, 0, 0).Add(position); + Rect top_bg_rect = new Rect(position); + Rect label_rect = new Rect(position); + Rect button_select = new Rect(position); + top_bg_rect = new RectOffset(0, 0, 0, 25).Add(top_bg_rect); + label_rect = new RectOffset(-5, 5, -3, 3).Add(label_rect); + button_select = new RectOffset((int)button_select.width - 120, 20, 2, 0).Remove(button_select); + + GUILayoutUtility.GetRect(position.width, 30); // get space for gradient + border_position = new Rect(position.x, position.y + position.height, position.width, 30); + border_position = new RectOffset(3, 3, 0, 0).Remove(border_position); + gradient_position = new RectOffset(1, 1, 1, 1).Remove(border_position); + if (ShaderEditor.Input.Click && border_position.Contains(Event.current.mousePosition)) + Open(prop); + + GUI.DrawTexture(top_bg_rect, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); + + if (DrawingData.CurrentTextureProperty.hasScaleOffset || DrawingData.CurrentTextureProperty.Options.reference_properties != null) + { + Rect extraPropsBackground = EditorGUILayout.BeginVertical(); + extraPropsBackground.x = position.x; + extraPropsBackground.width = position.width; + extraPropsBackground.y = extraPropsBackground.y - 25; + extraPropsBackground.height = extraPropsBackground.height + 25; + float propertyX = extraPropsBackground.x + 15; + float propertyWidth = extraPropsBackground.width - 30; + GUI.DrawTexture(extraPropsBackground, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); + Rect r; + if (DrawingData.CurrentTextureProperty.hasScaleOffset) + { + r = GUILayoutUtility.GetRect(propertyWidth, 48); + r.x = propertyX; + r.y -= 8; + r.width = propertyWidth; + editor.TextureScaleOffsetProperty(r, prop); + } + if (DrawingData.CurrentTextureProperty.Options.reference_properties != null) + { + float labelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 100; + propertyX -= 30; + foreach (string pName in DrawingData.CurrentTextureProperty.Options.reference_properties) + { + ShaderProperty property = ShaderEditor.Active.PropertyDictionary[pName]; + if (property != null) + { + r = GUILayoutUtility.GetRect(propertyWidth, editor.GetPropertyHeight(property.MaterialProperty, property.Content.text) + 3); + r.x = propertyX; + r.width = propertyWidth; + property.Draw(r); + } + } + EditorGUIUtility.labelWidth = labelWidth; + } + EditorGUILayout.EndVertical(); + } + else + { + GUILayoutUtility.GetRect(0, 5); + Rect backgroundBottom = new RectOffset(3, 3, -5, 10).Add(border_position); + GUI.DrawTexture(backgroundBottom, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, 3, 10); + } + + bool changed = GUILib.HandleTexturePicker(prop); + changed |= GUILib.AcceptDragAndDrop(border_position, prop); + if (changed) + Init(prop, true); + if (GUI.Button(button_select, "Select", EditorStyles.miniButton)) + { + GUILib.OpenTexturePicker(prop); + } + + GradientField(); + GUI.Label(label_rect, label); + + GUILayoutUtility.GetRect(0, 5); + } + + ShaderEditor.Active.Editor.BeginAnimatedCheck(prop); + } + + private void Open(MaterialProperty prop) + { + ShaderEditor.Input.Use(); + PropertyOptions options = ShaderEditor.Active.CurrentProperty.Options; + GradientEditor.Open(data, prop, options.texture, options.force_texture_options, !options.force_texture_options); + } + + private void UpdateRects(Rect position, MaterialProperty prop) + { + border_position = new Rect(position.x + EditorGUIUtility.labelWidth, position.y, position.width - EditorGUIUtility.labelWidth - GUILib.GetSmallTextureVRAMWidth(prop), position.height); + gradient_position = new Rect(border_position.x + 1, border_position.y + 1, border_position.width - 2, border_position.height - 2); + } + + private void GradientField() + { + DrawBackgroundTexture(); + if (data.PreviewTexture != null) + DrawGradientTexture(); + else + GUI.DrawTexture(border_position, Texture2D.whiteTexture, ScaleMode.StretchToFill, false, 0, Color.grey, 1, 1); + } + + private void DrawBackgroundTexture() + { + Texture2D backgroundTexture = TextureHelper.GetBackgroundTexture(); + Rect texCoordsRect = new Rect(0, 0, gradient_position.width / backgroundTexture.width, gradient_position.height / backgroundTexture.height); + GUI.DrawTextureWithTexCoords(gradient_position, backgroundTexture, texCoordsRect, false); + } + + private void DrawGradientTexture() + { + TextureWrapMode wrap_mode = data.PreviewTexture.wrapMode; + data.PreviewTexture.wrapMode = TextureWrapMode.Clamp; + bool vertical = data.PreviewTexture.height > data.PreviewTexture.width; + Vector2 pivot = new Vector2(); + if (vertical) + { + pivot = new Vector2(gradient_position.x, gradient_position.y + gradient_position.height); + GUIUtility.RotateAroundPivot(-90, pivot); + gradient_position.y += gradient_position.height; + float h = gradient_position.width; + gradient_position.width = gradient_position.height; + gradient_position.y += h; + gradient_position.height = -h; + } + GUI.DrawTexture(gradient_position, data.PreviewTexture, ScaleMode.StretchToFill, true); + if (vertical) + { + GUIUtility.RotateAroundPivot(90, pivot); + } + GUI.DrawTexture(border_position, data.PreviewTexture, ScaleMode.StretchToFill, false, 0, Color.grey, 1, 1); + data.PreviewTexture.wrapMode = wrap_mode; + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs.meta new file mode 100644 index 00000000..ec157098 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Gradient.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 27c8df6277ae1dc4d999acc99f296ec4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs new file mode 100644 index 00000000..a44830cb --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class HelpboxDrawer : MaterialPropertyDrawer + { + readonly MessageType type; + + public HelpboxDrawer() + { + type = MessageType.Info; + } + + public HelpboxDrawer(float f) + { + type = (MessageType)(int)f; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUILayout.HelpBox(label.text, type); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return 0; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs.meta new file mode 100644 index 00000000..8dde7a67 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Helpbox.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: edb12ad39e13f1242a06cb8551182b2c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs new file mode 100644 index 00000000..49d141cd --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class LocalMessageDrawer : MaterialPropertyDrawer + { + protected ButtonData _buttonData; + protected bool _isInit; + protected virtual void Init(string s) + { + if (_isInit) return; + _buttonData = Parser.Deserialize(s); + _isInit = true; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + Init(prop.displayName); + if (_buttonData == null) return; + if (_buttonData.text.Length > 0) + { + GUILayout.Label(new GUIContent(_buttonData.text, _buttonData.hover), _buttonData.center_position ? Styles.richtext_center : Styles.richtext); + Rect r = GUILayoutUtility.GetLastRect(); + if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition)) + _buttonData.action.Perform(ShaderEditor.Active?.Materials); + } + if (_buttonData.texture != null) + { + if (_buttonData.center_position) GUILayout.Label(new GUIContent(_buttonData.texture.loaded_texture, _buttonData.hover), EditorStyles.centeredGreyMiniLabel, GUILayout.MaxHeight(_buttonData.texture.height)); + else GUILayout.Label(new GUIContent(_buttonData.texture.loaded_texture, _buttonData.hover), GUILayout.MaxHeight(_buttonData.texture.height)); + Rect r = GUILayoutUtility.GetLastRect(); + if (Event.current.type == EventType.MouseDown && r.Contains(Event.current.mousePosition)) + _buttonData.action.Perform(ShaderEditor.Active?.Materials); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return 0; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs.meta new file mode 100644 index 00000000..6aa82d72 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/LocalMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4e5a24972aaa4b445a7b75361002c6d0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs new file mode 100644 index 00000000..6ba8752f --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class MultiSliderDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + GUILib.MinMaxSlider(position, label, prop); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs.meta new file mode 100644 index 00000000..111f09cc --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/MultiSlider.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5bbd6ae45d0117b44bd8b7bbd1e58a96 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs new file mode 100644 index 00000000..1ea53d83 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class RemoteMessageDrawer : LocalMessageDrawer + { + + protected override void Init(string s) + { + if (_isInit) return; + WebHelper.DownloadStringASync(s, (Action)((string data) => + { + _buttonData = Parser.Deserialize(data); + })); + _isInit = true; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs.meta new file mode 100644 index 00000000..f55691fc --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/RemoteMessage.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 32f11164f1847a14091bc66ddb7154e5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs new file mode 100644 index 00000000..efc783d9 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class SimpleLargeTextureDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + GUILib.BigTexturePropertyBasic(position, prop, label, editor, ((ShaderTextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs.meta new file mode 100644 index 00000000..a0c14a6e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SimpleLargeTexture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 213b200fada9c6141af789bd68c1fc33 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs new file mode 100644 index 00000000..37405f7e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class SmallTextureDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + GUILib.SmallTextureProperty(position, prop, label, editor, ((ShaderTextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs.meta new file mode 100644 index 00000000..d451a8e3 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/SmallTexture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 335752e4d4adf444d935e267da3ae691 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs new file mode 100644 index 00000000..00d66ad7 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class StylizedLargeTextureDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + GUILib.StylizedBigTextureProperty(position, prop, label, editor, ((ShaderTextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs.meta new file mode 100644 index 00000000..b39d8655 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/StylizedLargeTexture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 719c3f337c479f54a9ca1c908e53aeac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs new file mode 100644 index 00000000..fed7bcf4 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class TextureArrayDrawer : MaterialPropertyDrawer + { + private string framesProperty; + + public TextureArrayDrawer() { } + + public TextureArrayDrawer(string framesProperty) + { + this.framesProperty = framesProperty; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + ShaderProperty shaderProperty = (ShaderProperty)ShaderEditor.Active.CurrentProperty; + GUILib.ConfigTextureProperty(position, prop, label, editor, true, true); + + if ((ShaderEditor.Input.is_drag_drop_event) && position.Contains(ShaderEditor.Input.mouse_position)) + { + DragAndDrop.visualMode = DragAndDropVisualMode.Copy; + if (ShaderEditor.Input.is_drop_event) + { + DragAndDrop.AcceptDrag(); + HanldeDropEvent(prop, shaderProperty); + } + } + if (ShaderEditor.Active.IsFirstCall) + ShaderEditor.Active.TextureArrayProperties.Add(shaderProperty); + } + + public void HanldeDropEvent(MaterialProperty prop, ShaderProperty shaderProperty) + { + string[] paths = DragAndDrop.paths; + Texture2DArray tex; + if (AssetDatabase.GetMainAssetTypeAtPath(paths[0]) != typeof(Texture2DArray)) + tex = Converter.PathsToTexture2DArray(paths); + else + tex = AssetDatabase.LoadAssetAtPath(paths[0]); + prop.textureValue = tex; + UpdateFramesProperty(prop, shaderProperty, tex); + EditorGUIUtility.ExitGUI(); + } + + private void UpdateFramesProperty(MaterialProperty prop, ShaderProperty shaderProperty, Texture2DArray tex) + { + if (framesProperty == null) + framesProperty = shaderProperty.Options.reference_property; + + if (framesProperty != null) + { + if (ShaderEditor.Active.PropertyDictionary.ContainsKey(framesProperty)) + ShaderEditor.Active.PropertyDictionary[framesProperty].MaterialProperty.SetNumber(tex.depth); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs.meta new file mode 100644 index 00000000..9bbb3887 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/TextureArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dc00edeaf8634a4448677e6cecbe0e91 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs new file mode 100644 index 00000000..ce9b61df --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryCustomGUIDrawer : MaterialPropertyDrawer + { + private MethodInfo _method; + public ThryCustomGUIDrawer(string type, string namespaceName, string method) + { + Type t = Type.GetType(type + ", " + namespaceName); + if (t != null) + { + _method = t.GetMethod(method); + } + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + if (_method != null) + { + _method.Invoke(null, new object[] { position, prop, label, editor, ShaderEditor.Active }); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return 0; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs.meta new file mode 100644 index 00000000..49ab5d42 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryCustomGUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 775ce26b4b5bcca4096f118fd65230d7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs new file mode 100644 index 00000000..aa802ab8 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryExternalTextureToolDrawer : MaterialPropertyDrawer + { + string _toolTypeName; + string _toolHeader; + + Type t_ExternalToolType; + MethodInfo _onGui; + object _externalTool; + MaterialProperty _prop; + + bool _isTypeLoaded; + bool _doesExternalTypeExist; + bool _isInit; + bool _showTool; + + public ThryExternalTextureToolDrawer(string toolHeader, string toolTypeName) + { + this._toolTypeName = toolTypeName; + this._toolHeader = toolHeader; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + LoadType(); + if (_doesExternalTypeExist) + { + _prop = prop; + GUILib.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties, ExternalGUI); + } + else + { + GUILib.SmallTextureProperty(position, prop, label, editor, DrawingData.CurrentTextureProperty.hasFoldoutProperties); + } + } + + void ExternalGUI() + { + if (GUI.Button(EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()), _toolHeader)) _showTool = !_showTool; + if (_showTool) + { + Init(); + + int indent = EditorGUI.indentLevel; + GUILib.BeginCustomIndentLevel(0); + GUILayout.BeginHorizontal(); + GUILayout.Space(indent * 15); + GUILayout.BeginVertical(); + _onGui.Invoke(_externalTool, new object[0]); + GUILayout.EndVertical(); + GUILayout.EndHorizontal(); + GUILib.EndCustomIndentLevel(); + } + } + + public void LoadType() + { + if (_isTypeLoaded) return; + t_ExternalToolType = AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetType(_toolTypeName)).Where(t => t != null).FirstOrDefault(); + _doesExternalTypeExist = t_ExternalToolType != null; + _isTypeLoaded = true; + } + + public void Init() + { + if (_isInit) return; + if (_isTypeLoaded && _doesExternalTypeExist) + { + _onGui = t_ExternalToolType.GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance); + _externalTool = ScriptableObject.CreateInstance(t_ExternalToolType); + EventInfo eventTextureGenerated = t_ExternalToolType.GetEvent("TextureGenerated"); + if (eventTextureGenerated != null) + eventTextureGenerated.AddEventHandler(_externalTool, new EventHandler(TextureGenerated)); + } + _isInit = true; + } + + void TextureGenerated(object sender, EventArgs args) + { + if (args != null && args.GetType().GetField("generated_texture") != null) + { + Texture2D generated = args.GetType().GetField("generated_texture").GetValue(args) as Texture2D; + _prop.textureValue = generated; + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs.meta new file mode 100644 index 00000000..cdc6210b --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryExternalTextureTool.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 857425fd747aeda44b119b0f07509122 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs new file mode 100644 index 00000000..c2d7a62f --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryIntRangeDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + var range = prop.rangeLimits; + EditorGUI.BeginChangeCheck(); + var value = EditorGUI.IntSlider(position, label, (int)prop.GetNumber(), (int)range.x, (int)range.y); + if (EditorGUI.EndChangeCheck()) + prop.SetNumber(value); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs.meta new file mode 100644 index 00000000..9a4ec1c5 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryIntRange.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85f0c659d42b78641b7fa2df7b14aa47 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs new file mode 100644 index 00000000..8127479d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryMultiFloatsDrawer : MaterialPropertyDrawer + { + string[] _otherProperties; + MaterialProperty[] _otherMaterialProps; + bool _displayAsToggles; + + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5, string p6, string p7) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5, p6, p7 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5, string p6) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5, p6 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4, string p5) : this(displayAsToggles, new string[] { p1, p2, p3, p4, p5 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3, string p4) : this(displayAsToggles, new string[] { p1, p2, p3, p4 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2, string p3) : this(displayAsToggles, new string[] { p1, p2, p3 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1, string p2) : this(displayAsToggles, new string[] { p1, p2 }) { } + public ThryMultiFloatsDrawer(string displayAsToggles, string p1) : this(displayAsToggles, new string[] { p1 }) { } + + public ThryMultiFloatsDrawer(string displayAsToggles, params string[] extraProperties) + { + _displayAsToggles = displayAsToggles.ToLower() == "true" || displayAsToggles == "1"; + _otherProperties = extraProperties; + _otherMaterialProps = new MaterialProperty[extraProperties.Length]; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + Rect labelR = new Rect(position); + labelR.width = EditorGUIUtility.labelWidth; + Rect contentR = new Rect(position); + contentR.width = (contentR.width - labelR.width) / (_otherProperties.Length + 1); + contentR.x += labelR.width; + + for (int i = 0; i < _otherProperties.Length; i++) + _otherMaterialProps[i] = ShaderEditor.Active.PropertyDictionary[_otherProperties[i]].MaterialProperty; + EditorGUI.BeginChangeCheck(); + + EditorGUI.LabelField(labelR, label); + int indentLevel = EditorGUI.indentLevel; //else it double indents + EditorGUI.indentLevel = 0; + PropGUI(prop, contentR, 0); + if (ShaderEditor.Active.IsInAnimationMode) + MaterialEditor.PrepareMaterialPropertiesForAnimationMode(_otherMaterialProps, true); + for (int i = 0; i < _otherProperties.Length; i++) + { + PropGUI(_otherMaterialProps[i], contentR, i + 1); + } + EditorGUI.indentLevel = indentLevel; + + //If edited in animation mode mark as animated (needed cause other properties isnt checked in draw) + if (EditorGUI.EndChangeCheck() && ShaderEditor.Active.IsInAnimationMode && !ShaderEditor.Active.CurrentProperty.IsAnimated) + ShaderEditor.Active.CurrentProperty.SetAnimated(true, false); + //make sure all are animated together + bool animated = ShaderEditor.Active.CurrentProperty.IsAnimated; + bool renamed = ShaderEditor.Active.CurrentProperty.IsRenaming; + for (int i = 0; i < _otherProperties.Length; i++) + ShaderEditor.Active.PropertyDictionary[_otherProperties[i]].SetAnimated(animated, renamed); + } + + void PropGUI(MaterialProperty prop, Rect contentRect, int index) + { + contentRect.x += contentRect.width * index; + contentRect.width -= 5; + + float val = prop.floatValue; + EditorGUI.showMixedValue = prop.hasMixedValue; + EditorGUI.BeginChangeCheck(); + if (_displayAsToggles) val = EditorGUI.Toggle(contentRect, val == 1) ? 1 : 0; + else val = EditorGUI.FloatField(contentRect, val); + if (EditorGUI.EndChangeCheck()) + { + prop.floatValue = val; + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs.meta new file mode 100644 index 00000000..1484bd5d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryMultiFloats.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 69df82e12577e36408ae20e092320402 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs new file mode 100644 index 00000000..83b40b5e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs @@ -0,0 +1,453 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryRGBAPackerDrawer : MaterialPropertyDrawer + { + // TODO : Load lacale by property name in the future: propname_r, propname_g, propname_b, propname_a + class ThryRGBAPackerData + { + public Texture _previousTexture; + public Texture2D _packedTexture; + + public InlinePackerChannelConfig _input_r; + public InlinePackerChannelConfig _input_g; + public InlinePackerChannelConfig _input_b; + public InlinePackerChannelConfig _input_a; + + public bool _isInit; + public bool _hasConfigChanged; + public bool _hasTextureChanged; + public long _lastConfirmTime; + public int _overwriteShowInline; + + public TexturePacker.Connection[] _connections; + public TexturePacker.TextureSource[] _sources; + } + + Dictionary materialPackerData = new Dictionary(); + + MaterialProperty _prop; + ThryRGBAPackerData _current; + + string _label1; + string _label2; + string _label3; + string _label4; + bool _firstTextureIsRGB; + ColorSpace _colorSpace = ColorSpace.Gamma; + bool _alphaIsTransparency = true; + + // for locale changing + // i tried using an array to save the default labels, but the data just got lost somewhere. not sure why + string _defaultLabel1; + string _defaultLabel2; + string _defaultLabel3; + string _defaultLabel4; + int _reloadCount = -1; + static int _reloadCountStatic; + + public static void Reload() + { + _reloadCountStatic++; + } + + void LoadLabels() + { + if (_reloadCount == _reloadCountStatic) return; + // using the string itself as a key for reuse in other places. this might cause issues, if it does in the future + // we can add the class name as a prefix to the key + _label1 = ShaderEditor.Active.Locale.Get(_defaultLabel1, _defaultLabel1); + _label2 = ShaderEditor.Active.Locale.Get(_defaultLabel2, _defaultLabel2); + _label3 = ShaderEditor.Active.Locale.Get(_defaultLabel3, _defaultLabel3); + _label4 = ShaderEditor.Active.Locale.Get(_defaultLabel4, _defaultLabel4); + _reloadCount = _reloadCountStatic; + } + + // end locale changing + + public ThryRGBAPackerDrawer(string label1, string label2, string label3, string label4, string colorspace, string alphaIsTransparency) + { + _label1 = string.IsNullOrWhiteSpace(label1) ? null : label1; + _label2 = string.IsNullOrWhiteSpace(label2) ? null : label2; + _label3 = string.IsNullOrWhiteSpace(label3) ? null : label3; + _label4 = string.IsNullOrWhiteSpace(label4) ? null : label4; + _defaultLabel1 = _label1; + _defaultLabel2 = _label2; + _defaultLabel3 = _label3; + _defaultLabel4 = _label4; + _colorSpace = (colorspace == "linear" || colorspace == "Linear") ? ColorSpace.Linear : ColorSpace.Gamma; + _alphaIsTransparency = alphaIsTransparency == "true" || alphaIsTransparency == "True"; + } + + public ThryRGBAPackerDrawer(string label1, string label2, string colorspace, string alphaIsTransparency) : this(label1, label2, null, null, colorspace, alphaIsTransparency) + { + _firstTextureIsRGB = true; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + _prop = prop; + if (materialPackerData.ContainsKey(_prop.targets[0]) == false) materialPackerData[_prop.targets[0]] = new ThryRGBAPackerData(); + _current = materialPackerData[_prop.targets[0]]; + // So showFoldoutProperties is reset to false a few events after an undo event. + // To keep the texture packer open we just force it to ture until this reset is done (which happens in / after the ValidateCommand event, right before the KeyUp event) + if (_current._overwriteShowInline > 0) + { + DrawingData.CurrentTextureProperty.showFoldoutProperties = true; + if (Event.current.type == EventType.ValidateCommand) + _current._overwriteShowInline = 1; + else if (Event.current.type == EventType.Layout && _current._overwriteShowInline == 1) + _current._overwriteShowInline = 0; + } + GUILib.SmallTextureProperty(position, prop, label, editor, true, TexturePackerGUI); + if (_prop.textureValue != _current._packedTexture) _current._previousTexture = _prop.textureValue; + } + + bool DidTextureGetEdit(InlinePackerChannelConfig data) + { + if (data.TextureSource.Texture == null) return false; + string path = AssetDatabase.GetAssetPath(data.TextureSource.Texture); + if (System.IO.File.Exists(path) == false) return false; + long lastEditTime = Helper.DatetimeToUnixSeconds(System.IO.File.GetLastWriteTime(path)); + bool hasBeenEdited = lastEditTime > _current._lastConfirmTime && lastEditTime != data.TextureSource.LastHandledTextureEditTime; + data.TextureSource.LastHandledTextureEditTime = lastEditTime; + if (hasBeenEdited) TexturePacker.TextureSource.SetUncompressedTextureDirty(data.TextureSource.Texture); + return hasBeenEdited; + } + + void TexturePackerGUI() + { + Init(); + LoadLabels(); + EditorGUI.BeginChangeCheck(); + _current._input_r = TexturePackerSlotGUI(_current._input_r, _label1); + _current._input_g = TexturePackerSlotGUI(_current._input_g, _label2); + if (_label3 != null) _current._input_b = TexturePackerSlotGUI(_current._input_b, _label3); + if (_label4 != null) _current._input_a = TexturePackerSlotGUI(_current._input_a, _label4); + bool changeCheck = EditorGUI.EndChangeCheck(); + changeCheck |= DidTextureGetEdit(_current._input_r); + changeCheck |= DidTextureGetEdit(_current._input_g); + changeCheck |= DidTextureGetEdit(_current._input_b); + changeCheck |= DidTextureGetEdit(_current._input_a); + if (changeCheck) + { + _current._hasConfigChanged = true; + foreach (Material m in ShaderEditor.Active.Materials) + Undo.RegisterCompleteObjectUndo(m, "Thry Packer Texture Change " + _prop.name); + Save(); + Pack(); + } + + Rect buttonRect = EditorGUI.IndentedRect(EditorGUILayout.GetControlRect()); + buttonRect.width /= 3; + EditorGUI.BeginDisabledGroup(!_current._hasConfigChanged); + if (GUI.Button(buttonRect, "Confirm Merge")) Confirm(); + buttonRect.x += buttonRect.width; + EditorGUI.EndDisabledGroup(); + EditorGUI.BeginDisabledGroup(!_current._hasTextureChanged); + if (GUI.Button(buttonRect, "Revert")) Revert(); + EditorGUI.EndDisabledGroup(); + buttonRect.x += buttonRect.width; + if (GUI.Button(buttonRect, "Advanced")) OpenFullTexturePacker(); + } + + InlinePackerChannelConfig TexturePackerSlotGUI(InlinePackerChannelConfig input, string label) + { + Rect totalRect = EditorGUILayout.GetControlRect(false); + totalRect = EditorGUI.IndentedRect(totalRect); + Rect r = totalRect; + + int ind = EditorGUI.indentLevel; + EditorGUI.indentLevel = 0; + + float texWidth = Math.Max(50, r.width - 130 - 30) - 5; + r.x = totalRect.x; + r.width = 30; + EditorGUI.BeginChangeCheck(); + Texture2D changed = EditorGUI.ObjectField(r, input.TextureSource.Texture, typeof(Texture2D), false) as Texture2D; + if (EditorGUI.EndChangeCheck()) + { + input.TextureSource.SetInputTexture(changed); + } + + r.x += r.width + 5; + r.width = texWidth - 5; + EditorGUI.LabelField(r, label); + + if (input.TextureSource.Texture == null) + { + r.width = 70; + r.x = totalRect.x + totalRect.width - r.width; + input.Fallback = EditorGUI.FloatField(r, input.Fallback); + + r.width = 60; + r.x -= r.width; + EditorGUI.LabelField(r, "Fallback:"); + } + else + { + r.width = 50; + r.x = totalRect.x + totalRect.width - r.width; + if (!_firstTextureIsRGB || input != _current._input_r) + input.Channel = (TexturePacker.TextureChannelIn)EditorGUI.EnumPopup(r, input.Channel); + + r.width = 20; + r.x -= r.width; + input.Invert = EditorGUI.Toggle(r, input.Invert); + + r.width = 60; + r.x -= r.width; + EditorGUI.LabelField(r, "Inverted:"); + } + + EditorGUI.indentLevel = ind; + + return input; + } + + void Init() + { + if (_current._isInit) return; + _current._input_r = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "r"); + _current._input_g = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "g"); + _current._input_b = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "b"); + _current._input_a = LoadForChannel(ShaderEditor.Active.Materials[0], _prop.name, "a"); + _current._lastConfirmTime = long.Parse(ShaderEditor.Active.Materials[0].GetTag(_prop.name + "_texPack_lastConfirmTime", false, "" + Helper.DatetimeToUnixSeconds(DateTime.Now))); + _current._previousTexture = _prop.textureValue; + _current._isInit = true; + +#if UNITY_2022_1_OR_NEWER + Undo.undoRedoEvent += OnUndoRedo; + } + + void OnUndoRedo(in UndoRedoInfo undoRedoInfo) + { + if (undoRedoInfo.undoName == "Thry Packer Texture Change " + _prop.name) + { + _current._isInit = false; + _current._overwriteShowInline = 2; + Undo.undoRedoEvent -= OnUndoRedo; + } +#endif + } + + void Save() + { + SaveForChannel(_current._input_r, _prop.name, "r"); + SaveForChannel(_current._input_g, _prop.name, "g"); + SaveForChannel(_current._input_b, _prop.name, "b"); + SaveForChannel(_current._input_a, _prop.name, "a"); + foreach (Material m in ShaderEditor.Active.Materials) + { + m.SetOverrideTag(_prop.name + "_texPack_lastConfirmTime", "" + _current._lastConfirmTime); + } + } + + void SaveForChannel(InlinePackerChannelConfig input, string id, string channel) + { + foreach (Material m in ShaderEditor.Active.Materials) + { + if (input.TextureSource.Texture != null) m.SetOverrideTag(id + "_texPack_" + channel + "_guid", AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(input.TextureSource.Texture))); + else m.SetOverrideTag(id + "_texPack_" + channel + "_guid", ""); + m.SetOverrideTag(id + "_texPack_" + channel + "_fallback", input.Fallback.ToString()); + m.SetOverrideTag(id + "_texPack_" + channel + "_inverted", input.Invert.ToString()); + m.SetOverrideTag(id + "_texPack_" + channel + "_channel", ((int)input.Channel).ToString()); + } + } + + InlinePackerChannelConfig LoadForChannel(Material m, string id, string channel) + { + InlinePackerChannelConfig packerChannelConfig = new InlinePackerChannelConfig(); + packerChannelConfig.Fallback = float.Parse(m.GetTag(id + "_texPack_" + channel + "_fallback", false, "1")); + packerChannelConfig.Invert = bool.Parse(m.GetTag(id + "_texPack_" + channel + "_inverted", false, "false")); + packerChannelConfig.Channel = (TexturePacker.TextureChannelIn)int.Parse(m.GetTag(id + "_texPack_" + channel + "_channel", false, "4")); + string guid = m.GetTag(id + "_texPack_" + channel + "_guid", false, ""); + if (string.IsNullOrEmpty(guid) == false) + { + string p = AssetDatabase.GUIDToAssetPath(guid); + if (p != null) + packerChannelConfig.TextureSource.SetInputTexture(AssetDatabase.LoadAssetAtPath(p)); + } + return packerChannelConfig; + } + + void Pack() + { + _current._packedTexture = TexturePacker.Pack(GetTextureSources(), GetOutputConfigs(), GetConnections(), GetFiltermode(), _colorSpace, alphaIsTransparency: _alphaIsTransparency); + _prop.textureValue = _current._packedTexture; + + _current._hasTextureChanged = true; + } + + TexturePacker.TextureSource[] GetTextureSources() + { + // build sources array + return new TexturePacker.TextureSource[4]{ + _current._input_r.TextureSource, _current._input_g.TextureSource, _current._input_b.TextureSource, _current._input_a.TextureSource }; + } + + TexturePacker.OutputConfig[] GetOutputConfigs() + { + // Build OutputConfig Array + TexturePacker.OutputConfig[] outputConfigs = new TexturePacker.OutputConfig[4]; + + if (_firstTextureIsRGB) + { + outputConfigs[0] = _current._input_r.ToOutputConfig(); + outputConfigs[1] = _current._input_r.ToOutputConfig(); + outputConfigs[2] = _current._input_r.ToOutputConfig(); + outputConfigs[3] = _current._input_g.ToOutputConfig(); + } + else + { + outputConfigs[0] = _current._input_r.ToOutputConfig(); + outputConfigs[1] = _current._input_g.ToOutputConfig(); + outputConfigs[2] = _current._input_b.ToOutputConfig(); + outputConfigs[3] = _current._input_a.ToOutputConfig(); + } + return outputConfigs; + } + + TexturePacker.Connection[] GetConnections() + { + // Build connections array + TexturePacker.Connection[] connections = new TexturePacker.Connection[4]; + if (_firstTextureIsRGB) + { + connections[0] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.R, TexturePacker.TextureChannelOut.R); + connections[1] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.G, TexturePacker.TextureChannelOut.G); + connections[2] = TexturePacker.Connection.CreateFull(0, TexturePacker.TextureChannelIn.B, TexturePacker.TextureChannelOut.B); + connections[3] = TexturePacker.Connection.CreateFull(1, _current._input_g.Channel, TexturePacker.TextureChannelOut.A); + } + else + { + connections[0] = TexturePacker.Connection.CreateFull(0, _current._input_r.Channel, TexturePacker.TextureChannelOut.R); + connections[1] = TexturePacker.Connection.CreateFull(1, _current._input_g.Channel, TexturePacker.TextureChannelOut.G); + connections[2] = TexturePacker.Connection.CreateFull(2, _current._input_b.Channel, TexturePacker.TextureChannelOut.B); + connections[3] = TexturePacker.Connection.CreateFull(3, _current._input_a.Channel, TexturePacker.TextureChannelOut.A); + } + return connections; + } + + void OpenFullTexturePacker() + { + TexturePacker packer = TexturePacker.ShowWindow(); + packer.InitilizeWithData(GetTextureSources(), GetOutputConfigs(), GetConnections(), GetFiltermode(), _colorSpace, _alphaIsTransparency); + packer.OnChange += FullTexturePackerOnChange; + packer.OnSave += FullTexturePackerOnSave; + } + + void FullTexturePackerOnSave(Texture2D tex) + { + _current._packedTexture = tex; + _prop.textureValue = _current._packedTexture; + _current._hasTextureChanged = false; + } + + void FullTexturePackerOnChange(Texture2D tex, TexturePacker.TextureSource[] sources, TexturePacker.OutputConfig[] configs, TexturePacker.Connection[] connections) + { + TexturePacker.Connection connection_0 = connections.Where(c => c.FromTextureIndex == 0).FirstOrDefault(); + TexturePacker.Connection connection_1 = connections.Where(c => c.FromTextureIndex == 1).FirstOrDefault(); + TexturePacker.Connection connection_2 = connections.Where(c => c.FromTextureIndex == 2).FirstOrDefault(); + TexturePacker.Connection connection_3 = connections.Where(c => c.FromTextureIndex == 3).FirstOrDefault(); + + _current._input_r.TextureSource = connection_0 != null ? sources[0] : new TextureSource(); + _current._input_g.TextureSource = connection_1 != null ? sources[1] : new TextureSource(); + _current._input_b.TextureSource = connection_2 != null ? sources[2] : new TextureSource(); + _current._input_a.TextureSource = connection_3 != null ? sources[3] : new TextureSource(); + + _current._input_r.FromOutputConfig(configs[0]); + _current._input_g.FromOutputConfig(configs[1]); + _current._input_b.FromOutputConfig(configs[2]); + _current._input_a.FromOutputConfig(configs[3]); + + _current._input_r.Channel = connection_0 != null ? connection_0.FromChannel : TexturePacker.TextureChannelIn.Max; + _current._input_g.Channel = connection_1 != null ? connection_1.FromChannel : TexturePacker.TextureChannelIn.Max; + _current._input_b.Channel = connection_2 != null ? connection_2.FromChannel : TexturePacker.TextureChannelIn.Max; + _current._input_a.Channel = connection_3 != null ? connection_3.FromChannel : TexturePacker.TextureChannelIn.Max; + + _current._packedTexture = tex; + _prop.textureValue = _current._packedTexture; + _current._hasTextureChanged = true; + _current._hasConfigChanged = true; + } + + FilterMode GetFiltermode() + { + if (_current._input_r.GetTexture() != null) return _current._input_r.GetTexture().filterMode; + if (_current._input_g.GetTexture() != null) return _current._input_g.GetTexture().filterMode; + if (_current._input_b.GetTexture() != null) return _current._input_b.GetTexture().filterMode; + if (_current._input_a.GetTexture() != null) return _current._input_a.GetTexture().filterMode; + return FilterMode.Bilinear; + } + + void Confirm() + { + if (_current._packedTexture == null) Pack(); + string path = System.IO.Path.GetDirectoryName(AssetDatabase.GetAssetPath(ShaderEditor.Active.Materials[0])); + path = path + "/" + ShaderEditor.Active.Materials[0].name + _prop.name + ".png"; + _prop.textureValue = TextureHelper.SaveTextureAsPNG(_current._packedTexture, path); + TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; + importer.streamingMipmaps = true; + importer.crunchedCompression = true; + importer.sRGBTexture = _colorSpace == ColorSpace.Gamma; + importer.filterMode = GetFiltermode(); + importer.alphaIsTransparency = _current._packedTexture.alphaIsTransparency; + importer.SaveAndReimport(); + + _current._hasConfigChanged = false; + _current._hasTextureChanged = false; + _current._lastConfirmTime = Helper.DatetimeToUnixSeconds(DateTime.Now); + } + + void Revert() + { + _prop.textureValue = _current._previousTexture; + _current._hasTextureChanged = false; + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + + class InlinePackerChannelConfig + { + public TexturePacker.TextureSource TextureSource = new TexturePacker.TextureSource(); + public bool Invert; + public float Fallback; + public TexturePacker.TextureChannelIn Channel = TexturePacker.TextureChannelIn.Max; + + public TexturePacker.OutputConfig ToOutputConfig() + { + TexturePacker.OutputConfig outputConfig = new TexturePacker.OutputConfig(); + outputConfig.BlendMode = TexturePacker.BlendMode.Add; + outputConfig.Invert = Invert ? TexturePacker.InvertMode.Invert : TexturePacker.InvertMode.None; + outputConfig.Fallback = Fallback; + return outputConfig; + } + + public void FromOutputConfig(TexturePacker.OutputConfig config) + { + Invert = config.Invert == TexturePacker.InvertMode.Invert; + Fallback = config.Fallback; + } + + public Texture2D GetTexture() + { + if (TextureSource == null) return null; + return TextureSource.Texture; + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs.meta new file mode 100644 index 00000000..c457ee78 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRGBAPacker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a2e8a3ad288fc847879ddd9ea2c98c4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs new file mode 100644 index 00000000..ea6f58e1 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryRichLabelDrawer : MaterialPropertyDrawer + { + readonly int _size; + GUIStyle _style; + + public ThryRichLabelDrawer(float size) + { + this._size = (int)size; + } + + public ThryRichLabelDrawer() : this(EditorStyles.standardFont.fontSize) { } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + return _size + 4; + } + + public override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor) + { + // Done here instead of constructor because else unity throws warnings + if (_style == null) + { + _style = new GUIStyle(EditorStyles.boldLabel); + _style.richText = true; + _style.fontSize = this._size; + } + + float offst = position.height; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, label, _style); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs.meta new file mode 100644 index 00000000..936e7819 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryRichLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b4560f3118b9bb64e8405a3e4a46143a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs new file mode 100644 index 00000000..4e01c180 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryShaderOptimizerLockButtonDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty shaderOptimizer, string label, MaterialEditor materialEditor) + { + Material material = shaderOptimizer.targets[0] as Material; + Shader shader = material.shader; + // The GetPropertyDefaultFloatValue is changed from 0 to 1 when the shader is locked in + bool isLocked = shader.name.StartsWith("Hidden/Locked/") || + (shader.name.StartsWith("Hidden/") && material.GetTag("OriginalShader", false, "") != "" && shader.GetPropertyDefaultFloatValue(shader.FindPropertyIndex(shaderOptimizer.name)) == 1); + //this will make sure the button is unlocked if you manually swap to an unlocked shader + //shaders that have the ability to be locked shouldnt really be hidden themself. at least it wouldnt make too much sense + if (shaderOptimizer.hasMixedValue == false && shaderOptimizer.GetNumber() == 1 && isLocked == false) + { + shaderOptimizer.SetNumber(0); + } + else if (shaderOptimizer.hasMixedValue == false && shaderOptimizer.GetNumber() == 0 && isLocked) + { + shaderOptimizer.SetNumber(1); + } + + bool disabled = false; +#if UNITY_2022_1_OR_NEWER + disabled |= ShaderEditor.Active.Materials[0].isVariant; +#endif + EditorGUI.BeginDisabledGroup(disabled); // for variant materials + + // Theoretically this shouldn't ever happen since locked in materials have different shaders. + // But in a case where the material property says its locked in but the material really isn't, this + // will display and allow users to fix the property/lock in + ShaderEditor.Active.IsLockedMaterial = shaderOptimizer.GetNumber() == 1; + if (shaderOptimizer.hasMixedValue) + { + EditorGUI.BeginChangeCheck(); + GUILayout.Button(EditorLocale.editor.Get("lockin_button_multi").ReplaceVariables(materialEditor.targets.Length)); + if (EditorGUI.EndChangeCheck()) + { + SaveChangeStack(); + ShaderOptimizer.SetLockedForAllMaterials(shaderOptimizer.targets.Select(t => t as Material), shaderOptimizer.floatValue == 1 ? 0 : 1, true, false, false, shaderOptimizer); + RestoreChangeStack(); + } + } + else + { + EditorGUI.BeginChangeCheck(); + if (shaderOptimizer.GetNumber() == 0) + { + if (materialEditor.targets.Length == 1) + RectifiedLayout.Button(EditorLocale.editor.Get("lockin_button_single")); + else RectifiedLayout.Button(EditorLocale.editor.Get("lockin_button_multi").ReplaceVariables(materialEditor.targets.Length)); + } + else + { + if (materialEditor.targets.Length == 1) + RectifiedLayout.Button(EditorLocale.editor.Get("unlock_button_single")); + else RectifiedLayout.Button(EditorLocale.editor.Get("unlock_button_multi").ReplaceVariables(materialEditor.targets.Length)); + } + if (EditorGUI.EndChangeCheck()) + { + SaveChangeStack(); + ShaderOptimizer.SetLockedForAllMaterials(shaderOptimizer.targets.Select(t => t as Material), shaderOptimizer.GetNumber() == 1 ? 0 : 1, true, false, false, shaderOptimizer); + RestoreChangeStack(); + } + } + if (Config.Singleton.allowCustomLockingRenaming || ShaderEditor.Active.HasCustomRenameSuffix) + { + EditorGUI.BeginDisabledGroup(!Config.Singleton.allowCustomLockingRenaming || ShaderEditor.Active.IsLockedMaterial); + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = ShaderEditor.Active.HasMixedCustomPropertySuffix; + ShaderEditor.Active.RenamedPropertySuffix = EditorGUILayout.TextField("Locked property suffix: ", ShaderEditor.Active.RenamedPropertySuffix); + if (EditorGUI.EndChangeCheck()) + { + // Make sure suffix that is saved is valid + ShaderEditor.Active.RenamedPropertySuffix = ShaderOptimizer.CleanStringForPropertyNames(ShaderEditor.Active.RenamedPropertySuffix.Replace(" ", "_")); + foreach (Material m in ShaderEditor.Active.Materials) + m.SetOverrideTag("thry_rename_suffix", ShaderEditor.Active.RenamedPropertySuffix); + if (ShaderEditor.Active.RenamedPropertySuffix == "") + ShaderEditor.Active.RenamedPropertySuffix = ShaderOptimizer.GetRenamedPropertySuffix(ShaderEditor.Active.Materials[0]); + ShaderEditor.Active.HasCustomRenameSuffix = ShaderOptimizer.HasCustomRenameSuffix(ShaderEditor.Active.Materials[0]); + } + if (!Config.Singleton.allowCustomLockingRenaming) + { + EditorGUILayout.HelpBox("This feature is disabled in the config file. You can enable it by setting allowCustomLockingRenaming to true.", MessageType.Info); + } + EditorGUI.EndDisabledGroup(); + } + + EditorGUI.EndDisabledGroup(); // for variant materials + } + + //This code purly exists cause Unity 2019 is a piece of shit that looses it's internal change stack on locking CAUSE FUCK IF I KNOW + static System.Reflection.FieldInfo changeStack = typeof(EditorGUI).GetField("s_ChangedStack", BindingFlags.Static | BindingFlags.NonPublic); + static int preLockStackSize = 0; + private static void SaveChangeStack() + { + if (changeStack != null) + { + Stack stack = (Stack)changeStack.GetValue(null); + if (stack != null) + { + preLockStackSize = stack.Count(); + } + } + } + + private static void RestoreChangeStack() + { + if (changeStack != null) + { + Stack stack = (Stack)changeStack.GetValue(null); + if (stack != null) + { + int postLockStackSize = stack.Count(); + //Restore change stack from before lock / unlocking + for (int i = postLockStackSize; i < preLockStackSize; i++) + { + EditorGUI.BeginChangeCheck(); + } + } + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + DrawingData.LastPropertyDoesntAllowAnimation = true; + ShaderEditor.Active.DoUseShaderOptimizer = true; + return -2; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs.meta new file mode 100644 index 00000000..c66df6d9 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryShaderOptimizerLockButton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: eca3e64717baa0848ab849e94212e1c5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs new file mode 100644 index 00000000..d6e36cad --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryTextureDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + GUILib.ConfigTextureProperty(position, prop, label, editor, ((ShaderTextureProperty)ShaderEditor.Active.CurrentProperty).hasScaleOffset); + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs.meta new file mode 100644 index 00000000..c2931a0d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryTexture.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5214bf61cea3fbc439617fa03ab4542c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs new file mode 100644 index 00000000..810bf14c --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs @@ -0,0 +1,162 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryToggleDrawer : MaterialPropertyDrawer + { + public string keyword; + private bool isFirstGUICall = true; + public bool left = false; + private bool hasKeyword = false; + + public ThryToggleDrawer() + { + } + + //the reason for weird string thing here is that you cant have bools as params for drawers + public ThryToggleDrawer(string keywordLeft) + { + if (keywordLeft == "true") left = true; + else if (keywordLeft == "false") left = false; + else keyword = keywordLeft; + hasKeyword = keyword != null; + } + + public ThryToggleDrawer(string keyword, string left) + { + this.keyword = keyword; + this.left = left == "true"; + hasKeyword = keyword != null; + } + + protected void SetKeyword(MaterialProperty prop, bool on) + { + if (ShaderOptimizer.IsMaterialLocked(prop.targets[0] as Material)) return; + SetKeywordInternal(prop, on, "_ON"); + } + + protected void CheckKeyword(MaterialProperty prop) + { + if (ShaderEditor.Active != null && ShaderOptimizer.IsMaterialLocked(prop.targets[0] as Material)) return; + if (prop.hasMixedValue) + { + foreach (Material m in prop.targets) + { + if (m.GetNumber(prop) == 1) + m.EnableKeyword(keyword); + else + m.DisableKeyword(keyword); + } + } + else + { + foreach (Material m in prop.targets) + { + if (prop.GetNumber() == 1) + m.EnableKeyword(keyword); + else + m.DisableKeyword(keyword); + } + } + } + + static bool IsPropertyTypeSuitable(MaterialProperty prop) + { + return prop.type == MaterialProperty.PropType.Float + || prop.type == MaterialProperty.PropType.Range +#if UNITY_2022_1_OR_NEWER + || prop.type == MaterialProperty.PropType.Int; +#endif + ; + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + if (!IsPropertyTypeSuitable(prop)) + { + return EditorGUIUtility.singleLineHeight * 2.5f; + } + if (hasKeyword) + { + CheckKeyword(prop); + DrawingData.LastPropertyDoesntAllowAnimation = true; + } + return base.GetPropertyHeight(prop, label, editor); + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + if (!IsPropertyTypeSuitable(prop)) + { + return; + } + if (isFirstGUICall && !ShaderEditor.Active.IsLockedMaterial) + { + if (hasKeyword) CheckKeyword(prop); + isFirstGUICall = false; + } + //why is this not inFirstGUICall ? cause it seems drawers are kept between different openings of the shader editor, so this needs to be set again every time the shader editor is reopened for that material + ShaderEditor.Active.PropertyDictionary[prop.name].SetKeyword(keyword); + + if (hasKeyword) + ShaderEditor.Active.Editor.EndAnimatedCheck(); + + EditorGUI.BeginChangeCheck(); + + bool value = (Math.Abs(prop.GetNumber()) > 0.001f); + EditorGUI.showMixedValue = prop.hasMixedValue; + if (left) value = EditorGUI.ToggleLeft(position, label, value, Styles.style_toggle_left_richtext); + else value = EditorGUI.Toggle(position, label, value); + EditorGUI.showMixedValue = false; + if (EditorGUI.EndChangeCheck()) + { + bool wasRecording = UnityHelper.InAnimationRecording(); + if (hasKeyword && wasRecording) + UnityHelper.StopAnimationRecording(); + + prop.SetNumber(value ? 1.0f : 0.0f); + if (hasKeyword) + SetKeyword(prop, value); + + if (hasKeyword && wasRecording) + UnityHelper.StartAnimationRecording(); + } + + ShaderEditor.Active.Editor.BeginAnimatedCheck(prop); + } + + public override void Apply(MaterialProperty prop) + { + base.Apply(prop); + if (!IsPropertyTypeSuitable(prop)) + return; + + if (prop.hasMixedValue) + return; + + if (hasKeyword) SetKeyword(prop, (Math.Abs(prop.GetNumber()) > 0.001f)); + } + + protected void SetKeywordInternal(MaterialProperty prop, bool on, string defaultKeywordSuffix) + { + // if no keyword is provided, use + defaultKeywordSuffix + string kw = string.IsNullOrEmpty(keyword) ? prop.name.ToUpperInvariant() + defaultKeywordSuffix : keyword; + // set or clear the keyword + foreach (Material material in prop.targets) + { + if (on) + material.EnableKeyword(kw); + else + material.DisableKeyword(kw); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs.meta new file mode 100644 index 00000000..61aa333d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e9fbbc14860b69548a12caf0663b2274 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs new file mode 100644 index 00000000..4920af9e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class ThryToggleUIDrawer : ThryToggleDrawer + { + public ThryToggleUIDrawer() + { + } + + //the reason for weird string thing here is that you cant have bools as params for drawers + public ThryToggleUIDrawer(string keywordLeft) + { + if (keywordLeft == "true") left = true; + else if (keywordLeft == "false") left = false; + else keyword = keywordLeft; + } + + public ThryToggleUIDrawer(string keyword, string left) + { + this.keyword = keyword; + this.left = left == "true"; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs.meta new file mode 100644 index 00000000..24e83375 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryToggleUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 808bc088b8745044e84383d71ddeb173 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs new file mode 100644 index 00000000..f17f1949 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + // Enum with normal editor width, rather than MaterialEditor Default GUI widths + // Would be nice if Decorators could access Drawers too so this wouldn't be necessary for something to trivial + // Adapted from Unity interal MaterialEnumDrawer https://github.com/Unity-Technologies/UnityCsReference/ + public class ThryWideEnumDrawer : MaterialPropertyDrawer + { + // TODO: Consider Load locale by property name in the future (maybe, could have drawbacks) + private GUIContent[] names; + private readonly string[] defaultNames; + private readonly float[] values; + private int _reloadCount = -1; + private static int _reloadCountStatic; + + public static bool RenderLabel = true; + + // internal Unity AssemblyHelper can't be accessed + private Type[] TypesFromAssembly(Assembly a) + { + if (a == null) + return new Type[0]; + try + { + return a.GetTypes(); + } + catch (ReflectionTypeLoadException) + { + return new Type[0]; + } + } + public ThryWideEnumDrawer(string enumName, int j) + { + var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany( + x => TypesFromAssembly(x)).ToArray(); + try + { + var enumType = types.FirstOrDefault( + x => x.IsEnum && (x.Name == enumName || x.FullName == enumName) + ); + var enumNames = Enum.GetNames(enumType); + names = new GUIContent[enumNames.Length]; + for (int i = 0; i < enumNames.Length; ++i) + names[i] = new GUIContent(enumNames[i]); + + var enumVals = Enum.GetValues(enumType); + values = new float[enumVals.Length]; + for (int i = 0; i < enumVals.Length; ++i) + values[i] = (int)enumVals.GetValue(i); + } + catch (Exception) + { + Debug.LogWarningFormat("Failed to create WideEnum, enum {0} not found", enumName); + throw; + } + + } + + public ThryWideEnumDrawer(string n1, float v1) : this(new[] { n1 }, new[] { v1 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2) : this(new[] { n1, n2 }, new[] { v1, v2 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3) : this(new[] { n1, n2, n3 }, new[] { v1, v2, v3 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4) : this(new[] { n1, n2, n3, n4 }, new[] { v1, v2, v3, v4 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5) : this(new[] { n1, n2, n3, n4, n5 }, new[] { v1, v2, v3, v4, v5 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6) : this(new[] { n1, n2, n3, n4, n5, n6 }, new[] { v1, v2, v3, v4, v5, v6 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7) : this(new[] { n1, n2, n3, n4, n5, n6, n7 }, new[] { v1, v2, v3, v4, v5, v6, v7 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18, string n19, float v19) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19 }) { } + public ThryWideEnumDrawer(string n1, float v1, string n2, float v2, string n3, float v3, string n4, float v4, string n5, float v5, string n6, float v6, string n7, float v7, string n8, float v8, string n9, float v9, string n10, float v10, string n11, float v11, string n12, float v12, string n13, float v13, string n14, float v14, string n15, float v15, string n16, float v16, string n17, float v17, string n18, float v18, string n19, float v19, string n20, float v20) : this(new[] { n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15, n16, n17, n18, n19, n20 }, new[] { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20 }) { } + public ThryWideEnumDrawer(string[] enumNames, float[] vals) + { + defaultNames = enumNames; + + // Init without Locale to prevent errors + names = new GUIContent[enumNames.Length]; + for (int i = 0; i < enumNames.Length; ++i) + names[i] = new GUIContent(enumNames[i]); + + values = new float[vals.Length]; + for (int i = 0; i < vals.Length; ++i) + values[i] = vals[i]; + } + + void LoadNames() + { + names = new GUIContent[defaultNames.Length]; + for (int i = 0; i < defaultNames.Length; ++i) + { + names[i] = new GUIContent(ShaderEditor.Active.Locale.Get(defaultNames[i], defaultNames[i])); + } + } + public static void Reload() + { + _reloadCountStatic++; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUI.showMixedValue = prop.hasMixedValue; + float value = prop.GetNumber(); + int selectedIndex = Array.IndexOf(values, value); + + if (_reloadCount != _reloadCountStatic) + { + _reloadCount = _reloadCountStatic; + LoadNames(); + } + + // Custom Change Check, so it triggers on reselect too + bool wasClickEvent = Event.current.type == EventType.ExecuteCommand; + int selIndex; + if(RenderLabel) + selIndex = EditorGUI.Popup(position, label, selectedIndex, names); + else + selIndex = EditorGUI.Popup(position, selectedIndex, names); + EditorGUI.showMixedValue = false; + if (wasClickEvent && Event.current.type == EventType.Used) + { + // Set GUI.changed to true, so it triggers a change event, even on reselection + GUI.changed = true; + prop.SetNumber(values[selIndex]); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + + public enum ColorMask + { + None, + Alpha, + Blue, + BA, + Green, + GA, + GB, + GBA, + Red, + RA, + RB, + RBA, + RG, + RGA, + RGB, + RGBA + } + + // DX11 only blend operations + public enum BlendOp + { + Add, + Subtract, + ReverseSubtract, + Min, + Max, + LogicalClear, + LogicalSet, + LogicalCopy, + LogicalCopyInverted, + LogicalNoop, + LogicalInvert, + LogicalAnd, + LogicalNand, + LogicalOr, + LogicalNor, + LogicalXor, + LogicalEquivalence, + LogicalAndReverse, + LogicalAndInverted, + LogicalOrReverse, + LogicalOrInverted + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs.meta new file mode 100644 index 00000000..54195592 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/ThryWideEnum.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a2f135f1c3200ac4aa76f9b1227d7916 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs new file mode 100644 index 00000000..7af07399 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class Vector2Drawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = prop.hasMixedValue; + Vector4 vec = EditorGUI.Vector2Field(position, label, prop.vectorValue); + if (EditorGUI.EndChangeCheck()) + { + prop.vectorValue = new Vector4(vec.x, vec.y, prop.vectorValue.z, prop.vectorValue.w); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs.meta new file mode 100644 index 00000000..e931805a --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector2.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f9651914d1c2d2c4a9ec112013e059f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs new file mode 100644 index 00000000..64d2352d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class Vector3Drawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = prop.hasMixedValue; + Vector4 vec = EditorGUI.Vector3Field(position, label, prop.vectorValue); + if (EditorGUI.EndChangeCheck()) + { + prop.vectorValue = new Vector4(vec.x, vec.y, vec.z, prop.vectorValue.w); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs.meta new file mode 100644 index 00000000..19e0225b --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector3.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cd91476f71a0d244f8fd7bea9513adff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs new file mode 100644 index 00000000..891129b0 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class Vector4TogglesDrawer : MaterialPropertyDrawer + { + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = prop.hasMixedValue; + EditorGUI.LabelField(position, label); + position.x += EditorGUIUtility.labelWidth; + position.width = (position.width - EditorGUIUtility.labelWidth) / 4; + bool b1 = GUI.Toggle(position, prop.vectorValue.x == 1, ""); + position.x += position.width; + bool b2 = GUI.Toggle(position, prop.vectorValue.y == 1, ""); + position.x += position.width; + bool b3 = GUI.Toggle(position, prop.vectorValue.z == 1, ""); + position.x += position.width; + bool b4 = GUI.Toggle(position, prop.vectorValue.w == 1, ""); + if (EditorGUI.EndChangeCheck()) + { + prop.vectorValue = new Vector4(b1 ? 1 : 0, b2 ? 1 : 0, b3 ? 1 : 0, b4 ? 1 : 0); + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs.meta new file mode 100644 index 00000000..f773876e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/Vector4Toggles.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 7b70f33fb05855c4888ab7d73f80e34a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs new file mode 100644 index 00000000..b0dbace6 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class VectorLabelDrawer : MaterialPropertyDrawer + { + string[] _labelStrings = new string[4] { "X", "Y", "Z", "W" }; + int vectorChannels = 0; + + public VectorLabelDrawer(string labelX, string labelY) + { + _labelStrings[0] = labelX; + _labelStrings[1] = labelY; + vectorChannels = 2; + } + + public VectorLabelDrawer(string labelX, string labelY, string labelZ) + { + _labelStrings[0] = labelX; + _labelStrings[1] = labelY; + _labelStrings[2] = labelZ; + vectorChannels = 3; + } + + public VectorLabelDrawer(string labelX, string labelY, string labelZ, string labelW) + { + _labelStrings[0] = labelX; + _labelStrings[1] = labelY; + _labelStrings[2] = labelZ; + _labelStrings[3] = labelW; + vectorChannels = 4; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + EditorGUI.BeginChangeCheck(); + EditorGUI.showMixedValue = prop.hasMixedValue; + + Rect labelR = new Rect(position.x, position.y, position.width * 0.41f, position.height); + Rect contentR = new Rect(position.x + labelR.width, position.y, position.width - labelR.width, position.height); + + float[] values = new float[vectorChannels]; + GUIContent[] labels = new GUIContent[vectorChannels]; + + for (int i = 0; i < vectorChannels; i++) + { + values[i] = prop.vectorValue[i]; + labels[i] = new GUIContent(_labelStrings[i]); + } + + EditorGUI.LabelField(labelR, label); + EditorGUI.MultiFloatField(contentR, labels, values); + + if (EditorGUI.EndChangeCheck()) + { + switch (vectorChannels) + { + case 2: + prop.vectorValue = new Vector4(values[0], values[1], prop.vectorValue.z, prop.vectorValue.w); + break; + case 3: + prop.vectorValue = new Vector4(values[0], values[1], values[2], prop.vectorValue.w); + break; + case 4: + prop.vectorValue = new Vector4(values[0], values[1], values[2], values[3]); + break; + default: + break; + } + } + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs.meta new file mode 100644 index 00000000..7fe5bb7e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorLabel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d59ceb95f1ec49e4dbd2bd133f1bd25d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs new file mode 100644 index 00000000..db6c978a --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs @@ -0,0 +1,149 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using UnityEditor; +using UnityEngine; +using static Thry.GradientEditor; +using static Thry.TexturePacker; + +namespace Thry +{ + public class VectorToSlidersDrawer : MaterialPropertyDrawer + { + class SliderConfig + { + public string Label; + public float Min; + public float Max; + + public SliderConfig(string l, string min, string max) + { + Label = l; + Min = Parse(min); + Max = Parse(max); + } + + public SliderConfig(string l, float min, float max) + { + Label = l; + Min = min; + Max = max; + } + + private float Parse(string s) + { + if (s.StartsWith("n", StringComparison.Ordinal)) + return -float.Parse(s.Substring(1), System.Globalization.CultureInfo.InvariantCulture); + return float.Parse(s.Substring(1), System.Globalization.CultureInfo.InvariantCulture); + } + } + + SliderConfig _slider1; + SliderConfig _slider2; + SliderConfig _slider3; + SliderConfig _slider4; + bool _twoMinMaxDrawers; + + VectorToSlidersDrawer(SliderConfig slider1, SliderConfig slider2, SliderConfig slider3, SliderConfig slider4, float twoMinMaxDrawers) + { + _slider1 = slider1; + _slider2 = slider2; + _slider3 = slider3; + _slider4 = slider4; + _twoMinMaxDrawers = twoMinMaxDrawers == 1; + } + + public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2, string label3, string min3, string max3, string label4, string min4, string max4) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), new SliderConfig(label4, min4, max4), 0) + { } + public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2, string label3, string min3, string max3) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), null, 0) + { } + public VectorToSlidersDrawer(string label1, string min1, string max1, string label2, string min2, string max2) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, 0) + { } + public VectorToSlidersDrawer(float twoMinMaxDrawers, string label1, string min1, string max1, string label2, string min2, string max2) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, twoMinMaxDrawers) + { } + + public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2, string label3, float min3, float max3, string label4, float min4, float max4) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), new SliderConfig(label4, min4, max4), 0) + { } + public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2, string label3, float min3, float max3) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), new SliderConfig(label3, min3, max3), null, 0) + { } + public VectorToSlidersDrawer(string label1, float min1, float max1, string label2, float min2, float max2) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, 0) + { } + public VectorToSlidersDrawer(float twoMinMaxDrawers, string label1, float min1, float max1, string label2, float min2, float max2) : + this(new SliderConfig(label1, min1, max1), new SliderConfig(label2, min2, max2), null, null, twoMinMaxDrawers) + { } + + private float GetIconHeight() + { + return GUILayoutUtility.GetLastRect().y + GUILayoutUtility.GetLastRect().height - 14; + } + + public override void OnGUI(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor) + { + Vector4 vector = prop.vectorValue; + + Rect fullRect = EditorGUILayout.BeginVertical(); + DrawingData.IconsPositioningCount = 2; + + EditorGUI.BeginChangeCheck(); + if (_twoMinMaxDrawers) + { + float min1 = vector.x; + float max1 = vector.y; + float min2 = vector.z; + float max2 = vector.w; + EditorGUI.showMixedValue = prop.hasMixedValue; + EditorGUILayout.MinMaxSlider(_slider1.Label, ref min1, ref max1, _slider1.Min, _slider1.Max); + DrawingData.IconsPositioningHeights[0] = GetIconHeight(); + EditorGUI.showMixedValue = prop.hasMixedValue; + EditorGUILayout.MinMaxSlider(_slider2.Label, ref min2, ref max2, _slider2.Min, _slider2.Max); + DrawingData.IconsPositioningHeights[1] = GetIconHeight(); + vector = new Vector4(min1, max1, min2, max2); + } + else + { + EditorGUI.showMixedValue = prop.hasMixedValue; + vector.x = EditorGUILayout.Slider(_slider1.Label, vector.x, _slider1.Min, _slider1.Max); + DrawingData.IconsPositioningHeights[0] = GetIconHeight(); + EditorGUI.showMixedValue = prop.hasMixedValue; + vector.y = EditorGUILayout.Slider(_slider2.Label, vector.y, _slider2.Min, _slider2.Max); + DrawingData.IconsPositioningHeights[1] = GetIconHeight(); + if (_slider3 != null) + { + EditorGUI.showMixedValue = prop.hasMixedValue; + vector.z = EditorGUILayout.Slider(_slider3.Label, vector.z, _slider3.Min, _slider3.Max); + DrawingData.IconsPositioningHeights[2] = GetIconHeight(); + + DrawingData.IconsPositioningCount = 3; + } + if (_slider4 != null) + { + EditorGUI.showMixedValue = prop.hasMixedValue; + vector.w = EditorGUILayout.Slider(_slider4.Label, vector.w, _slider4.Min, _slider4.Max); + DrawingData.IconsPositioningHeights[3] = GetIconHeight(); + + DrawingData.IconsPositioningCount = 4; + } + } + if (EditorGUI.EndChangeCheck()) + prop.vectorValue = vector; + + EditorGUILayout.EndVertical(); + DrawingData.TooltipCheckRect = fullRect; + } + + public override float GetPropertyHeight(MaterialProperty prop, string label, MaterialEditor editor) + { + DrawingData.LastPropertyUsedCustomDrawer = true; + return base.GetPropertyHeight(prop, label, editor) - EditorGUIUtility.singleLineHeight; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs.meta new file mode 100644 index 00000000..047a8a48 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Drawers/VectorToSliders.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bda8f8534c478fe41a0f5ac48b16e63a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs deleted file mode 100644 index d14163fd..00000000 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.cs +++ /dev/null @@ -1,1881 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Thry.ThryEditor; -using UnityEditor; -using UnityEngine; - -namespace Thry -{ - public class CRect - { - public Rect r; - public CRect(Rect r) - { - this.r = r; - } - } - - public class InputEvent - { - public bool HadMouseDownRepaint; - public bool HadMouseDown; - int _button; - bool _MouseClick; - bool _MouseLeftClickIgnoreLocked; - bool _MouseRightClickIgnoreLocked; - bool _MouseLeftClick; - bool _MouseRightClick; - - public bool is_alt_down; - - public bool is_drag_drop_event; - public bool is_drop_event; - - public Vector2 mouse_position; - public Vector2 screen_mouse_position; - - public EventType OriginalEventType; - - public void Update(bool isLockedMaterial) - { - Event e = Event.current; - _button = e.button; - _MouseClick = e.type == EventType.MouseDown && !isLockedMaterial; - _MouseLeftClick = _MouseClick && _button == 0; - _MouseRightClick = _MouseClick && _button == 1; - _MouseLeftClickIgnoreLocked = e.type == EventType.MouseDown && _button == 0; - _MouseRightClickIgnoreLocked = e.type == EventType.MouseDown && _button == 1; - if (_MouseClick) HadMouseDown = _MouseClick; - if (HadMouseDown && e.type == EventType.Repaint) - { - HadMouseDownRepaint = true; - HadMouseDown = false; - } - is_alt_down = e.alt; - mouse_position = e.mousePosition; - screen_mouse_position = GUIUtility.GUIToScreenPoint(e.mousePosition); - is_drop_event = e.type == EventType.DragPerform; - is_drag_drop_event = is_drop_event || e.type == EventType.DragUpdated; - OriginalEventType = e.type; - } - - public void Use() - { - _MouseClick = false; - _MouseLeftClick = false; - _MouseRightClick = false; - Event.current.Use(); - } - - // This is cursed. I need to look over this whole system at some point - public void PowerUse() - { - Use(); - _MouseRightClickIgnoreLocked = false; - _MouseLeftClickIgnoreLocked = false; - } - - public bool LeftClick_IgnoreLocked - { - get { return _MouseLeftClickIgnoreLocked && Event.current.type != EventType.Used; } - } - - public bool RightClick_IgnoreLocked - { - get { return _MouseRightClickIgnoreLocked && Event.current.type != EventType.Used; } - } - - public bool LeftClick_IgnoreLockedAndUnityUses - { - get { return _MouseLeftClickIgnoreLocked; } - } - - public bool RightClick_IgnoreLockedAndUnityUses - { - get { return _MouseRightClickIgnoreLocked; } - } - - public bool Click - { - get { return _MouseClick && Event.current.type != EventType.Used; } - } - } - - public abstract class ShaderPart - { - public ShaderEditor ActiveShaderEditor; - - public int XOffset = 0; - public GUIContent Content; - public MaterialProperty MaterialProperty; - public string PropertyIdentifier; - public System.Object PropertyData = null; - public bool DoReferencePropertiesExist = false; - public bool DoesReferencePropertyExist = false; - public bool IsHidden = false; - public bool IsAnimatable = true; - public bool IsPreset = false; - public bool ExemptFromLockedDisabling = false; - public bool IsAnimated = false; - public bool IsRenaming = false; - public string CustomStringTagID = null; - protected int ShaderPropertyId = -1; - protected int ShaderPropertyIndex = -1; - - public BetterTooltips.Tooltip tooltip; - - public bool has_not_searchedFor = false; //used for property search - - protected string _optionsRaw; - private PropertyOptions _options; - private bool _doOptionsNeedInitilization = true; - public PropertyOptions Options - { - get - { - if (_options == null) - { - _options = PropertyOptions.Deserialize(_optionsRaw); - } - return _options; - } - } - - GenericMenu contextMenu; - - public ShaderPart(string propertyIdentifier, int xOffset, string displayName, string tooltip, ShaderEditor shaderEditor) - { - this._optionsRaw = null; - this.ActiveShaderEditor = shaderEditor; - this.PropertyIdentifier = propertyIdentifier; - this.XOffset = xOffset; - this.Content = new GUIContent(displayName); - this.tooltip = new BetterTooltips.Tooltip(tooltip); - this.IsPreset = shaderEditor.IsPresetEditor && Presets.IsPreset(shaderEditor.Materials[0], this); - } - - public ShaderPart(ShaderEditor shaderEditor, MaterialProperty prop, int xOffset, string displayName, string optionsRaw, int propertyIndex) - { - this._optionsRaw = optionsRaw; - this.ActiveShaderEditor = shaderEditor; - this.MaterialProperty = prop; - this.XOffset = xOffset; - this.Content = new GUIContent(displayName); - this.IsPreset = shaderEditor.IsPresetEditor && Presets.IsPreset(shaderEditor.Materials[0], this); - - if (MaterialProperty == null) - return; - - this.ShaderPropertyId = Shader.PropertyToID(MaterialProperty.name); - this.ShaderPropertyIndex = propertyIndex; - - // Do parse options & check for alternative names if shader swap - if(ShaderEditor.Active.DidSwapToNewShader) - { - if(Options.alts != null && Options.alts.Length > 0) - CopyAlternativeUpgradeValues(); - } - - this.ExemptFromLockedDisabling |= ShaderOptimizer.IsPropertyExcemptFromLocking(prop); - } - - private void CopyAlternativeUpgradeValues() - { - MaterialProperty.PropType type = this.MaterialProperty.type; - if(type == MaterialProperty.PropType.Color) type = MaterialProperty.PropType.Vector; - if(type == MaterialProperty.PropType.Range) type = MaterialProperty.PropType.Float; - - int index = ShaderEditor.Active.Shader.FindPropertyIndex(this.MaterialProperty.name); - - object defaultValue = null; - if (type == MaterialProperty.PropType.Float) - defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultFloatValue(index); -#if UNITY_2022_1_OR_NEWER - else if(type == MaterialProperty.PropType.Int) - defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultIntValue(index); -#endif - else if (type == MaterialProperty.PropType.Vector) - defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultVectorValue(index); - else if (type == MaterialProperty.PropType.Texture) - defaultValue = ShaderEditor.Active.Shader.GetPropertyTextureDefaultName(index); - - foreach(Material m in ShaderEditor.Active.Materials) - { - // Check if is not default value - if (type == MaterialProperty.PropType.Float) - { - if (m.GetNumber(this.MaterialProperty) != (float)defaultValue) - continue; - } -#if UNITY_2022_1_OR_NEWER - else if (type == MaterialProperty.PropType.Int) - { - if (m.GetInt(this.MaterialProperty.name) != (int)defaultValue) - continue; - } -#endif - else if (type == MaterialProperty.PropType.Vector) - { - if (m.GetVector(this.MaterialProperty.name) != (Vector4)defaultValue) - continue; - } - else if (type == MaterialProperty.PropType.Texture) - { - if (m.GetTexture(this.MaterialProperty.name) != null && - m.GetTexture(this.MaterialProperty.name).name != (string)defaultValue) - continue; - } - - // Material as serializedObject - SerializedObject serializedObject = new SerializedObject(m); - foreach (string alt in Options.alts) - { - SerializedProperty arrayProp = null; - if(type == MaterialProperty.PropType.Float) - arrayProp = serializedObject.FindProperty("m_SavedProperties.m_Floats.Array"); -#if UNITY_2022_1_OR_NEWER - else if(type == MaterialProperty.PropType.Int) - arrayProp = serializedObject.FindProperty("m_SavedProperties.m_Ints.Array"); -#endif - else if(type == MaterialProperty.PropType.Vector) - arrayProp = serializedObject.FindProperty($"m_SavedProperties.m_Colors.Array"); - else if(type == MaterialProperty.PropType.Texture) - arrayProp = serializedObject.FindProperty($"m_SavedProperties.m_TexEnvs.Array"); - - if(arrayProp == null) - continue; - - // Iterate through properties in prop array, find where .first is alt - SerializedProperty valueProp = null; - for (int i = 0; i < arrayProp.arraySize; i++) - { - SerializedProperty keyProp = arrayProp.GetArrayElementAtIndex(i); - if (keyProp.FindPropertyRelative("first").stringValue == alt) - { - valueProp = keyProp.FindPropertyRelative("second"); - break; - } - } - - if (valueProp == null) - continue; - - if (type == MaterialProperty.PropType.Float) - this.MaterialProperty.floatValue = valueProp.floatValue; -#if UNITY_2022_1_OR_NEWER - else if(type == MaterialProperty.PropType.Int) - this.MaterialProperty.intValue = valueProp.intValue; -#endif - else if (type == MaterialProperty.PropType.Vector) - this.MaterialProperty.colorValue = valueProp.colorValue; - else if (type == MaterialProperty.PropType.Texture) - { - var texProperty = valueProp.FindPropertyRelative("m_Texture").objectReferenceValue as Texture; - var scaleProperty = valueProp.FindPropertyRelative("m_Scale").vector2Value; - var offsetProperty = valueProp.FindPropertyRelative("m_Offset").vector2Value; - - this.MaterialProperty.textureValue = texProperty; - this.MaterialProperty.textureScaleAndOffset = new Vector4(scaleProperty.x, scaleProperty.y, offsetProperty.x, offsetProperty.y); - } - } - } - } - - protected virtual void InitOptions() - { - this.tooltip = new BetterTooltips.Tooltip(Options.tooltip); - this.DoReferencePropertiesExist = Options.reference_properties != null && Options.reference_properties.Length > 0; - this.DoesReferencePropertyExist = Options.reference_property != null; - this.XOffset += Options.offset; - } - - public void SetReferenceProperty(string s) - { - Options.reference_property = s; - this.DoesReferencePropertyExist = Options.reference_property != null; - } - - public void SetReferenceProperties(string[] properties) - { - Options.reference_properties = properties; - this.DoReferencePropertiesExist = Options.reference_properties != null && Options.reference_properties.Length > 0; - } - - public void SetTooltip(string tooltip) - { - this.tooltip.SetText(tooltip); - } - - public abstract void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false); - public abstract void CopyFromMaterial(Material m, bool isTopCall = false); - public abstract void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null); - - protected void CopyReferencePropertiesToMaterial(Material target) - { - if (Options.reference_properties != null) - foreach (string r_property in Options.reference_properties) - { - ShaderProperty property = ActiveShaderEditor.PropertyDictionary[r_property]; - MaterialHelper.CopyPropertyValueToMaterial(property.MaterialProperty, target); - } - if (string.IsNullOrWhiteSpace(Options.reference_property) == false) - { - ShaderProperty property = ActiveShaderEditor.PropertyDictionary[Options.reference_property]; - MaterialHelper.CopyPropertyValueToMaterial(property.MaterialProperty, target); - } - } - - protected void CopyReferencePropertiesFromMaterial(Material source) - { - if (Options.reference_properties != null) - foreach (string r_property in Options.reference_properties) - { - ShaderProperty property = ActiveShaderEditor.PropertyDictionary[r_property]; - MaterialHelper.CopyPropertyValueFromMaterial(property.MaterialProperty, source); - } - if (string.IsNullOrWhiteSpace(Options.reference_property) == false) - { - ShaderProperty property = ActiveShaderEditor.PropertyDictionary[Options.reference_property]; - MaterialHelper.CopyPropertyValueFromMaterial(property.MaterialProperty, source); - } - } - - public abstract void TransferFromMaterialAndGroup(Material m, ShaderPart g, bool isTopCall = false, MaterialProperty.PropType[] propertyTypesToSkip = null); - - bool hasAddedDisabledGroup = false; - public void Draw(CRect rect = null, GUIContent content = null, bool useEditorIndent = false, bool isInHeader = false) - { - if(_doOptionsNeedInitilization) - { - InitOptions(); - _doOptionsNeedInitilization = false; - } - - if (has_not_searchedFor) - return; - if (DrawingData.IsEnabled && Options.condition_enable != null) - { - hasAddedDisabledGroup = !Options.condition_enable.Test(); - } - if(hasAddedDisabledGroup) - { - DrawingData.IsEnabled = !hasAddedDisabledGroup; - EditorGUI.BeginDisabledGroup(true); - } - - if (Options.condition_show.Test()) - { - PerformDraw(content, rect, useEditorIndent, isInHeader); - } - if (hasAddedDisabledGroup) - { - hasAddedDisabledGroup = false; - DrawingData.IsEnabled = true; - EditorGUI.EndDisabledGroup(); - } - } - - public virtual void HandleRightClickToggles(bool isInHeader) - { - if (this is ShaderGroup) return; - if (DrawingData.TooltipCheckRect.y < 25) return; // Happens in Layout event, with some dynamic properties - if (ShaderEditor.Input.RightClick_IgnoreLockedAndUnityUses && ShaderEditor.Input.OriginalEventType != EventType.Layout && DrawingData.TooltipCheckRect.Contains(Event.current.mousePosition)) - { - Event.current.Use(); - //Context menu - //Show context menu, if not open. - //If locked material only show menu for animated materials. Only show data retieving options in locked state - if (!ShaderEditor.Active.IsLockedMaterial || IsAnimated) { - contextMenu = new GenericMenu(); - if (IsAnimatable && !ShaderEditor.Active.IsLockedMaterial) - { - contextMenu.AddItem(new GUIContent("Animated (when locked)"), IsAnimated, () => { SetAnimated(!IsAnimated, false); }); - contextMenu.AddItem(new GUIContent("Renamed (when locked)"), IsAnimated && IsRenaming, () => { SetAnimated(true, !IsRenaming); }); - contextMenu.AddItem(new GUIContent("Locking Explanation"), false, () => { Application.OpenURL("https://www.youtube.com/watch?v=asWeDJb5LAo&ab_channel=poiyomi"); }); - contextMenu.AddSeparator(""); - } - if (ShaderEditor.Active.IsPresetEditor ) - { - contextMenu.AddItem(new GUIContent("Is part of preset"), IsPreset, ToggleIsPreset); - contextMenu.AddSeparator(""); - } - contextMenu.AddItem(new GUIContent("Copy Property Name"), false, () => { EditorGUIUtility.systemCopyBuffer = MaterialProperty.name; }); - contextMenu.AddItem(new GUIContent("Copy Animated Property Name"), false, () => { EditorGUIUtility.systemCopyBuffer = GetAnimatedPropertyName(); }); - contextMenu.AddItem(new GUIContent("Copy Animated Property Path"), false, CopyPropertyPath ); - contextMenu.AddItem(new GUIContent("Copy Property as Keyframe"), false, CopyPropertyAsKeyframe); -#if UNITY_2022_1_OR_NEWER - bool isLockedInChildren = false; - bool isLockedByAncestor = false; - bool isOverriden = true; - foreach (Material target in ShaderEditor.Active.Materials) - { - if(target == null) continue; - int nameId = Shader.PropertyToID(MaterialProperty.name); - isLockedInChildren |= target.IsPropertyLocked(nameId); - isLockedByAncestor |= target.IsPropertyLockedByAncestor(nameId); - isOverriden &= target.IsPropertyOverriden(nameId); - } - DoVariantMenuStuff(contextMenu, isOverriden, isLockedByAncestor, isLockedInChildren, ShaderEditor.Active.Materials, true); -#endif - contextMenu.ShowAsContext(); - } - } - } - -#if UNITY_2022_1_OR_NEWER - // static Type s_PropertyData = typeof(MaterialProperty).GetNestedType("PropertyData", BindingFlags.NonPublic); - // static MethodInfo s_HandleApplyRevert = s_PropertyData.GetMethod("HandleApplyRevert", BindingFlags.NonPublic | BindingFlags.Static); - - void DoVariantMenuStuff(GenericMenu menu, bool overriden, bool lockedByAncestor, bool isLockedInChildren, Material[] targets, bool allowLocking) - { - if (lockedByAncestor) - { - if (targets.Length != 1) - return; - - contextMenu.AddSeparator(""); - menu.AddItem(Styles.lockOriginContent, false, () => GotoLockOriginAction(targets)); - } - else if (GUI.enabled) - { - DoRegularMenu(menu, overriden, targets); - DoLockPropertiesMenu(contextMenu, !isLockedInChildren, ShaderEditor.Active.Materials, true); - } - } - - void DoRegularMenu(GenericMenu menu, bool isOverriden, Material[] targets) - { - var singleEditing = targets.Length == 1; - - if (isOverriden) - { - contextMenu.AddSeparator(""); - HandleApplyRevert(menu, singleEditing, targets); - } - - DisplayMode displayMode = GetDisplayMode(targets); - if (displayMode == DisplayMode.Material) - { - menu.AddSeparator(""); - menu.AddItem(Styles.resetContent, false, ResetMaterialProperties); - } - else if (displayMode == DisplayMode.Variant) - HandleRevertAll(menu, singleEditing, targets); - } - - enum DisplayMode { Material, Variant, Mixed }; - static DisplayMode GetDisplayMode(Material[] targets) - { - int variantCount = GetVariantCount(targets); - if (variantCount == 0) - return DisplayMode.Material; - if (variantCount == targets.Length) - return DisplayMode.Variant; - return DisplayMode.Mixed; - } - - static int GetVariantCount(Material[] targets) - { - int count = 0; - foreach (Material target in targets) - count += target.isVariant ? 1 : 0; - return count; - } - - void DoLockPropertiesMenu(GenericMenu menu, bool lockValue, Material[] targets, bool allowLocking) - { - if (menu.GetItemCount() != 0) - menu.AddSeparator(""); - - if (allowLocking) - { - menu.AddItem(Styles.lockContent, !lockValue, () => { SetLockedProperty(targets, lockValue); }); - } - else - { - menu.AddDisabledItem(Styles.lockContent); - } - } - - void SetLockedProperty(Material[] targets, bool value) - { - foreach (Material target in targets) - { - target.SetPropertyLock(ShaderPropertyId, value); - } - } - - void GotoLockOriginAction(Material[] targets) - { - Material origin = targets[0] as Material; - while (origin = origin.parent) - { - if(origin.IsPropertyLocked(ShaderPropertyId)) - break; - } - - if (origin) - { - EditorGUIUtility.PingObject(origin); - } - } - - void HandleApplyRevert(GenericMenu menu, bool singleEditing, Material[] targets) - { - // Apply - if (singleEditing) - { - Material source = (Material)targets[0]; - Material destination = (Material)targets[0]; - while (destination = destination.parent as Material) - { - if (AssetDatabase.IsForeignAsset(destination)) - continue; - - var text = destination.isVariant ? Styles.applyToVariantText : Styles.applyToMaterialText; - var applyContent = new GUIContent(string.Format(text, destination.name)); - - menu.AddItem(applyContent, false, (object dest) => { - source.ApplyPropertyOverride((Material)dest, ShaderPropertyId); - }, destination); - } - } - - // Revert - var content = singleEditing ? Styles.revertContent : - new GUIContent(string.Format(Styles.revertMultiText, targets.Length)); - menu.AddItem(content, false, () => { - string displayName = MaterialProperty.displayName; - string targetName = singleEditing ? targets[0].name : targets.Length + " Materials"; - Undo.RecordObjects(targets, "Revert " + displayName + " of " + targetName); - - foreach (Material target in targets) - { - target.RevertPropertyOverride(ShaderPropertyId); - } - }); - } - - void HandleRevertAll(GenericMenu menu, bool singleEditing, Material[] targets) - { - foreach (Material target in targets) - { - if (target.isVariant) - { - menu.AddSeparator(""); - - menu.AddItem(Styles.revertAllContent, false, () => { - string targetName = singleEditing ? targets[0].name : targets.Length + " Materials"; - Undo.RecordObjects(targets, "Revert all overrides of " + targetName); - - foreach (Material target in targets) - target.RevertAllPropertyOverrides(); - }); - break; - } - } - } - - void ResetMaterialProperties() - { - MaterialProperty prop = MaterialProperty; - Shader shader = ShaderEditor.Active.Shader; - switch (prop.type) - { - case MaterialProperty.PropType.Float: - case MaterialProperty.PropType.Range: - prop.floatValue = shader.GetPropertyDefaultFloatValue(ShaderPropertyIndex); - break; - case MaterialProperty.PropType.Vector: - prop.vectorValue = shader.GetPropertyDefaultVectorValue(ShaderPropertyIndex); - break; - case MaterialProperty.PropType.Color: - prop.colorValue = shader.GetPropertyDefaultVectorValue(ShaderPropertyIndex); - break; - case MaterialProperty.PropType.Int: - prop.intValue = shader.GetPropertyDefaultIntValue(ShaderPropertyIndex); - break; - case MaterialProperty.PropType.Texture: - Texture texture = null; - var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(shader)) as ShaderImporter; - if (importer != null) - texture = importer.GetDefaultTexture(prop.name); - prop.textureValue = texture; - prop.textureScaleAndOffset = new Vector4(1, 1, 0, 0); - break; - } - } -#endif - - void ToggleIsPreset() - { - IsPreset = !IsPreset; - if(MaterialProperty != null) Presets.SetProperty(ActiveShaderEditor.Materials[0], this, IsPreset); - ShaderEditor.RepaintActive(); - } - - void CopyPropertyPath() - { - string path = GetAnimatedPropertyName(); - Transform selected = Selection.activeTransform; - Transform root = selected; - while(root != null && root.GetComponent() == null) - root = root.parent; - if (selected != null && root != null && selected != root) - path = AnimationUtility.CalculateTransformPath(selected, root) + "/" + path; - EditorGUIUtility.systemCopyBuffer = path; - } - - string GetAnimatedPropertyName() - { - string propName = MaterialProperty.name; - if (IsRenaming && !ShaderEditor.Active.IsLockedMaterial) propName = propName + "_" + ShaderEditor.Active.RenamedPropertySuffix; - if (MaterialProperty.type == MaterialProperty.PropType.Texture) propName = propName + "_ST"; - return propName; - } - - void CopyPropertyAsKeyframe() - { - string path = ""; - Transform selected = Selection.activeTransform; - Transform root = selected; - while (root != null && root.GetComponent() == null) - root = root.parent; - if (selected != null && root != null && selected != root) - path = AnimationUtility.CalculateTransformPath(selected, root); - if(selected == null && root == null) - return; - - Type rendererType = typeof(Renderer); - if (selected.GetComponent()) rendererType = typeof(SkinnedMeshRenderer); - if (selected.GetComponent()) rendererType = typeof(MeshRenderer); - - Type animationStateType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowState"); - Type animationKeyframeType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowKeyframe"); - Type animationCurveType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowCurve"); - - FieldInfo clipboardField = animationStateType.GetField("s_KeyframeClipboard", BindingFlags.NonPublic | BindingFlags.Static); - - Type keyframeListType = typeof(List<>).MakeGenericType(animationKeyframeType); - IList keyframeList = (IList)Activator.CreateInstance(keyframeListType); - - AnimationClip clip = new AnimationClip(); - - string propertyname = "material." + GetAnimatedPropertyName(); - if (MaterialProperty.type == MaterialProperty.PropType.Float || MaterialProperty.type == MaterialProperty.PropType.Range) - { - clip.SetCurve(path, rendererType, propertyname, new AnimationCurve(new Keyframe(0, MaterialProperty.floatValue))); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, "", rendererType)); - } -#if UNITY_2022_1_OR_NEWER - else if(MaterialProperty.type == MaterialProperty.PropType.Int) - { - clip.SetCurve(path, rendererType, propertyname, new AnimationCurve(new Keyframe(0, MaterialProperty.intValue))); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, "", rendererType)); - } -#endif - else if(MaterialProperty.type == MaterialProperty.PropType.Color) - { - clip.SetCurve(path, rendererType, propertyname + ".r", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.r))); - clip.SetCurve(path, rendererType, propertyname + ".g", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.g))); - clip.SetCurve(path, rendererType, propertyname + ".b", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.b))); - clip.SetCurve(path, rendererType, propertyname + ".a", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.a))); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".r", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".g", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".b", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".a", rendererType)); - }else if(MaterialProperty.type == MaterialProperty.PropType.Vector) - { - clip.SetCurve(path, rendererType, propertyname + ".x", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.x))); - clip.SetCurve(path, rendererType, propertyname + ".y", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.y))); - clip.SetCurve(path, rendererType, propertyname + ".z", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.z))); - clip.SetCurve(path, rendererType, propertyname + ".w", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.w))); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".x", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".y", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".z", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".w", rendererType)); - }else if(MaterialProperty.type == MaterialProperty.PropType.Texture) - { - clip.SetCurve(path, rendererType, propertyname + ".x", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.x))); - clip.SetCurve(path, rendererType, propertyname + ".y", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.y))); - clip.SetCurve(path, rendererType, propertyname + ".z", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.z))); - clip.SetCurve(path, rendererType, propertyname + ".w", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.w))); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".x", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".y", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".z", rendererType)); - keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".w", rendererType)); - } - clipboardField.SetValue(null, keyframeList); - } - - object ClipToKeyFrame(Type animationCurveType, AnimationClip clip, string path, string propertyPostFix, Type rendererType) - { - FieldInfo curvesField = animationCurveType.GetField("m_Keyframes", BindingFlags.Instance | BindingFlags.Public); - - object windowCurve = Activator.CreateInstance(animationCurveType, clip, - EditorCurveBinding.FloatCurve(path, rendererType, "material." + GetAnimatedPropertyName() + propertyPostFix), typeof(float)); - IEnumerator enumerator = (curvesField.GetValue(windowCurve) as IList).GetEnumerator(); - enumerator.MoveNext(); - return enumerator.Current; - } - - public void SetAnimated(bool animated, bool renamed) - { - if (IsAnimated == animated && IsRenaming == renamed) return; - IsAnimated = animated; - IsRenaming = renamed; - ShaderOptimizer.SetAnimatedTag(MaterialProperty, IsAnimated ? (IsRenaming ? "2" : "1") : ""); - } - - private void PerformDraw(GUIContent content, CRect rect, bool useEditorIndent, bool isInHeader = false) - { - if (content == null) - content = this.Content; - EditorGUI.BeginChangeCheck(); - DrawInternal(content, rect, useEditorIndent, isInHeader); - - if(this is TextureProperty == false) - { - DrawingData.TooltipCheckRect = DrawingData.LastGuiObjectRect; - DrawingData.IconsPositioningHeight = DrawingData.LastGuiObjectRect.y + DrawingData.LastGuiObjectRect.height - 14; - } - DrawingData.TooltipCheckRect.width = EditorGUIUtility.labelWidth; - - HandleRightClickToggles(isInHeader); - - if (EditorGUI.EndChangeCheck()) - { - OnPropertyValueChanged(); - ExecuteOnValueActions(ShaderEditor.Active.Materials); - //Check if property is being animated - if (this is ShaderProperty && ActiveShaderEditor.ActiveRenderer != null && ActiveShaderEditor.IsInAnimationMode && IsAnimatable && !IsAnimated) - { - if (MaterialProperty.type == MaterialProperty.PropType.Texture ? - AnimationMode.IsPropertyAnimated(ActiveShaderEditor.ActiveRenderer, "material." + MaterialProperty.name + "_ST.x" ) : - AnimationMode.IsPropertyAnimated(ActiveShaderEditor.ActiveRenderer, "material." + MaterialProperty.name)) - SetAnimated(true, false); - } - } - - if (IsAnimatable && IsAnimated) DrawLockedAnimated(); - if (IsPreset) DrawPresetProperty(); - - tooltip.ConditionalDraw(DrawingData.TooltipCheckRect); - - //Click testing - if(Event.current.type == EventType.MouseDown && DrawingData.LastGuiObjectRect.Contains(ShaderEditor.Input.mouse_position)) - { - if ((ShaderEditor.Input.is_alt_down && Options.altClick != null)) Options.altClick.Perform(ShaderEditor.Active.Materials); - else if (Options.onClick != null) Options.onClick.Perform(ShaderEditor.Active.Materials); - } - } - - protected virtual void OnPropertyValueChanged() - { - - } - - private void DrawLockedAnimated() - { - Rect r = new Rect(14, DrawingData.IconsPositioningHeight, 16, 16); - //GUI.DrawTexture(r, is_renaming ? Styles.texture_animated_renamed : Styles.texture_animated, ScaleMode.StretchToFill, true); - if (IsRenaming) GUI.Label(r, "RA", Styles.animatedIndicatorStyle); - else GUI.Label(r, "A", Styles.animatedIndicatorStyle); - } - - private void DrawPresetProperty() - { - Rect r = new Rect(3, DrawingData.IconsPositioningHeight, 8, 16); - //GUI.DrawTexture(r, Styles.texture_preset, ScaleMode.StretchToFill, true); - GUI.Label(r, "P", Styles.presetIndicatorStyle); - } - - protected void ExecuteOnValueActions(Material[] targets) - { - if (Options.on_value_actions != null) - foreach (PropertyValueAction action in Options.on_value_actions) - { - action.Execute(MaterialProperty, targets); - } - } - - public abstract void FindUnusedTextures(List unusedList, bool isEnabled); - - protected bool ShouldSkipProperty(MaterialProperty property, MaterialProperty.PropType[] propertyTypesToSkip) - { - if(propertyTypesToSkip != null) - foreach(MaterialProperty.PropType typeToSkip in propertyTypesToSkip) - if(property.type == typeToSkip) - return true; - return false; - } - } - - public class ShaderGroup : ShaderPart - { - public List parts = new List(); - protected bool _isExpanded; - - public ShaderGroup(ShaderEditor shaderEditor) : base(null, 0, "", null, shaderEditor) - { - - } - - public ShaderGroup(ShaderEditor shaderEditor, string optionsRaw) : base(null, 0, "", null, shaderEditor) - { - this._optionsRaw = optionsRaw; - } - - public ShaderGroup(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, xOffset, displayName, optionsRaw, propertyIndex) - { - - } - - protected override void InitOptions() - { - base.InitOptions(); - if(Options.persistent_expand) _isExpanded = this.MaterialProperty.GetNumber() == 1; - else _isExpanded = Options.default_expand; - } - - protected bool IsExpanded - { - get - { - return _isExpanded; - } - set - { - if(Options.persistent_expand) - { - if (AnimationMode.InAnimationMode()) - { - // This fails when unselecting the object in hirearchy - // Then reselecting it - // Don't know why - // It seems AnimationMode is not working properly in Unity 2022 - // It worked fine in Unity 2019 - - // AnimationMode.StopAnimationMode(); - // this.MaterialProperty.SetNumber(value ? 1 : 0); - // AnimationMode.StartAnimationMode(); - - // So we do this instead - _isExpanded = value; - }else - { - this.MaterialProperty.SetNumber(value ? 1 : 0); - } - } - _isExpanded = value; - } - } - - protected bool DoDisableChildren - { - get - { - return Options.condition_enable_children != null && !Options.condition_enable_children.Test(); - } - } - - public void addPart(ShaderPart part) - { - parts.Add(part); - } - - public override void CopyFromMaterial(Material m, bool isTopCall = false) - { - if (Options.reference_property != null) - ActiveShaderEditor.PropertyDictionary[Options.reference_property].CopyFromMaterial(m); - foreach (ShaderPart p in parts) - p.CopyFromMaterial(m); - if (isTopCall) ActiveShaderEditor.ApplyDrawers(); - } - - public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - if (ShouldSkipProperty(MaterialProperty, skipPropertyTypes)) return; - - if (Options.reference_property != null) - ActiveShaderEditor.PropertyDictionary[Options.reference_property].CopyToMaterial(m); - foreach(ShaderPart p in parts) - { - if(!ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) - p.CopyToMaterial(m); - } - if (isTopCall) MaterialEditor.ApplyMaterialPropertyDrawers(m); - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - if(Options.margin_top > 0) - { - GUILayoutUtility.GetRect(0, Options.margin_top); - } - foreach (ShaderPart part in parts) - { - part.Draw(); - } - } - - public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] propertyTypesToSkip = null) - { - if (ShouldSkipProperty(MaterialProperty, propertyTypesToSkip)) return; - if (p is ShaderGroup == false) return; - ShaderGroup group = p as ShaderGroup; - if (Options.reference_property != null && group.Options.reference_property != null) - ActiveShaderEditor.PropertyDictionary[Options.reference_property].TransferFromMaterialAndGroup(m, group.ActiveShaderEditor.PropertyDictionary[group.Options.reference_property]); - for(int i=0;i unusedList, bool isEnabled) - { - if (isEnabled && Options.condition_enable != null) - { - isEnabled &= Options.condition_enable.Test(); - } - foreach (ShaderPart p in (this as ShaderGroup).parts) - p.FindUnusedTextures(unusedList, isEnabled); - } - - protected void HandleLinkedMaterials() - { - List linked_materials = MaterialLinker.GetLinked(MaterialProperty); - if (linked_materials != null) - foreach (Material m in linked_materials) - this.CopyToMaterial(m); - } - - protected void FoldoutArrow(Rect rect, Event e) - { - if (e.type == EventType.Repaint) - { - Rect arrowRect = new RectOffset(4, 0, 0, 0).Remove(rect); - arrowRect.width = 13; - EditorStyles.foldout.Draw(arrowRect, false, false, _isExpanded, false); - } - } - } - - public class ShaderSection : ShaderGroup - { - - const int BORDER_WIDTH = 3; - const int HEADER_HEIGHT = 20; - const int CHECKBOX_OFFSET = 20; - - public ShaderSection(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, materialEditor, displayName, xOffset, optionsRaw, propertyIndex) - { - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - if(Options.margin_top > 0) - { - GUILayoutUtility.GetRect(0, Options.margin_top); - } - - ShaderProperty reference = Options.reference_property != null ? ActiveShaderEditor.PropertyDictionary[Options.reference_property] : null; - bool has_header = string.IsNullOrWhiteSpace(this.Content.text) == false || reference != null; - - int headerTextX = 18; - int height = (has_header ? HEADER_HEIGHT : 0) + 4; // 4 for border margin - - // Draw border - Rect border = EditorGUILayout.BeginVertical(); - border = new RectOffset(this.XOffset * -15 - 12, 3, -2, -2).Add(border); - if(IsExpanded) - { - // Draw as border line - Vector4 borderWidths = new Vector4(3, (has_header ? HEADER_HEIGHT : 3), 3, 3); - GUI.DrawTexture(border, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, borderWidths, 5); - }else - { - // Draw as solid - GUI.DrawTexture(border, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, Vector4.zero, 5); - } - - // Draw Reference - Rect clickCheckRect = GUILayoutUtility.GetRect(0, height); - if(reference != null) - { - EditorGUI.BeginChangeCheck(); - Rect referenceRect = new Rect(border.x + CHECKBOX_OFFSET, border.y + 1, HEADER_HEIGHT - 2, HEADER_HEIGHT - 2); - reference.Draw(new CRect(referenceRect), new GUIContent(), isInHeader: true, useEditorIndent: true); - headerTextX = CHECKBOX_OFFSET + HEADER_HEIGHT; - // Change expand state if reference is toggled - if(EditorGUI.EndChangeCheck() && Options.ref_float_toggles_expand) - { - IsExpanded = reference.MaterialProperty.GetNumber() == 1; - } - } - - // Draw Header (GUIContent) - Rect top_border = new Rect(border.x, border.y - 2, border.width - 16, 22); - if(has_header) - { - Rect header_rect = new RectOffset(headerTextX, 0, 0, 0).Remove(top_border); - GUI.Label(header_rect, this.Content, EditorStyles.label); - } - - // Toggling + Draw Arrow - FoldoutArrow(top_border, Event.current); - if (Event.current.type == EventType.MouseDown && clickCheckRect.Contains(Event.current.mousePosition)) - { - IsExpanded = !IsExpanded; - Event.current.Use(); - } - - // Draw Children - if(IsExpanded) - { - EditorGUI.BeginDisabledGroup(DoDisableChildren); - foreach (ShaderPart part in parts) - { - part.Draw(); - } - EditorGUI.EndDisabledGroup(); - GUILayoutUtility.GetRect(0, 5); - } - EditorGUILayout.EndVertical(); - } - } - - public class ShaderHeader : ShaderGroup - { - - public ShaderHeader(ShaderEditor shaderEditor) : base(shaderEditor) - { - } - - public ShaderHeader(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, materialEditor, displayName, xOffset, optionsRaw, propertyIndex) - { - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - ActiveShaderEditor.CurrentProperty = this; - EditorGUI.BeginChangeCheck(); - Rect position = GUILayoutUtility.GetRect(content, Styles.dropDownHeader); - DrawHeader(position, content); - Rect headerRect = DrawingData.LastGuiObjectHeaderRect; - if (IsExpanded) - { - if (ShaderEditor.Active.IsSectionedPresetEditor) - { - string presetName = Presets.GetSectionPresetName(ShaderEditor.Active.Materials[0], this.MaterialProperty.name); - EditorGUI.BeginChangeCheck(); - presetName = EditorGUILayout.DelayedTextField("Preset Name:", presetName); - if (EditorGUI.EndChangeCheck()) - { - Presets.SetSectionPreset(ShaderEditor.Active.Materials[0], this.MaterialProperty.name, presetName); - } - } - - EditorGUILayout.Space(); - EditorGUI.BeginDisabledGroup(DoDisableChildren); - foreach (ShaderPart part in parts) - { - part.Draw(); - } - EditorGUI.EndDisabledGroup(); - EditorGUILayout.Space(); - } - if (EditorGUI.EndChangeCheck()) - HandleLinkedMaterials(); - DrawingData.LastGuiObjectHeaderRect = headerRect; - DrawingData.LastGuiObjectRect = headerRect; - } - - private void DrawHeader(Rect position, GUIContent label) - { - PropertyOptions options = ShaderEditor.Active.CurrentProperty.Options; - Event e = Event.current; - - int xOffset_total = XOffset * 15 + 15; - - position.width -= xOffset_total - position.x; - position.x = xOffset_total; - - DrawingData.LastGuiObjectHeaderRect = position; - DrawBoxAndContent(position, e, label, options); - - Rect arrowRect = new Rect(position){ height = 18 }; - FoldoutArrow(arrowRect, e); - - HandleToggleInput(position); - } - - private void DrawBoxAndContent(Rect rect, Event e, GUIContent content, PropertyOptions options) - { - if (options.reference_property != null && ShaderEditor.Active.PropertyDictionary.ContainsKey(options.reference_property)) - { - GUI.Box(rect, new GUIContent(" " + content.text, content.tooltip), Styles.dropDownHeader); - DrawIcons(rect, options, e); - - Rect togglePropertyRect = new Rect(rect); - togglePropertyRect.x += 5; - togglePropertyRect.y += 1; - togglePropertyRect.height -= 4; - togglePropertyRect.width = GUI.skin.font.fontSize * 3; - float fieldWidth = EditorGUIUtility.fieldWidth; - EditorGUIUtility.fieldWidth = 20; - ShaderProperty refProperty = ShaderEditor.Active.PropertyDictionary[options.reference_property]; - - EditorGUI.BeginChangeCheck(); - - int xOffset = refProperty.XOffset; - refProperty.XOffset = 0; - refProperty.Draw(new CRect(togglePropertyRect), new GUIContent(), isInHeader: true); - refProperty.XOffset = xOffset; - EditorGUIUtility.fieldWidth = fieldWidth; - - // Change expand state if reference is toggled - if(EditorGUI.EndChangeCheck() && Options.ref_float_toggles_expand) - { - IsExpanded = refProperty.MaterialProperty.GetNumber() == 1; - } - } - // else if(keyword != null) - // { - // GUI.Box(rect, " " + content.text, Styles.dropDownHeader); - // DrawIcons(rect, options, e); - - // Rect togglePropertyRect = new Rect(rect); - // togglePropertyRect.x += 20; - // togglePropertyRect.width = 20; - - // EditorGUI.BeginChangeCheck(); - // bool keywordOn = EditorGUI.Toggle(togglePropertyRect, "", ShaderEditor.Active.Materials[0].IsKeywordEnabled(keyword)); - // if (EditorGUI.EndChangeCheck()) - // { - // MaterialHelper.ToggleKeyword(ShaderEditor.Active.Materials, keyword, keywordOn); - // } - // } - else - { - GUI.Box(rect, content, Styles.dropDownHeader); - DrawIcons(rect, options, e); - } - - } - - /// - /// Draws the icons for ShaderEditor features like linking and copying - /// - /// - /// - private void DrawIcons(Rect rect, PropertyOptions options, Event e) - { - Rect buttonRect = new Rect(rect); - buttonRect.y += 1; - buttonRect.height -= 4; - buttonRect.width = buttonRect.height; - - float right = rect.x + rect.width; - buttonRect.x = right - 74; - DrawPresetButton(buttonRect, options, e); - buttonRect.x = right - 56; - DrawHelpButton(buttonRect, options, e); - buttonRect.x = right - 38; - DrawLinkSettings(buttonRect, e); - buttonRect.x = right - 20; - DrawDowdownSettings(buttonRect, e); - } - - private void DrawHelpButton(Rect rect, PropertyOptions options, Event e) - { - ButtonData button = options.button_help; - if (button != null && button.condition_show.Test()) - { - if (GuiHelper.Button(rect, Styles.icon_style_help)) - { - ShaderEditor.Input.Use(); - if (button.action != null) button.action.Perform(ShaderEditor.Active?.Materials); - } - } - } - - private void DrawPresetButton(Rect rect, PropertyOptions options, Event e) - { - bool hasPresets = Presets.DoesSectionHavePresets(this.MaterialProperty.name); - if (hasPresets) - { - if (GuiHelper.Button(rect, Styles.icon_style_presets)) - { - ShaderEditor.Input.Use(); - Presets.OpenPresetsMenu(rect, ActiveShaderEditor, true, this.MaterialProperty.name); - } - } - } - - private void DrawDowdownSettings(Rect rect, Event e) - { - if (GuiHelper.Button(rect, Styles.icon_style_menu)) - { - ShaderEditor.Input.Use(); - Rect buttonRect = new Rect(rect); - buttonRect.width = 150; - buttonRect.x = Mathf.Min(Screen.width - buttonRect.width, buttonRect.x); - buttonRect.height = 60; - float maxY = GUIUtility.ScreenToGUIPoint(new Vector2(0, EditorWindow.focusedWindow.position.y + Screen.height)).y - 2.5f * buttonRect.height; - buttonRect.y = Mathf.Min(buttonRect.y - buttonRect.height / 2, maxY); - - ShowHeaderContextMenu(buttonRect, ShaderEditor.Active.CurrentProperty, ShaderEditor.Active.Materials[0]); - } - } - - private void DrawLinkSettings(Rect rect, Event e) - { - if (GuiHelper.Button(rect, Styles.icon_style_linked, Styles.COLOR_ICON_ACTIVE_CYAN, MaterialLinker.IsLinked(ShaderEditor.Active.CurrentProperty.MaterialProperty))) - { - ShaderEditor.Input.Use(); - List linked_materials = MaterialLinker.GetLinked(ShaderEditor.Active.CurrentProperty.MaterialProperty); - MaterialLinker.Popup(rect, linked_materials, ShaderEditor.Active.CurrentProperty.MaterialProperty); - } - } - - void ShowHeaderContextMenu(Rect position, ShaderPart property, Material material) - { - var menu = new GenericMenu(); - menu.AddItem(new GUIContent("Reset"), false, delegate () - { - property.CopyFromMaterial(new Material(material.shader), true); - List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); - if (linked_materials != null) - foreach (Material m in linked_materials) - property.CopyToMaterial(m, true); - }); - menu.AddItem(new GUIContent("Copy"), false, delegate () - { - Mediator.copy_material = new Material(material); - Mediator.transfer_group = property; - }); - menu.AddItem(new GUIContent("Paste"), false, delegate () - { - if (Mediator.copy_material != null || Mediator.transfer_group != null) - { - property.TransferFromMaterialAndGroup(Mediator.copy_material, Mediator.transfer_group, true); - List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); - if (linked_materials != null) - foreach (Material m in linked_materials) - property.CopyToMaterial(m, true); - } - }); - menu.AddItem(new GUIContent("Paste without Textures"), false, delegate () - { - if(Mediator.copy_material != null || Mediator.transfer_group != null) - { - var propsToIgnore = new MaterialProperty.PropType[] { MaterialProperty.PropType.Texture }; - property.TransferFromMaterialAndGroup(Mediator.copy_material, Mediator.transfer_group, true, propsToIgnore); - List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); - if(linked_materials != null) - foreach(Material m in linked_materials) - property.CopyToMaterial(m, true, propsToIgnore); - } - }); - menu.DropDown(position); - } - - private void HandleToggleInput(Rect rect) - { - //Ignore unity uses is cause disabled will use the event to prevent toggling - if (ShaderEditor.Input.LeftClick_IgnoreLocked && rect.Contains(ShaderEditor.Input.mouse_position) && !ShaderEditor.Input.is_alt_down) - { - IsExpanded = !IsExpanded; - ShaderEditor.Input.Use(); - } - } - } - - public class ShaderProperty : ShaderPart - { - protected bool _doCustomDrawLogic = false; - protected bool _doForceIntoOneLine = false; - protected bool _doDrawTwoFields = false; - - //Done for e.g. Vectors cause they draw in 2 lines for some fucking reasons - public bool DoCustomHeightOffset = false; - public float CustomHeightOffset = 0; - - public string Keyword; - - protected MaterialPropertyDrawer[] _customDecorators; - protected Rect[] _customDecoratorRects; - protected bool _hasDrawer = false; - - bool _needsDrawerInitlization = true; - - public ShaderProperty(ShaderEditor shaderEditor, string propertyIdentifier, int xOffset, string displayName, string tooltip, int propertyIndex) : base(propertyIdentifier, xOffset, displayName, tooltip, shaderEditor) - { - this.ShaderPropertyIndex = propertyIndex; - } - - public ShaderProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int propertyIndex) : base(shaderEditor, materialProperty, xOffset, displayName, optionsRaw, propertyIndex) - { - this._doCustomDrawLogic = false; - this._doForceIntoOneLine = forceOneLine; - } - - protected override void InitOptions() - { - base.InitOptions(); - this._doDrawTwoFields = Options.reference_property != null; - } - - public override void CopyFromMaterial(Material m, bool isTopCall = false) - { - MaterialHelper.CopyPropertyValueFromMaterial(MaterialProperty, m); - CopyReferencePropertiesFromMaterial(m); - - if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, m.GetNumber(MaterialProperty)==1); - if (IsAnimatable) - { - ShaderOptimizer.CopyAnimatedTagFromMaterial(m, MaterialProperty); - } - this.IsAnimated = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) != ""; - this.IsRenaming = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) == "2"; - - ExecuteOnValueActions(ShaderEditor.Active.Materials); - - if (isTopCall) ActiveShaderEditor.ApplyDrawers(); - } - - public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - if (ShouldSkipProperty(MaterialProperty, skipPropertyTypes)) return; - - MaterialHelper.CopyPropertyValueToMaterial(MaterialProperty, m); - CopyReferencePropertiesToMaterial(m); - - if (Keyword != null) SetKeyword(m, MaterialProperty.GetNumber() == 1); - if (IsAnimatable) - ShaderOptimizer.CopyAnimatedTagToMaterials(new Material[] { m }, MaterialProperty); - - ExecuteOnValueActions(new Material[] { m }); - - if (isTopCall) MaterialEditor.ApplyMaterialPropertyDrawers(m); - } - - private void SetKeyword(Material[] materials, bool enabled) - { - if (enabled) foreach (Material m in materials) m.EnableKeyword(Keyword); - else foreach (Material m in materials) m.DisableKeyword(Keyword); - } - - private void SetKeyword(Material m, bool enabled) - { - if (enabled) m.EnableKeyword(Keyword); - else m.DisableKeyword(Keyword); - } - - public void UpdateKeywordFromValue() - { - if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, MaterialProperty.GetNumber() == 1); - } - - void InitializeDrawers() - { - DrawingData.ResetLastDrawerData(); - DrawingData.IsCollectingProperties = true; - ShaderEditor.Active.Editor.GetPropertyHeight(MaterialProperty, MaterialProperty.displayName); - - this.IsAnimatable = !DrawingData.LastPropertyDoesntAllowAnimation && IsAnimatable; // &&, so that IsAnimatable can be set to false before InitializeDrawers - this._hasDrawer = DrawingData.LastPropertyUsedCustomDrawer; - - if (MaterialProperty.type == MaterialProperty.PropType.Vector && _doForceIntoOneLine == false) - { - this.DoCustomHeightOffset = !DrawingData.LastPropertyUsedCustomDrawer; - this.CustomHeightOffset = -EditorGUIUtility.singleLineHeight; - } - if(DrawingData.LastPropertyDecorators.Count > 0) - { - _customDecorators = DrawingData.LastPropertyDecorators.ToArray(); - _customDecoratorRects = new Rect[DrawingData.LastPropertyDecorators.Count]; - } - - // Animatable Stuff - bool propHasDuplicate = ShaderEditor.Active.GetMaterialProperty(MaterialProperty.name + "_" + ShaderEditor.Active.RenamedPropertySuffix) != null; - string tag = null; - //If prop is og, but is duplicated (locked) dont have it animateable - if (propHasDuplicate) - { - this.IsAnimatable = false; - } - else - { - //if prop is a duplicated or renamed get og property to check for animted status - if (MaterialProperty.name.Contains(ShaderEditor.Active.RenamedPropertySuffix)) - { - string ogName = MaterialProperty.name.Substring(0, MaterialProperty.name.Length - ShaderEditor.Active.RenamedPropertySuffix.Length - 1); - tag = ShaderOptimizer.GetAnimatedTag(MaterialProperty.targets[0] as Material, ogName); - } - else - { - tag = ShaderOptimizer.GetAnimatedTag(MaterialProperty); - } - } - - this.IsAnimated = IsAnimatable && tag != ""; - this.IsRenaming = IsAnimatable && tag == "2"; - - DrawingData.IsCollectingProperties = false; - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - ActiveShaderEditor.CurrentProperty = this; - this.MaterialProperty = ActiveShaderEditor.Properties[ShaderPropertyIndex]; - - if(_needsDrawerInitlization) - { - InitializeDrawers(); - _needsDrawerInitlization = false; - } - - PreDraw(); - if (ActiveShaderEditor.IsLockedMaterial) - EditorGUI.BeginDisabledGroup(!(IsAnimatable && (IsAnimated || IsRenaming)) && !ExemptFromLockedDisabling); - int oldIndentLevel = EditorGUI.indentLevel; - if (!useEditorIndent) - EditorGUI.indentLevel = XOffset + 1; - - if(_customDecorators != null && _doCustomDrawLogic) - { - for(int i= 0;i<_customDecorators.Length;i++) - { - _customDecoratorRects[i] = EditorGUILayout.GetControlRect(false, GUILayout.Height(_customDecorators[i].GetPropertyHeight(MaterialProperty, content.text, ActiveShaderEditor.Editor))); - } - } - - if (_doCustomDrawLogic) - { - DrawDefault(); - } - else if (_doDrawTwoFields) - { - Rect r = GUILayoutUtility.GetRect(content, Styles.vectorPropertyStyle); - float labelWidth = (r.width - EditorGUIUtility.labelWidth) / 2; ; - r.width -= labelWidth; - ActiveShaderEditor.Editor.ShaderProperty(r, this.MaterialProperty, content); - - r.x += r.width; - r.width = labelWidth; - float prevLabelW = EditorGUIUtility.labelWidth; - EditorGUIUtility.labelWidth = 0; - ActiveShaderEditor.PropertyDictionary[Options.reference_property].Draw(new CRect(r), new GUIContent()); - EditorGUIUtility.labelWidth = prevLabelW; - } - else if (_doForceIntoOneLine) - { - ActiveShaderEditor.Editor.ShaderProperty(GUILayoutUtility.GetRect(content, Styles.vectorPropertyStyle), this.MaterialProperty, content); - }else if (DoCustomHeightOffset) - { - ActiveShaderEditor.Editor.ShaderProperty( - GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, ActiveShaderEditor.Editor.GetPropertyHeight(this.MaterialProperty, content.text) + CustomHeightOffset) - , this.MaterialProperty, content); - } - else if (rect != null) - { - // Custom Drawing for Range, because it doesnt draw correctly if inside the big texture property - if(!_hasDrawer && MaterialProperty.type == MaterialProperty.PropType.Range) - { - MaterialProperty.floatValue = EditorGUI.Slider(rect.r, content, MaterialProperty.floatValue, 0, MaterialProperty.rangeLimits.y); - }else - { - ActiveShaderEditor.Editor.ShaderProperty(rect.r, this.MaterialProperty, content); - } - } - else - { - ActiveShaderEditor.Editor.ShaderProperty(this.MaterialProperty, content); - } - - if(_customDecorators != null && _doCustomDrawLogic) - { - for(int i= 0;i<_customDecorators.Length;i++) - { - _customDecorators[i].OnGUI(_customDecoratorRects[i], MaterialProperty, content, ShaderEditor.Active.Editor); - } - } - - EditorGUI.indentLevel = oldIndentLevel; - if (rect == null) DrawingData.LastGuiObjectRect = GUILayoutUtility.GetLastRect(); - else DrawingData.LastGuiObjectRect = rect.r; - if (ActiveShaderEditor.IsLockedMaterial) - EditorGUI.EndDisabledGroup(); - } - - public virtual void PreDraw() { } - - public virtual void DrawDefault() { } - - public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - if (ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) return; - if (MaterialProperty.type != p.MaterialProperty.type) return; - MaterialHelper.CopyMaterialValueFromProperty(MaterialProperty, p.MaterialProperty); - if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, m.GetNumber(p.MaterialProperty) == 1); - if (IsAnimatable && p.IsAnimatable) - ShaderOptimizer.CopyAnimatedTagFromProperty(p.MaterialProperty, MaterialProperty); - this.IsAnimated = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) != ""; - this.IsRenaming = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) == "2"; - - if (isTopCall) ActiveShaderEditor.ApplyDrawers(); - } - - public override void FindUnusedTextures(List unusedList, bool isEnabled) - { - if (isEnabled && Options.condition_enable != null) - { - isEnabled &= Options.condition_enable.Test(); - } - if (!isEnabled && MaterialProperty != null && MaterialProperty.type == MaterialProperty.PropType.Texture && MaterialProperty.textureValue != null) - { - unusedList.Add(MaterialProperty.name); - } - } - } - - public class TextureProperty : ShaderProperty - { - public bool showFoldoutProperties = false; - public bool hasFoldoutProperties = false; - public bool hasScaleOffset = false; - public string VRAMString = ""; - bool _isVRAMDirty = true; - - public TextureProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool hasScaleOffset, bool forceThryUI, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, false, property_index) - { - _doCustomDrawLogic = forceThryUI; - this.hasScaleOffset = hasScaleOffset; - } - - protected override void InitOptions() - { - base.InitOptions(); - this.hasFoldoutProperties = hasScaleOffset || DoReferencePropertiesExist; - } - - void UpdateVRAM() - { - if (MaterialProperty.textureValue != null) - { - var details = TextureHelper.VRAM.CalcSize(MaterialProperty.textureValue); - this.VRAMString = $"{TextureHelper.VRAM.ToByteString(details.size)}"; - } - else - { - VRAMString = null; - } - } - - protected override void OnPropertyValueChanged() - { - base.OnPropertyValueChanged(); - _isVRAMDirty = true; - } - - public override void PreDraw() - { - DrawingData.CurrentTextureProperty = this; - this._doCustomDrawLogic = !this._hasDrawer; - if (this._isVRAMDirty) - { - UpdateVRAM(); - _isVRAMDirty = false; - } - } - - public override void DrawDefault() - { - Rect pos = GUILayoutUtility.GetRect(Content, Styles.vectorPropertyStyle); - GuiHelper.ConfigTextureProperty(pos, MaterialProperty, Content, ActiveShaderEditor.Editor, hasFoldoutProperties); - DrawingData.LastGuiObjectRect = pos; - } - - public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - if (ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) return; - if (MaterialProperty.type != p.MaterialProperty.type) return; - MaterialHelper.CopyMaterialValueFromProperty(MaterialProperty, p.MaterialProperty); - TransferReferencePropertiesToMaterial(m, p); - } - private void TransferReferencePropertiesToMaterial(Material target, ShaderPart p) - { - if (p.Options.reference_properties == null || this.Options.reference_properties == null) return; - for (int i = 0; i < p.Options.reference_properties.Length && i < Options.reference_properties.Length; i++) - { - if (ActiveShaderEditor.PropertyDictionary.ContainsKey(this.Options.reference_properties[i]) == false) continue; - - ShaderProperty targetP = ActiveShaderEditor.PropertyDictionary[this.Options.reference_properties[i]]; - ShaderProperty sourceP = p.ActiveShaderEditor.PropertyDictionary[p.Options.reference_properties[i]]; - MaterialHelper.CopyMaterialValueFromProperty(targetP.MaterialProperty, sourceP.MaterialProperty); - } - } - } - - public class ShaderHeaderProperty : ShaderPart - { - public ShaderHeaderProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int propertyIndex) : base(shaderEditor, materialProperty, xOffset, displayName, optionsRaw, propertyIndex) - { - // guid is defined as - if(displayName.Contains("", start); - string guid = displayName.Substring(start + 6, end - start - 6); - string path = AssetDatabase.GUIDToAssetPath(guid); - string replacement = ""; - if (path != null && System.IO.File.Exists(path)) - { - replacement = System.IO.File.ReadAllText(path); - } - Content.text = displayName.Replace($"", replacement); - } - } - - public override void HandleRightClickToggles(bool isInHeader) - { - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - if (rect == null) - { - if (Options.texture != null && Options.texture.name != null) - { - //is texutre draw - content = new GUIContent(Options.texture.loaded_texture, content.tooltip); - int height = Options.texture.height; - int width = (int)((float)Options.texture.loaded_texture.width / Options.texture.loaded_texture.height * height); - Rect control = EditorGUILayout.GetControlRect(false, height-18); - Rect r = new Rect((control.width-width)/2,control.y,width, height); - GUI.DrawTexture(r, Options.texture.loaded_texture); - } - } - else - { - //is text draw - Rect headerrect = new Rect(0, rect.r.y, rect.r.width, 18); - EditorGUI.LabelField(headerrect, "" + this.Content.text + "", Styles.masterLabel); - DrawingData.LastGuiObjectRect = headerrect; - } - } - - public override void CopyFromMaterial(Material m, bool isTopCall = false) - { - throw new System.NotImplementedException(); - } - - public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - throw new System.NotImplementedException(); - } - - public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - throw new System.NotImplementedException(); - } - - public override void FindUnusedTextures(List unusedList, bool isEnabled) - { - } - } - - public class RenderQueueProperty : ShaderProperty - { - public RenderQueueProperty(ShaderEditor shaderEditor) : base(shaderEditor, "RenderQueue", 0, "", "Change the Queue at which the material is rendered.", 0) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - CustomStringTagID = "RenderQueue"; - } - - public override void DrawDefault() - { - ActiveShaderEditor.Editor.RenderQueueField(); - } - - public override void CopyFromMaterial(Material sourceM, bool isTopCall = false) - { - foreach (Material m in ActiveShaderEditor.Materials) m.renderQueue = sourceM.renderQueue; - } - public override void CopyToMaterial(Material targetM, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - targetM.renderQueue = ActiveShaderEditor.Materials[0].renderQueue; - } - } - public class VRCFallbackProperty : ShaderProperty - { - static string[] s_fallbackShaderTypes = { "Standard", "Toon", "Unlit", "VertexLit", "Particle", "Sprite", "Matcap", "MobileToon" }; - static string[] s_fallbackRenderTypes = { "Opaque", "Cutout", "Transparent", "Fade" }; - static string[] s_fallbackRenderTypesValues = { "", "Cutout", "Transparent", "Fade" }; - static string[] s_fallbackCullTypes = { "OneSided", "DoubleSided" }; - static string[] s_fallbackCullTypesValues = { "", "DoubleSided" }; - static string[] s_fallbackNoTypes = { "None", "Hidden" }; - static string[] s_fallbackNoTypesValues = { "", "Hidden" }; - static string[] s_vRCFallbackOptionsPopup = s_fallbackNoTypes.Union(s_fallbackShaderTypes.SelectMany(s => s_fallbackRenderTypes.SelectMany(r => s_fallbackCullTypes.Select(c => r + "/" + c).Select(rc => s + "/" + rc)))).ToArray(); - static string[] s_vRCFallbackOptionsValues = s_fallbackNoTypes.Union(s_fallbackShaderTypes.SelectMany(s => s_fallbackRenderTypesValues.SelectMany(r => s_fallbackCullTypesValues.Select(c => r + c).Select(rc => s + rc)))).ToArray(); - - public VRCFallbackProperty(ShaderEditor shaderEditor) : base(shaderEditor, "VRCFallback", 0, "", "Select the shader VRChat should use when your shaders are being hidden.", 0) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - CustomStringTagID = "VRCFallback"; - ExemptFromLockedDisabling = true; - } - - public override void DrawDefault() - { - string current = ActiveShaderEditor.Materials[0].GetTag("VRCFallback", false, "None"); - EditorGUI.BeginChangeCheck(); - int selected = EditorGUILayout.Popup("VRChat Fallback Shader", s_vRCFallbackOptionsValues.Select((f, i) => (f, i)).FirstOrDefault(f => f.f == current).i, s_vRCFallbackOptionsPopup); - if (EditorGUI.EndChangeCheck()) - { - foreach(Material m in ActiveShaderEditor.Materials) - { - m.SetOverrideTag("VRCFallback", s_vRCFallbackOptionsValues[selected]); - EditorUtility.SetDirty(m); - } - } - } - - public override void CopyFromMaterial(Material sourceM, bool isTopCall = false) - { - string value = sourceM.GetTag("VRCFallback", false, "None"); - foreach (Material m in ActiveShaderEditor.Materials) m.SetOverrideTag("VRCFallback", value); - } - public override void CopyToMaterial(Material targetM, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) - { - string value = ActiveShaderEditor.Materials[0].GetTag("VRCFallback", false, "None"); - targetM.SetOverrideTag("VRCFallback", value); - } - } - public class InstancingProperty : ShaderProperty - { - public InstancingProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - } - - public override void DrawDefault() - { - ActiveShaderEditor.Editor.EnableInstancingField(); - } - } - public class GIProperty : ShaderProperty - { - public GIProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - } - - public override void DrawInternal(GUIContent content, CRect rect = null, bool useEditorIndent = false, bool isInHeader = false) - { - base.DrawInternal(content, rect, useEditorIndent, isInHeader); - } - - public override void DrawDefault() - { - LightmapEmissionFlagsProperty(XOffset, false); - } - - public static readonly GUIContent lightmapEmissiveLabel = EditorGUIUtility.TrTextContent("Global Illumination", "Controls if the emission is baked or realtime.\n\nBaked only has effect in scenes where baked global illumination is enabled.\n\nRealtime uses realtime global illumination if enabled in the scene. Otherwise the emission won't light up other objects."); - public static GUIContent[] lightmapEmissiveStrings = { EditorGUIUtility.TrTextContent("Realtime"), EditorGUIUtility.TrTextContent("Baked"), EditorGUIUtility.TrTextContent("None") }; - public static int[] lightmapEmissiveValues = { (int)MaterialGlobalIlluminationFlags.RealtimeEmissive, (int)MaterialGlobalIlluminationFlags.BakedEmissive, (int)MaterialGlobalIlluminationFlags.None }; - - public static void FixupEmissiveFlag(Material mat) - { - if (mat == null) - throw new System.ArgumentNullException("mat"); - - mat.globalIlluminationFlags = FixupEmissiveFlag(mat.GetColor("_EmissionColor"), mat.globalIlluminationFlags); - } - - public static MaterialGlobalIlluminationFlags FixupEmissiveFlag(Color col, MaterialGlobalIlluminationFlags flags) - { - if ((flags & MaterialGlobalIlluminationFlags.BakedEmissive) != 0 && col.maxColorComponent == 0.0f) // flag black baked - flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; - else if (flags != MaterialGlobalIlluminationFlags.EmissiveIsBlack) // clear baked flag on everything else, unless it's explicity disabled - flags &= MaterialGlobalIlluminationFlags.AnyEmissive; - return flags; - } - - public void LightmapEmissionFlagsProperty(int indent, bool enabled) - { - LightmapEmissionFlagsProperty(indent, enabled, false); - } - - public void LightmapEmissionFlagsProperty(int indent, bool enabled, bool ignoreEmissionColor) - { - // Calculate isMixed - MaterialGlobalIlluminationFlags any_em = MaterialGlobalIlluminationFlags.AnyEmissive; - MaterialGlobalIlluminationFlags giFlags = ActiveShaderEditor.Materials[0].globalIlluminationFlags & any_em; - bool isMixed = false; - for (int i = 1; i < ActiveShaderEditor.Materials.Length; i++) - { - if((ActiveShaderEditor.Materials[i].globalIlluminationFlags & any_em) != giFlags) - { - isMixed = true; - break; - } - } - - EditorGUI.BeginChangeCheck(); - - // Show popup - EditorGUI.showMixedValue = isMixed; - giFlags = (MaterialGlobalIlluminationFlags)EditorGUILayout.IntPopup(lightmapEmissiveLabel, (int)giFlags, lightmapEmissiveStrings, lightmapEmissiveValues); - EditorGUI.showMixedValue = false; - - // Apply flags. But only the part that this tool modifies (RealtimeEmissive, BakedEmissive, None) - bool applyFlags = EditorGUI.EndChangeCheck(); - foreach (Material mat in ActiveShaderEditor.Materials) - { - mat.globalIlluminationFlags = applyFlags ? giFlags : mat.globalIlluminationFlags; - if (!ignoreEmissionColor) - { - FixupEmissiveFlag(mat); - } - } - } - } - public class DSGIProperty : ShaderProperty - { - public DSGIProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - } - - public override void DrawDefault() - { - ActiveShaderEditor.Editor.DoubleSidedGIField(); - } - } - public class LocaleProperty : ShaderProperty - { - public LocaleProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) - { - _doCustomDrawLogic = true; - IsAnimatable = false; - } - - public override void DrawDefault() - { - ShaderEditor.Active.Locale.DrawDropdown(); - } - } -} diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.meta new file mode 100644 index 00000000..fc99d9ce --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 78352e6991d72044a8be5d55b9180c02 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs new file mode 100644 index 00000000..55ea702e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs @@ -0,0 +1,199 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class RenderQueueProperty : ShaderProperty + { + public RenderQueueProperty(ShaderEditor shaderEditor) : base(shaderEditor, "RenderQueue", 0, "", "Change the Queue at which the material is rendered.", 0) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + CustomStringTagID = "RenderQueue"; + } + + public override void DrawDefault() + { + ActiveShaderEditor.Editor.RenderQueueField(); + } + + public override void CopyFromMaterial(Material sourceM, bool isTopCall = false) + { + foreach (Material m in ActiveShaderEditor.Materials) m.renderQueue = sourceM.renderQueue; + } + public override void CopyToMaterial(Material targetM, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + targetM.renderQueue = ActiveShaderEditor.Materials[0].renderQueue; + } + } + public class VRCFallbackProperty : ShaderProperty + { + static string[] s_fallbackShaderTypes = { "Standard", "Toon", "Unlit", "VertexLit", "Particle", "Sprite", "Matcap", "MobileToon" }; + static string[] s_fallbackRenderTypes = { "Opaque", "Cutout", "Transparent", "Fade" }; + static string[] s_fallbackRenderTypesValues = { "", "Cutout", "Transparent", "Fade" }; + static string[] s_fallbackCullTypes = { "OneSided", "DoubleSided" }; + static string[] s_fallbackCullTypesValues = { "", "DoubleSided" }; + static string[] s_fallbackNoTypes = { "None", "Hidden" }; + static string[] s_fallbackNoTypesValues = { "", "Hidden" }; + static string[] s_vRCFallbackOptionsPopup = s_fallbackNoTypes.Union(s_fallbackShaderTypes.SelectMany(s => s_fallbackRenderTypes.SelectMany(r => s_fallbackCullTypes.Select(c => r + "/" + c).Select(rc => s + "/" + rc)))).ToArray(); + static string[] s_vRCFallbackOptionsValues = s_fallbackNoTypes.Union(s_fallbackShaderTypes.SelectMany(s => s_fallbackRenderTypesValues.SelectMany(r => s_fallbackCullTypesValues.Select(c => r + c).Select(rc => s + rc)))).ToArray(); + + public VRCFallbackProperty(ShaderEditor shaderEditor) : base(shaderEditor, "VRCFallback", 0, "", "Select the shader VRChat should use when your shaders are being hidden.", 0) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + CustomStringTagID = "VRCFallback"; + IsExemptFromLockedDisabling = true; + } + + public override void DrawDefault() + { + string current = ActiveShaderEditor.Materials[0].GetTag("VRCFallback", false, "None"); + EditorGUI.BeginChangeCheck(); + int selected = EditorGUILayout.Popup("VRChat Fallback Shader", s_vRCFallbackOptionsValues.Select((f, i) => (f, i)).FirstOrDefault(f => f.f == current).i, s_vRCFallbackOptionsPopup); + if (EditorGUI.EndChangeCheck()) + { + foreach (Material m in ActiveShaderEditor.Materials) + { + m.SetOverrideTag("VRCFallback", s_vRCFallbackOptionsValues[selected]); + EditorUtility.SetDirty(m); + } + } + } + + public override void CopyFromMaterial(Material sourceM, bool isTopCall = false) + { + string value = sourceM.GetTag("VRCFallback", false, "None"); + foreach (Material m in ActiveShaderEditor.Materials) m.SetOverrideTag("VRCFallback", value); + } + public override void CopyToMaterial(Material targetM, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + string value = ActiveShaderEditor.Materials[0].GetTag("VRCFallback", false, "None"); + targetM.SetOverrideTag("VRCFallback", value); + } + } + public class InstancingProperty : ShaderProperty + { + public InstancingProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + } + + public override void DrawDefault() + { + ActiveShaderEditor.Editor.EnableInstancingField(); + } + } + public class GIProperty : ShaderProperty + { + public GIProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + base.DrawInternal(content, rect, useEditorIndent, isInHeader); + } + + public override void DrawDefault() + { + LightmapEmissionFlagsProperty(XOffset, false); + } + + public static readonly GUIContent lightmapEmissiveLabel = EditorGUIUtility.TrTextContent("Global Illumination", "Controls if the emission is baked or realtime.\n\nBaked only has effect in scenes where baked global illumination is enabled.\n\nRealtime uses realtime global illumination if enabled in the scene. Otherwise the emission won't light up other objects."); + public static GUIContent[] lightmapEmissiveStrings = { EditorGUIUtility.TrTextContent("Realtime"), EditorGUIUtility.TrTextContent("Baked"), EditorGUIUtility.TrTextContent("None") }; + public static int[] lightmapEmissiveValues = { (int)MaterialGlobalIlluminationFlags.RealtimeEmissive, (int)MaterialGlobalIlluminationFlags.BakedEmissive, (int)MaterialGlobalIlluminationFlags.None }; + + public static void FixupEmissiveFlag(Material mat) + { + if (mat == null) + throw new System.ArgumentNullException("mat"); + + mat.globalIlluminationFlags = FixupEmissiveFlag(mat.GetColor("_EmissionColor"), mat.globalIlluminationFlags); + } + + public static MaterialGlobalIlluminationFlags FixupEmissiveFlag(Color col, MaterialGlobalIlluminationFlags flags) + { + if ((flags & MaterialGlobalIlluminationFlags.BakedEmissive) != 0 && col.maxColorComponent == 0.0f) // flag black baked + flags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack; + else if (flags != MaterialGlobalIlluminationFlags.EmissiveIsBlack) // clear baked flag on everything else, unless it's explicity disabled + flags &= MaterialGlobalIlluminationFlags.AnyEmissive; + return flags; + } + + public void LightmapEmissionFlagsProperty(int indent, bool enabled) + { + LightmapEmissionFlagsProperty(indent, enabled, false); + } + + public void LightmapEmissionFlagsProperty(int indent, bool enabled, bool ignoreEmissionColor) + { + // Calculate isMixed + MaterialGlobalIlluminationFlags any_em = MaterialGlobalIlluminationFlags.AnyEmissive; + MaterialGlobalIlluminationFlags giFlags = ActiveShaderEditor.Materials[0].globalIlluminationFlags & any_em; + bool isMixed = false; + for (int i = 1; i < ActiveShaderEditor.Materials.Length; i++) + { + if ((ActiveShaderEditor.Materials[i].globalIlluminationFlags & any_em) != giFlags) + { + isMixed = true; + break; + } + } + + EditorGUI.BeginChangeCheck(); + + // Show popup + EditorGUI.showMixedValue = isMixed; + giFlags = (MaterialGlobalIlluminationFlags)EditorGUILayout.IntPopup(lightmapEmissiveLabel, (int)giFlags, lightmapEmissiveStrings, lightmapEmissiveValues); + EditorGUI.showMixedValue = false; + + // Apply flags. But only the part that this tool modifies (RealtimeEmissive, BakedEmissive, None) + bool applyFlags = EditorGUI.EndChangeCheck(); + foreach (Material mat in ActiveShaderEditor.Materials) + { + mat.globalIlluminationFlags = applyFlags ? giFlags : mat.globalIlluminationFlags; + if (!ignoreEmissionColor) + { + FixupEmissiveFlag(mat); + } + } + } + } + public class DSGIProperty : ShaderProperty + { + public DSGIProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + } + + public override void DrawDefault() + { + ActiveShaderEditor.Editor.DoubleSidedGIField(); + } + } + public class LocaleProperty : ShaderProperty + { + public LocaleProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, forceOneLine, property_index) + { + _doCustomDrawLogic = true; + IsAnimatable = false; + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + ShaderEditor.Active.Locale.DrawDropdown(rect.Value); + } + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs.meta new file mode 100644 index 00000000..c15763e5 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/OtherShaderProperties.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8a62d1ae1883bb74e93bfde3d4b2d98f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs new file mode 100644 index 00000000..17ab1510 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderGroup : ShaderPart + { + public List parts = new List(); + protected bool _isExpanded; + + public ShaderGroup(ShaderEditor shaderEditor) : base(null, 0, "", null, shaderEditor) + { + + } + + public ShaderGroup(ShaderEditor shaderEditor, string optionsRaw) : base(null, 0, "", null, shaderEditor) + { + this._optionsRaw = optionsRaw; + } + + public ShaderGroup(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, xOffset, displayName, optionsRaw, propertyIndex) + { + + } + + protected override void InitOptions() + { + base.InitOptions(); + if (Options.persistent_expand) _isExpanded = this.MaterialProperty.GetNumber() == 1; + else _isExpanded = Options.default_expand; + } + + protected bool IsExpanded + { + get + { + return _isExpanded; + } + set + { + if (Options.persistent_expand) + { + if (AnimationMode.InAnimationMode()) + { + + +#if UNITY_2020_1_OR_NEWER + // So we do this instead + _isExpanded = value; +#else + // This fails when unselecting the object in hirearchy + // Then reselecting it + // Don't know why + // It seems AnimationMode is not working properly in Unity 2022 + // It worked fine in Unity 2019 + + AnimationMode.StopAnimationMode(); + this.MaterialProperty.SetNumber(value ? 1 : 0); + AnimationMode.StartAnimationMode(); +#endif + } + else + { + this.MaterialProperty.SetNumber(value ? 1 : 0); + } + } + _isExpanded = value; + } + } + + protected bool DoDisableChildren + { + get + { + return Options.condition_enable_children != null && !Options.condition_enable_children.Test(); + } + } + + public void addPart(ShaderPart part) + { + parts.Add(part); + } + + public override void CopyFromMaterial(Material m, bool isTopCall = false) + { + if (Options.reference_property != null) + ActiveShaderEditor.PropertyDictionary[Options.reference_property].CopyFromMaterial(m); + foreach (ShaderPart p in parts) + p.CopyFromMaterial(m); + if (isTopCall) ActiveShaderEditor.ApplyDrawers(); + } + + public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + if (ShouldSkipProperty(MaterialProperty, skipPropertyTypes)) return; + + if (Options.reference_property != null) + ActiveShaderEditor.PropertyDictionary[Options.reference_property].CopyToMaterial(m); + foreach (ShaderPart p in parts) + { + if (!ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) + p.CopyToMaterial(m); + } + if (isTopCall) MaterialEditor.ApplyMaterialPropertyDrawers(m); + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + if (Options.margin_top > 0) + { + GUILayoutUtility.GetRect(0, Options.margin_top); + } + foreach (ShaderPart part in parts) + { + part.Draw(); + } + } + + public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] propertyTypesToSkip = null) + { + if (ShouldSkipProperty(MaterialProperty, propertyTypesToSkip)) return; + if (p is ShaderGroup == false) return; + ShaderGroup group = p as ShaderGroup; + if (Options.reference_property != null && group.Options.reference_property != null) + ActiveShaderEditor.PropertyDictionary[Options.reference_property].TransferFromMaterialAndGroup(m, group.ActiveShaderEditor.PropertyDictionary[group.Options.reference_property]); + for (int i = 0; i < group.parts.Count && i < parts.Count; i++) + { + if (!ShouldSkipProperty(parts[i].MaterialProperty, propertyTypesToSkip)) + parts[i].TransferFromMaterialAndGroup(m, group.parts[i]); + } + if (isTopCall) ActiveShaderEditor.ApplyDrawers(); + } + + public override void FindUnusedTextures(List unusedList, bool isEnabled) + { + if (isEnabled && Options.condition_enable != null) + { + isEnabled &= Options.condition_enable.Test(); + } + foreach (ShaderPart p in (this as ShaderGroup).parts) + p.FindUnusedTextures(unusedList, isEnabled); + } + + protected void HandleLinkedMaterials() + { + List linked_materials = MaterialLinker.GetLinked(MaterialProperty); + if (linked_materials != null) + foreach (Material m in linked_materials) + this.CopyToMaterial(m); + } + + protected void FoldoutArrow(Rect rect, Event e) + { + if (e.type == EventType.Repaint) + { + Rect arrowRect = new RectOffset(4, 0, 0, 0).Remove(rect); + arrowRect.width = 13; + EditorStyles.foldout.Draw(arrowRect, false, false, _isExpanded, false); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs.meta new file mode 100644 index 00000000..9e72b8e3 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderGroup.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4fba5d6078a22db4faae64b09eb83826 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs new file mode 100644 index 00000000..459e97df --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderHeader : ShaderGroup + { + + public ShaderHeader(ShaderEditor shaderEditor) : base(shaderEditor) + { + } + + public ShaderHeader(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, materialEditor, displayName, xOffset, optionsRaw, propertyIndex) + { + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + ActiveShaderEditor.CurrentProperty = this; + EditorGUI.BeginChangeCheck(); + Rect position = GUILayoutUtility.GetRect(content, Styles.dropDownHeader); + DrawHeader(position, content); + Rect headerRect = DrawingData.LastGuiObjectHeaderRect; + if (IsExpanded) + { + if (ShaderEditor.Active.IsSectionedPresetEditor) + { + string presetName = Presets.GetSectionPresetName(ShaderEditor.Active.Materials[0], this.MaterialProperty.name); + EditorGUI.BeginChangeCheck(); + presetName = EditorGUILayout.DelayedTextField("Preset Name:", presetName); + if (EditorGUI.EndChangeCheck()) + { + Presets.SetSectionPreset(ShaderEditor.Active.Materials[0], this.MaterialProperty.name, presetName); + } + } + + EditorGUILayout.Space(); + EditorGUI.BeginDisabledGroup(DoDisableChildren); + foreach (ShaderPart part in parts) + { + part.Draw(); + } + EditorGUI.EndDisabledGroup(); + EditorGUILayout.Space(); + } + if (EditorGUI.EndChangeCheck()) + HandleLinkedMaterials(); + DrawingData.LastGuiObjectHeaderRect = headerRect; + DrawingData.LastGuiObjectRect = headerRect; + } + + private void DrawHeader(Rect position, GUIContent label) + { + PropertyOptions options = ShaderEditor.Active.CurrentProperty.Options; + Event e = Event.current; + + int xOffset_total = XOffset * 15 + 15; + + position.width -= xOffset_total - position.x; + position.x = xOffset_total; + + DrawingData.LastGuiObjectHeaderRect = position; + DrawBoxAndContent(position, e, label, options); + + Rect arrowRect = new Rect(position) { height = 18 }; + FoldoutArrow(arrowRect, e); + + HandleToggleInput(position); + } + + private void DrawBoxAndContent(Rect rect, Event e, GUIContent content, PropertyOptions options) + { + if (options.reference_property != null && ShaderEditor.Active.PropertyDictionary.ContainsKey(options.reference_property)) + { + GUI.Box(rect, new GUIContent(" " + content.text, content.tooltip), Styles.dropDownHeader); + DrawIcons(rect, options, e); + + Rect togglePropertyRect = new Rect(rect); + togglePropertyRect.x += 5; + togglePropertyRect.y += 1; + togglePropertyRect.height -= 4; + togglePropertyRect.width = GUI.skin.font.fontSize * 3; + float fieldWidth = EditorGUIUtility.fieldWidth; + EditorGUIUtility.fieldWidth = 20; + ShaderProperty refProperty = ShaderEditor.Active.PropertyDictionary[options.reference_property]; + + EditorGUI.BeginChangeCheck(); + + int xOffset = refProperty.XOffset; + refProperty.SetTemporaryXOffset(0); + refProperty.Draw(togglePropertyRect, new GUIContent(), isInHeader: true); + refProperty.ResetTemporaryXOffset(); + EditorGUIUtility.fieldWidth = fieldWidth; + + // Change expand state if reference is toggled + if (EditorGUI.EndChangeCheck() && Options.ref_float_toggles_expand) + { + IsExpanded = refProperty.MaterialProperty.GetNumber() == 1; + } + } + // else if(keyword != null) + // { + // GUI.Box(rect, " " + content.text, Styles.dropDownHeader); + // DrawIcons(rect, options, e); + + // Rect togglePropertyRect = new Rect(rect); + // togglePropertyRect.x += 20; + // togglePropertyRect.width = 20; + + // EditorGUI.BeginChangeCheck(); + // bool keywordOn = EditorGUI.Toggle(togglePropertyRect, "", ShaderEditor.Active.Materials[0].IsKeywordEnabled(keyword)); + // if (EditorGUI.EndChangeCheck()) + // { + // MaterialHelper.ToggleKeyword(ShaderEditor.Active.Materials, keyword, keywordOn); + // } + // } + else + { + GUI.Box(rect, content, Styles.dropDownHeader); + DrawIcons(rect, options, e); + } + + } + + /// + /// Draws the icons for ShaderEditor features like linking and copying + /// + /// + /// + private void DrawIcons(Rect rect, PropertyOptions options, Event e) + { + Rect buttonRect = new Rect(rect); + buttonRect.y += 1; + buttonRect.height -= 4; + buttonRect.width = buttonRect.height; + + float right = rect.x + rect.width; + buttonRect.x = right - 74; + DrawPresetButton(buttonRect, options, e); + buttonRect.x = right - 56; + DrawHelpButton(buttonRect, options, e); + buttonRect.x = right - 38; + DrawLinkSettings(buttonRect, e); + buttonRect.x = right - 20; + DrawDowdownSettings(buttonRect, e); + } + + private void DrawHelpButton(Rect rect, PropertyOptions options, Event e) + { + ButtonData button = options.button_help; + if (button != null && button.condition_show.Test()) + { + if (GUILib.Button(rect, Styles.icon_style_help)) + { + ShaderEditor.Input.Use(); + if (button.action != null) button.action.Perform(ShaderEditor.Active?.Materials); + } + } + } + + private void DrawPresetButton(Rect rect, PropertyOptions options, Event e) + { + bool hasPresets = Presets.DoesSectionHavePresets(this.MaterialProperty.name); + if (hasPresets) + { + if (GUILib.Button(rect, Styles.icon_style_presets)) + { + ShaderEditor.Input.Use(); + Presets.OpenPresetsMenu(rect, ActiveShaderEditor, true, this.MaterialProperty.name); + } + } + } + + private void DrawDowdownSettings(Rect rect, Event e) + { + if (GUILib.Button(rect, Styles.icon_style_menu)) + { + ShaderEditor.Input.Use(); + Rect buttonRect = new Rect(rect); + buttonRect.width = 150; + buttonRect.x = Mathf.Min(Screen.width - buttonRect.width, buttonRect.x); + buttonRect.height = 60; + float maxY = GUIUtility.ScreenToGUIPoint(new Vector2(0, EditorWindow.focusedWindow.position.y + Screen.height)).y - 2.5f * buttonRect.height; + buttonRect.y = Mathf.Min(buttonRect.y - buttonRect.height / 2, maxY); + + ShowHeaderContextMenu(buttonRect, ShaderEditor.Active.CurrentProperty, ShaderEditor.Active.Materials[0]); + } + } + + private void DrawLinkSettings(Rect rect, Event e) + { + if (GUILib.Button(rect, Styles.icon_style_linked, Styles.COLOR_ICON_ACTIVE_CYAN, MaterialLinker.IsLinked(ShaderEditor.Active.CurrentProperty.MaterialProperty))) + { + ShaderEditor.Input.Use(); + List linked_materials = MaterialLinker.GetLinked(ShaderEditor.Active.CurrentProperty.MaterialProperty); + MaterialLinker.Popup(rect, linked_materials, ShaderEditor.Active.CurrentProperty.MaterialProperty); + } + } + + void ShowHeaderContextMenu(Rect position, ShaderPart property, Material material) + { + var menu = new GenericMenu(); + menu.AddItem(new GUIContent("Reset"), false, delegate () + { + property.CopyFromMaterial(new Material(material.shader), true); + List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); + if (linked_materials != null) + foreach (Material m in linked_materials) + property.CopyToMaterial(m, true); + }); + menu.AddItem(new GUIContent("Copy"), false, delegate () + { + Mediator.copy_material = new Material(material); + Mediator.transfer_group = property; + }); + menu.AddItem(new GUIContent("Paste"), false, delegate () + { + if (Mediator.copy_material != null || Mediator.transfer_group != null) + { + property.TransferFromMaterialAndGroup(Mediator.copy_material, Mediator.transfer_group, true); + List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); + if (linked_materials != null) + foreach (Material m in linked_materials) + property.CopyToMaterial(m, true); + } + }); + menu.AddItem(new GUIContent("Paste without Textures"), false, delegate () + { + if (Mediator.copy_material != null || Mediator.transfer_group != null) + { + var propsToIgnore = new MaterialProperty.PropType[] { MaterialProperty.PropType.Texture }; + property.TransferFromMaterialAndGroup(Mediator.copy_material, Mediator.transfer_group, true, propsToIgnore); + List linked_materials = MaterialLinker.GetLinked(property.MaterialProperty); + if (linked_materials != null) + foreach (Material m in linked_materials) + property.CopyToMaterial(m, true, propsToIgnore); + } + }); + menu.DropDown(position); + } + + private void HandleToggleInput(Rect rect) + { + //Ignore unity uses is cause disabled will use the event to prevent toggling + if (ShaderEditor.Input.LeftClick_IgnoreLocked && rect.Contains(ShaderEditor.Input.mouse_position) && !ShaderEditor.Input.is_alt_down) + { + IsExpanded = !IsExpanded; + ShaderEditor.Input.Use(); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs.meta new file mode 100644 index 00000000..bc09d31d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4067467ca7fad4d4090638c20b2412ab +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs new file mode 100644 index 00000000..693f98bf --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderHeaderProperty : ShaderPart + { + public ShaderHeaderProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int propertyIndex) : base(shaderEditor, materialProperty, xOffset, displayName, optionsRaw, propertyIndex) + { + // guid is defined as + if (displayName.Contains("", start); + string guid = displayName.Substring(start + 6, end - start - 6); + string path = AssetDatabase.GUIDToAssetPath(guid); + string replacement = ""; + if (path != null && System.IO.File.Exists(path)) + { + replacement = System.IO.File.ReadAllText(path); + } + Content.text = displayName.Replace($"", replacement); + } + } + + public override void HandleRightClickToggles(bool isInHeader) + { + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + if (rect == null) + { + if (Options.texture != null && Options.texture.name != null) + { + //is texutre draw + content = new GUIContent(Options.texture.loaded_texture, content.tooltip); + int height = Options.texture.height; + int width = (int)((float)Options.texture.loaded_texture.width / Options.texture.loaded_texture.height * height); + Rect control = EditorGUILayout.GetControlRect(false, height - 18); + Rect r = new Rect((control.width - width) / 2, control.y, width, height); + GUI.DrawTexture(r, Options.texture.loaded_texture); + } + } + else + { + //is text draw + EditorGUI.LabelField(rect.Value, "" + this.Content.text + "", Styles.masterLabel); + DrawingData.LastGuiObjectRect = rect.Value; + } + } + + public override void CopyFromMaterial(Material m, bool isTopCall = false) + { + throw new System.NotImplementedException(); + } + + public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + throw new System.NotImplementedException(); + } + + public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + throw new System.NotImplementedException(); + } + + public override void FindUnusedTextures(List unusedList, bool isEnabled) + { + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs.meta new file mode 100644 index 00000000..ae195355 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderHeaderProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25056b675251a9743bd327cdfada3326 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs new file mode 100644 index 00000000..a0334c58 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs @@ -0,0 +1,868 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class InputEvent + { + public bool HadMouseDownRepaint; + public bool HadMouseDown; + int _button; + bool _MouseClick; + bool _MouseLeftClickIgnoreLocked; + bool _MouseRightClickIgnoreLocked; + bool _MouseLeftClick; + bool _MouseRightClick; + + public bool is_alt_down; + + public bool is_drag_drop_event; + public bool is_drop_event; + + public Vector2 mouse_position; + public Vector2 screen_mouse_position; + + public EventType OriginalEventType; + + public void Update(bool isLockedMaterial) + { + Event e = Event.current; + _button = e.button; + _MouseClick = e.type == EventType.MouseDown && !isLockedMaterial; + _MouseLeftClick = _MouseClick && _button == 0; + _MouseRightClick = _MouseClick && _button == 1; + _MouseLeftClickIgnoreLocked = e.type == EventType.MouseDown && _button == 0; + _MouseRightClickIgnoreLocked = e.type == EventType.MouseDown && _button == 1; + if (_MouseClick) HadMouseDown = _MouseClick; + if (HadMouseDown && e.type == EventType.Repaint) + { + HadMouseDownRepaint = true; + HadMouseDown = false; + } + is_alt_down = e.alt; + mouse_position = e.mousePosition; + screen_mouse_position = GUIUtility.GUIToScreenPoint(e.mousePosition); + is_drop_event = e.type == EventType.DragPerform; + is_drag_drop_event = is_drop_event || e.type == EventType.DragUpdated; + OriginalEventType = e.type; + } + + public void Use() + { + _MouseClick = false; + _MouseLeftClick = false; + _MouseRightClick = false; + Event.current.Use(); + } + + // This is cursed. I need to look over this whole system at some point + public void PowerUse() + { + Use(); + _MouseRightClickIgnoreLocked = false; + _MouseLeftClickIgnoreLocked = false; + } + + public bool LeftClick_IgnoreLocked + { + get { return _MouseLeftClickIgnoreLocked && Event.current.type != EventType.Used; } + } + + public bool RightClick_IgnoreLocked + { + get { return _MouseRightClickIgnoreLocked && Event.current.type != EventType.Used; } + } + + public bool LeftClick_IgnoreLockedAndUnityUses + { + get { return _MouseLeftClickIgnoreLocked; } + } + + public bool RightClick_IgnoreLockedAndUnityUses + { + get { return _MouseRightClickIgnoreLocked; } + } + + public bool Click + { + get { return _MouseClick && Event.current.type != EventType.Used; } + } + } + + public abstract class ShaderPart + { + public ShaderEditor ActiveShaderEditor { protected set; get; } + public MaterialProperty MaterialProperty { private set; get; } + + public GUIContent Content { protected set; get; } + public BetterTooltips.Tooltip Tooltip { protected set; get; } + public System.Object PropertyData { protected set; get; } = null; + + public string PropertyIdentifier { protected set; get; } + public string CustomStringTagID { protected set; get; } = null; + + public bool IsHidden { protected set; get; } = false; + public bool IsPreset { protected set; get; } = false; + + public bool IsExemptFromLockedDisabling { protected set; get; } = false; + public bool IsAnimatable { protected set; get; } = true; + public bool IsAnimated { protected set; get; } = false; + public bool IsRenaming { protected set; get; } = false; + + + + public bool DoReferencePropertiesExist { protected set; get; } = false; + public bool DoesReferencePropertyExist { protected set; get; } = false; + + public int ShaderPropertyId { protected set; get; } = -1; + public int ShaderPropertyIndex { protected set; get; } = -1; + + + public bool has_not_searchedFor = false; //used for property search + + GenericMenu _contextMenu; + + protected string _optionsRaw; + private bool _doOptionsNeedInitilization = true; + + private PropertyOptions _options; + public PropertyOptions Options + { + get + { + if (_options == null) + { + _options = PropertyOptions.Deserialize(_optionsRaw); + } + return _options; + } + } + + private int _xoffset = 0; + private int _tempXOffset = -1; + public int XOffset + { + protected set + { + _xoffset = value; + } + get + { + if (_tempXOffset != -1) return _tempXOffset; + return _xoffset; + } + } + + public void SetTemporaryXOffset(int value) + { + _tempXOffset = value; + } + + public void ResetTemporaryXOffset() + { + _tempXOffset = -1; + } + + public void SetIsExemptFromLockedDisabling(bool b) + { + IsExemptFromLockedDisabling = b; + } + + + public ShaderPart(string propertyIdentifier, int xOffset, string displayName, string tooltip, ShaderEditor shaderEditor) + { + this._optionsRaw = null; + this.ActiveShaderEditor = shaderEditor; + this.PropertyIdentifier = propertyIdentifier; + this.XOffset = xOffset; + this.Content = new GUIContent(displayName); + this.Tooltip = new BetterTooltips.Tooltip(tooltip); + this.IsPreset = shaderEditor.IsPresetEditor && Presets.IsPreset(shaderEditor.Materials[0], this); + } + + public ShaderPart(ShaderEditor shaderEditor, MaterialProperty prop, int xOffset, string displayName, string optionsRaw, int propertyIndex) + { + this._optionsRaw = optionsRaw; + this.ActiveShaderEditor = shaderEditor; + this.MaterialProperty = prop; + this.XOffset = xOffset; + this.Content = new GUIContent(displayName); + this.IsPreset = shaderEditor.IsPresetEditor && Presets.IsPreset(shaderEditor.Materials[0], this); + + if (MaterialProperty == null) + return; + + this.ShaderPropertyId = Shader.PropertyToID(MaterialProperty.name); + this.ShaderPropertyIndex = propertyIndex; + + // Do parse options & check for alternative names if shader swap + if (ShaderEditor.Active.DidSwapToNewShader) + { + if (Options.alts != null && Options.alts.Length > 0) + CopyAlternativeUpgradeValues(); + } + + this.IsExemptFromLockedDisabling |= ShaderOptimizer.IsPropertyExcemptFromLocking(prop); + } + + protected void UpdatedMaterialPropertyReference() + { + this.MaterialProperty = ActiveShaderEditor.Properties[ShaderPropertyIndex]; + } + + private void CopyAlternativeUpgradeValues() + { + MaterialProperty.PropType type = this.MaterialProperty.type; + if (type == MaterialProperty.PropType.Color) type = MaterialProperty.PropType.Vector; + if (type == MaterialProperty.PropType.Range) type = MaterialProperty.PropType.Float; + + int index = ShaderEditor.Active.Shader.FindPropertyIndex(this.MaterialProperty.name); + + object defaultValue = null; + if (type == MaterialProperty.PropType.Float) + defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultFloatValue(index); +#if UNITY_2022_1_OR_NEWER + else if (type == MaterialProperty.PropType.Int) + defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultIntValue(index); +#endif + else if (type == MaterialProperty.PropType.Vector) + defaultValue = ShaderEditor.Active.Shader.GetPropertyDefaultVectorValue(index); + else if (type == MaterialProperty.PropType.Texture) + defaultValue = ShaderEditor.Active.Shader.GetPropertyTextureDefaultName(index); + + foreach (Material m in ShaderEditor.Active.Materials) + { + // Check if is not default value + if (type == MaterialProperty.PropType.Float) + { + if (m.GetNumber(this.MaterialProperty) != (float)defaultValue) + continue; + } +#if UNITY_2022_1_OR_NEWER + else if (type == MaterialProperty.PropType.Int) + { + if (m.GetInt(this.MaterialProperty.name) != (int)defaultValue) + continue; + } +#endif + else if (type == MaterialProperty.PropType.Vector) + { + if (m.GetVector(this.MaterialProperty.name) != (Vector4)defaultValue) + continue; + } + else if (type == MaterialProperty.PropType.Texture) + { + if (m.GetTexture(this.MaterialProperty.name) != null && + m.GetTexture(this.MaterialProperty.name).name != (string)defaultValue) + continue; + } + + // Material as serializedObject + SerializedObject serializedObject = new SerializedObject(m); + foreach (string alt in Options.alts) + { + SerializedProperty arrayProp = null; + if (type == MaterialProperty.PropType.Float) + arrayProp = serializedObject.FindProperty("m_SavedProperties.m_Floats.Array"); +#if UNITY_2022_1_OR_NEWER + else if (type == MaterialProperty.PropType.Int) + arrayProp = serializedObject.FindProperty("m_SavedProperties.m_Ints.Array"); +#endif + else if (type == MaterialProperty.PropType.Vector) + arrayProp = serializedObject.FindProperty($"m_SavedProperties.m_Colors.Array"); + else if (type == MaterialProperty.PropType.Texture) + arrayProp = serializedObject.FindProperty($"m_SavedProperties.m_TexEnvs.Array"); + + if (arrayProp == null) + continue; + + // Iterate through properties in prop array, find where .first is alt + SerializedProperty valueProp = null; + for (int i = 0; i < arrayProp.arraySize; i++) + { + SerializedProperty keyProp = arrayProp.GetArrayElementAtIndex(i); + if (keyProp.FindPropertyRelative("first").stringValue == alt) + { + valueProp = keyProp.FindPropertyRelative("second"); + break; + } + } + + if (valueProp == null) + continue; + + if (type == MaterialProperty.PropType.Float) + this.MaterialProperty.floatValue = valueProp.floatValue; +#if UNITY_2022_1_OR_NEWER + else if (type == MaterialProperty.PropType.Int) + this.MaterialProperty.intValue = valueProp.intValue; +#endif + else if (type == MaterialProperty.PropType.Vector) + this.MaterialProperty.colorValue = valueProp.colorValue; + else if (type == MaterialProperty.PropType.Texture) + { + var texProperty = valueProp.FindPropertyRelative("m_Texture").objectReferenceValue as Texture; + var scaleProperty = valueProp.FindPropertyRelative("m_Scale").vector2Value; + var offsetProperty = valueProp.FindPropertyRelative("m_Offset").vector2Value; + + this.MaterialProperty.textureValue = texProperty; + this.MaterialProperty.textureScaleAndOffset = new Vector4(scaleProperty.x, scaleProperty.y, offsetProperty.x, offsetProperty.y); + } + } + } + } + + protected virtual void InitOptions() + { + this.Tooltip = new BetterTooltips.Tooltip(Options.tooltip); + this.DoReferencePropertiesExist = Options.reference_properties != null && Options.reference_properties.Length > 0; + this.DoesReferencePropertyExist = Options.reference_property != null; + this.XOffset += Options.offset; + } + + public void SetReferenceProperty(string s) + { + Options.reference_property = s; + this.DoesReferencePropertyExist = Options.reference_property != null; + } + + public void SetReferenceProperties(string[] properties) + { + Options.reference_properties = properties; + this.DoReferencePropertiesExist = Options.reference_properties != null && Options.reference_properties.Length > 0; + } + + public void SetTooltip(string tooltip) + { + this.Tooltip.SetText(tooltip); + } + + public abstract void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false); + public abstract void CopyFromMaterial(Material m, bool isTopCall = false); + public abstract void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null); + + protected void CopyReferencePropertiesToMaterial(Material target) + { + if (Options.reference_properties != null) + foreach (string r_property in Options.reference_properties) + { + ShaderProperty property = ActiveShaderEditor.PropertyDictionary[r_property]; + MaterialHelper.CopyPropertyValueToMaterial(property.MaterialProperty, target); + } + if (string.IsNullOrWhiteSpace(Options.reference_property) == false) + { + ShaderProperty property = ActiveShaderEditor.PropertyDictionary[Options.reference_property]; + MaterialHelper.CopyPropertyValueToMaterial(property.MaterialProperty, target); + } + } + + protected void CopyReferencePropertiesFromMaterial(Material source) + { + if (Options.reference_properties != null) + foreach (string r_property in Options.reference_properties) + { + ShaderProperty property = ActiveShaderEditor.PropertyDictionary[r_property]; + MaterialHelper.CopyPropertyValueFromMaterial(property.MaterialProperty, source); + } + if (string.IsNullOrWhiteSpace(Options.reference_property) == false) + { + ShaderProperty property = ActiveShaderEditor.PropertyDictionary[Options.reference_property]; + MaterialHelper.CopyPropertyValueFromMaterial(property.MaterialProperty, source); + } + } + + public abstract void TransferFromMaterialAndGroup(Material m, ShaderPart g, bool isTopCall = false, MaterialProperty.PropType[] propertyTypesToSkip = null); + + bool hasAddedDisabledGroup = false; + public void Draw(Rect? rect = null, GUIContent content = null, bool useEditorIndent = false, bool isInHeader = false) + { + if (_doOptionsNeedInitilization) + { + InitOptions(); + _doOptionsNeedInitilization = false; + } + + if (has_not_searchedFor) + return; + if (DrawingData.IsEnabled && Options.condition_enable != null) + { + hasAddedDisabledGroup = !Options.condition_enable.Test(); + } + if (hasAddedDisabledGroup) + { + DrawingData.IsEnabled = !hasAddedDisabledGroup; + EditorGUI.BeginDisabledGroup(true); + } + + if (Options.condition_show.Test()) + { + PerformDraw(content, rect, useEditorIndent, isInHeader); + } + if (hasAddedDisabledGroup) + { + hasAddedDisabledGroup = false; + DrawingData.IsEnabled = true; + EditorGUI.EndDisabledGroup(); + } + } + + public virtual void HandleRightClickToggles(bool isInHeader) + { + if (this is ShaderGroup) return; + if (DrawingData.TooltipCheckRect.y < 25) return; // Happens in Layout event, with some dynamic properties + if (ShaderEditor.Input.RightClick_IgnoreLockedAndUnityUses && ShaderEditor.Input.OriginalEventType != EventType.Layout && DrawingData.TooltipCheckRect.Contains(Event.current.mousePosition)) + { + Event.current.Use(); + //Context menu + //Show context menu, if not open. + //If locked material only show menu for animated materials. Only show data retieving options in locked state + if (!ShaderEditor.Active.IsLockedMaterial || IsAnimated) + { + _contextMenu = new GenericMenu(); + if (IsAnimatable && !ShaderEditor.Active.IsLockedMaterial) + { + _contextMenu.AddItem(new GUIContent("Animated (when locked)"), IsAnimated, () => { SetAnimated(!IsAnimated, false); }); + _contextMenu.AddItem(new GUIContent("Renamed (when locked)"), IsAnimated && IsRenaming, () => { SetAnimated(true, !IsRenaming); }); + _contextMenu.AddItem(new GUIContent("Locking Explanation"), false, () => { Application.OpenURL("https://www.youtube.com/watch?v=asWeDJb5LAo&ab_channel=poiyomi"); }); + _contextMenu.AddSeparator(""); + } + if (ShaderEditor.Active.IsPresetEditor) + { + _contextMenu.AddItem(new GUIContent("Is part of preset"), IsPreset, ToggleIsPreset); + _contextMenu.AddSeparator(""); + } + _contextMenu.AddItem(new GUIContent("Copy Property Name"), false, () => { EditorGUIUtility.systemCopyBuffer = MaterialProperty.name; }); + _contextMenu.AddItem(new GUIContent("Copy Animated Property Name"), false, () => { EditorGUIUtility.systemCopyBuffer = GetAnimatedPropertyName(); }); + _contextMenu.AddItem(new GUIContent("Copy Animated Property Path"), false, CopyPropertyPath); + _contextMenu.AddItem(new GUIContent("Copy Property as Keyframe"), false, CopyPropertyAsKeyframe); +#if UNITY_2022_1_OR_NEWER + bool isLockedInChildren = false; + bool isLockedByAncestor = false; + bool isOverriden = true; + foreach (Material target in ShaderEditor.Active.Materials) + { + if (target == null) continue; + int nameId = Shader.PropertyToID(MaterialProperty.name); + isLockedInChildren |= target.IsPropertyLocked(nameId); + isLockedByAncestor |= target.IsPropertyLockedByAncestor(nameId); + isOverriden &= target.IsPropertyOverriden(nameId); + } + DoVariantMenuStuff(_contextMenu, isOverriden, isLockedByAncestor, isLockedInChildren, ShaderEditor.Active.Materials, true); +#endif + _contextMenu.ShowAsContext(); + } + } + } + +#if UNITY_2022_1_OR_NEWER + // static Type s_PropertyData = typeof(MaterialProperty).GetNestedType("PropertyData", BindingFlags.NonPublic); + // static MethodInfo s_HandleApplyRevert = s_PropertyData.GetMethod("HandleApplyRevert", BindingFlags.NonPublic | BindingFlags.Static); + + void DoVariantMenuStuff(GenericMenu menu, bool overriden, bool lockedByAncestor, bool isLockedInChildren, Material[] targets, bool allowLocking) + { + if (lockedByAncestor) + { + if (targets.Length != 1) + return; + + _contextMenu.AddSeparator(""); + menu.AddItem(Styles.lockOriginContent, false, () => GotoLockOriginAction(targets)); + } + else if (GUI.enabled) + { + DoRegularMenu(menu, overriden, targets); + DoLockPropertiesMenu(_contextMenu, !isLockedInChildren, ShaderEditor.Active.Materials, true); + } + } + + void DoRegularMenu(GenericMenu menu, bool isOverriden, Material[] targets) + { + var singleEditing = targets.Length == 1; + + if (isOverriden) + { + _contextMenu.AddSeparator(""); + HandleApplyRevert(menu, singleEditing, targets); + } + + DisplayMode displayMode = GetDisplayMode(targets); + if (displayMode == DisplayMode.Material) + { + menu.AddSeparator(""); + menu.AddItem(Styles.resetContent, false, ResetMaterialProperties); + } + else if (displayMode == DisplayMode.Variant) + HandleRevertAll(menu, singleEditing, targets); + } + + enum DisplayMode { Material, Variant, Mixed }; + static DisplayMode GetDisplayMode(Material[] targets) + { + int variantCount = GetVariantCount(targets); + if (variantCount == 0) + return DisplayMode.Material; + if (variantCount == targets.Length) + return DisplayMode.Variant; + return DisplayMode.Mixed; + } + + static int GetVariantCount(Material[] targets) + { + int count = 0; + foreach (Material target in targets) + count += target.isVariant ? 1 : 0; + return count; + } + + void DoLockPropertiesMenu(GenericMenu menu, bool lockValue, Material[] targets, bool allowLocking) + { + if (menu.GetItemCount() != 0) + menu.AddSeparator(""); + + if (allowLocking) + { + menu.AddItem(Styles.lockContent, !lockValue, () => { SetLockedProperty(targets, lockValue); }); + } + else + { + menu.AddDisabledItem(Styles.lockContent); + } + } + + void SetLockedProperty(Material[] targets, bool value) + { + foreach (Material target in targets) + { + target.SetPropertyLock(ShaderPropertyId, value); + } + } + + void GotoLockOriginAction(Material[] targets) + { + Material origin = targets[0] as Material; + while (origin = origin.parent) + { + if (origin.IsPropertyLocked(ShaderPropertyId)) + break; + } + + if (origin) + { + EditorGUIUtility.PingObject(origin); + } + } + + void HandleApplyRevert(GenericMenu menu, bool singleEditing, Material[] targets) + { + // Apply + if (singleEditing) + { + Material source = (Material)targets[0]; + Material destination = (Material)targets[0]; + while (destination = destination.parent as Material) + { + if (AssetDatabase.IsForeignAsset(destination)) + continue; + + var text = destination.isVariant ? Styles.applyToVariantText : Styles.applyToMaterialText; + var applyContent = new GUIContent(string.Format(text, destination.name)); + + menu.AddItem(applyContent, false, (object dest) => + { + source.ApplyPropertyOverride((Material)dest, ShaderPropertyId); + }, destination); + } + } + + // Revert + var content = singleEditing ? Styles.revertContent : + new GUIContent(string.Format(Styles.revertMultiText, targets.Length)); + menu.AddItem(content, false, () => + { + string displayName = MaterialProperty.displayName; + string targetName = singleEditing ? targets[0].name : targets.Length + " Materials"; + Undo.RecordObjects(targets, "Revert " + displayName + " of " + targetName); + + foreach (Material target in targets) + { + target.RevertPropertyOverride(ShaderPropertyId); + } + }); + } + + void HandleRevertAll(GenericMenu menu, bool singleEditing, Material[] targets) + { + foreach (Material target in targets) + { + if (target.isVariant) + { + menu.AddSeparator(""); + + menu.AddItem(Styles.revertAllContent, false, () => + { + string targetName = singleEditing ? targets[0].name : targets.Length + " Materials"; + Undo.RecordObjects(targets, "Revert all overrides of " + targetName); + + foreach (Material target in targets) + target.RevertAllPropertyOverrides(); + }); + break; + } + } + } + + void ResetMaterialProperties() + { + MaterialProperty prop = MaterialProperty; + Shader shader = ShaderEditor.Active.Shader; + switch (prop.type) + { + case MaterialProperty.PropType.Float: + case MaterialProperty.PropType.Range: + prop.floatValue = shader.GetPropertyDefaultFloatValue(ShaderPropertyIndex); + break; + case MaterialProperty.PropType.Vector: + prop.vectorValue = shader.GetPropertyDefaultVectorValue(ShaderPropertyIndex); + break; + case MaterialProperty.PropType.Color: + prop.colorValue = shader.GetPropertyDefaultVectorValue(ShaderPropertyIndex); + break; + case MaterialProperty.PropType.Int: + prop.intValue = shader.GetPropertyDefaultIntValue(ShaderPropertyIndex); + break; + case MaterialProperty.PropType.Texture: + Texture texture = null; + var importer = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(shader)) as ShaderImporter; + if (importer != null) + texture = importer.GetDefaultTexture(prop.name); + prop.textureValue = texture; + prop.textureScaleAndOffset = new Vector4(1, 1, 0, 0); + break; + } + } +#endif + + void ToggleIsPreset() + { + IsPreset = !IsPreset; + if (MaterialProperty != null) Presets.SetProperty(ActiveShaderEditor.Materials[0], this, IsPreset); + ShaderEditor.RepaintActive(); + } + + void CopyPropertyPath() + { + string path = GetAnimatedPropertyName(); + Transform selected = Selection.activeTransform; + Transform root = selected; + while (root != null && root.GetComponent() == null) + root = root.parent; + if (selected != null && root != null && selected != root) + path = AnimationUtility.CalculateTransformPath(selected, root) + "/" + path; + EditorGUIUtility.systemCopyBuffer = path; + } + + string GetAnimatedPropertyName() + { + string propName = MaterialProperty.name; + if (IsRenaming && !ShaderEditor.Active.IsLockedMaterial) propName = propName + "_" + ShaderEditor.Active.RenamedPropertySuffix; + if (MaterialProperty.type == MaterialProperty.PropType.Texture) propName = propName + "_ST"; + return propName; + } + + void CopyPropertyAsKeyframe() + { + string path = ""; + Transform selected = Selection.activeTransform; + Transform root = selected; + while (root != null && root.GetComponent() == null) + root = root.parent; + if (selected != null && root != null && selected != root) + path = AnimationUtility.CalculateTransformPath(selected, root); + if (selected == null && root == null) + return; + + Type rendererType = typeof(Renderer); + if (selected.GetComponent()) rendererType = typeof(SkinnedMeshRenderer); + if (selected.GetComponent()) rendererType = typeof(MeshRenderer); + + Type animationStateType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowState"); + Type animationKeyframeType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowKeyframe"); + Type animationCurveType = typeof(AnimationUtility).Assembly.GetType("UnityEditorInternal.AnimationWindowCurve"); + + FieldInfo clipboardField = animationStateType.GetField("s_KeyframeClipboard", BindingFlags.NonPublic | BindingFlags.Static); + + Type keyframeListType = typeof(List<>).MakeGenericType(animationKeyframeType); + IList keyframeList = (IList)Activator.CreateInstance(keyframeListType); + + AnimationClip clip = new AnimationClip(); + + string propertyname = "material." + GetAnimatedPropertyName(); + if (MaterialProperty.type == MaterialProperty.PropType.Float || MaterialProperty.type == MaterialProperty.PropType.Range) + { + clip.SetCurve(path, rendererType, propertyname, new AnimationCurve(new Keyframe(0, MaterialProperty.floatValue))); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, "", rendererType)); + } +#if UNITY_2022_1_OR_NEWER + else if (MaterialProperty.type == MaterialProperty.PropType.Int) + { + clip.SetCurve(path, rendererType, propertyname, new AnimationCurve(new Keyframe(0, MaterialProperty.intValue))); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, "", rendererType)); + } +#endif + else if (MaterialProperty.type == MaterialProperty.PropType.Color) + { + clip.SetCurve(path, rendererType, propertyname + ".r", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.r))); + clip.SetCurve(path, rendererType, propertyname + ".g", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.g))); + clip.SetCurve(path, rendererType, propertyname + ".b", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.b))); + clip.SetCurve(path, rendererType, propertyname + ".a", new AnimationCurve(new Keyframe(0, MaterialProperty.colorValue.a))); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".r", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".g", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".b", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".a", rendererType)); + } + else if (MaterialProperty.type == MaterialProperty.PropType.Vector) + { + clip.SetCurve(path, rendererType, propertyname + ".x", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.x))); + clip.SetCurve(path, rendererType, propertyname + ".y", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.y))); + clip.SetCurve(path, rendererType, propertyname + ".z", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.z))); + clip.SetCurve(path, rendererType, propertyname + ".w", new AnimationCurve(new Keyframe(0, MaterialProperty.vectorValue.w))); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".x", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".y", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".z", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".w", rendererType)); + } + else if (MaterialProperty.type == MaterialProperty.PropType.Texture) + { + clip.SetCurve(path, rendererType, propertyname + ".x", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.x))); + clip.SetCurve(path, rendererType, propertyname + ".y", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.y))); + clip.SetCurve(path, rendererType, propertyname + ".z", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.z))); + clip.SetCurve(path, rendererType, propertyname + ".w", new AnimationCurve(new Keyframe(0, MaterialProperty.textureScaleAndOffset.w))); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".x", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".y", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".z", rendererType)); + keyframeList.Add(ClipToKeyFrame(animationCurveType, clip, path, ".w", rendererType)); + } + clipboardField.SetValue(null, keyframeList); + } + + object ClipToKeyFrame(Type animationCurveType, AnimationClip clip, string path, string propertyPostFix, Type rendererType) + { + FieldInfo curvesField = animationCurveType.GetField("m_Keyframes", BindingFlags.Instance | BindingFlags.Public); + + object windowCurve = Activator.CreateInstance(animationCurveType, clip, + EditorCurveBinding.FloatCurve(path, rendererType, "material." + GetAnimatedPropertyName() + propertyPostFix), typeof(float)); + IEnumerator enumerator = (curvesField.GetValue(windowCurve) as IList).GetEnumerator(); + enumerator.MoveNext(); + return enumerator.Current; + } + + public void SetAnimated(bool animated, bool renamed) + { + if (IsAnimated == animated && IsRenaming == renamed) return; + IsAnimated = animated; + IsRenaming = renamed; + ShaderOptimizer.SetAnimatedTag(MaterialProperty, IsAnimated ? (IsRenaming ? "2" : "1") : ""); + } + + private void PerformDraw(GUIContent content, Rect? rect, bool useEditorIndent, bool isInHeader = false) + { + if (content == null) + content = this.Content; + EditorGUI.BeginChangeCheck(); + + DrawingData.IconsPositioningCount = 0; + + DrawInternal(content, rect, useEditorIndent, isInHeader); + + if (this is ShaderTextureProperty == false) + { + DrawingData.TooltipCheckRect = DrawingData.LastGuiObjectRect; + if (DrawingData.IconsPositioningCount == 0) + { + DrawingData.IconsPositioningCount = 1; + DrawingData.IconsPositioningHeights[0] = DrawingData.LastGuiObjectRect.y + DrawingData.LastGuiObjectRect.height - 14; + } + } + DrawingData.TooltipCheckRect.width = EditorGUIUtility.labelWidth; + + HandleRightClickToggles(isInHeader); + + if (EditorGUI.EndChangeCheck()) + { + OnPropertyValueChanged(); + ExecuteOnValueActions(ShaderEditor.Active.Materials); + //Check if property is being animated + if (this is ShaderProperty && ActiveShaderEditor.ActiveRenderer != null && ActiveShaderEditor.IsInAnimationMode && IsAnimatable && !IsAnimated) + { + if (MaterialProperty.type == MaterialProperty.PropType.Texture ? + AnimationMode.IsPropertyAnimated(ActiveShaderEditor.ActiveRenderer, "material." + MaterialProperty.name + "_ST.x") : + AnimationMode.IsPropertyAnimated(ActiveShaderEditor.ActiveRenderer, "material." + MaterialProperty.name)) + SetAnimated(true, false); + } + } + + if (IsAnimatable && IsAnimated) DrawLockedAnimated(); + if (IsPreset) DrawPresetProperty(); + + Tooltip.ConditionalDraw(DrawingData.TooltipCheckRect); + + //Click testing + if (Event.current.type == EventType.MouseDown && DrawingData.LastGuiObjectRect.Contains(ShaderEditor.Input.mouse_position)) + { + if ((ShaderEditor.Input.is_alt_down && Options.altClick != null)) Options.altClick.Perform(ShaderEditor.Active.Materials); + else if (Options.onClick != null) Options.onClick.Perform(ShaderEditor.Active.Materials); + } + } + + protected virtual void OnPropertyValueChanged() + { + + } + + private void DrawLockedAnimated() + { + for (int i = 0; i < DrawingData.IconsPositioningCount; i++) + { + Rect r = new Rect(14, DrawingData.IconsPositioningHeights[i], 16, 16); + if (IsRenaming) GUI.Label(r, "RA", Styles.animatedIndicatorStyle); + else GUI.Label(r, "A", Styles.animatedIndicatorStyle); + } + } + + private void DrawPresetProperty() + { + for (int i = 0; i < DrawingData.IconsPositioningCount; i++) + { + Rect r = new Rect(3, DrawingData.IconsPositioningHeights[i], 8, 16); + GUI.Label(r, "P", Styles.presetIndicatorStyle); + } + } + + protected void ExecuteOnValueActions(Material[] targets) + { + if (Options.on_value_actions != null) + foreach (PropertyValueAction action in Options.on_value_actions) + { + action.Execute(MaterialProperty, targets); + } + } + + public abstract void FindUnusedTextures(List unusedList, bool isEnabled); + + protected bool ShouldSkipProperty(MaterialProperty property, MaterialProperty.PropType[] propertyTypesToSkip) + { + if (propertyTypesToSkip != null) + foreach (MaterialProperty.PropType typeToSkip in propertyTypesToSkip) + if (property.type == typeToSkip) + return true; + return false; + } + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs.meta new file mode 100644 index 00000000..fd5cf307 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderPart.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d320d3af2488c134d84ae88c89dcadb4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs new file mode 100644 index 00000000..fc5330d4 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs @@ -0,0 +1,331 @@ +using JetBrains.Annotations; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderProperty : ShaderPart + { + protected bool _doCustomDrawLogic = false; + protected bool _doForceIntoOneLine = false; + protected bool _doDrawTwoFields = false; + + //Done for e.g. Vectors cause they draw in 2 lines for some fucking reasons + public bool DoCustomHeightOffset { protected set; get; } = false; + public float CustomHeightOffset { protected set; get; } = 0; + + public string Keyword { private set; get; } + + protected MaterialPropertyDrawer[] _customDecorators; + protected Rect[] _customDecoratorRects; + protected bool _hasDrawer = false; + + bool _needsDrawerInitlization = true; + + public ShaderProperty(ShaderEditor shaderEditor, string propertyIdentifier, int xOffset, string displayName, string tooltip, int propertyIndex) : base(propertyIdentifier, xOffset, displayName, tooltip, shaderEditor) + { + this.ShaderPropertyIndex = propertyIndex; + } + + public ShaderProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool forceOneLine, int propertyIndex) : base(shaderEditor, materialProperty, xOffset, displayName, optionsRaw, propertyIndex) + { + this._doCustomDrawLogic = false; + this._doForceIntoOneLine = forceOneLine; + } + + protected override void InitOptions() + { + base.InitOptions(); + this._doDrawTwoFields = Options.reference_property != null; + } + + public void SetKeyword(string keyword) + { + this.Keyword = keyword; + } + + [PublicAPI] + public float FloatValue + { + get + { + return MaterialProperty.floatValue; + } + set + { + MaterialProperty.SetNumber(value); + if (Keyword != null) SetKeyword(ShaderEditor.Active.Materials, MaterialProperty.GetNumber() == 1); + ExecuteOnValueActions(ShaderEditor.Active.Materials); + MaterialEditor.ApplyMaterialPropertyDrawers(ShaderEditor.Active.Materials); + } + } + + [PublicAPI] + public Vector4 VectorValue + { + get + { + return MaterialProperty.vectorValue; + } + set + { + MaterialProperty.vectorValue = value; + ExecuteOnValueActions(ShaderEditor.Active.Materials); + MaterialEditor.ApplyMaterialPropertyDrawers(ShaderEditor.Active.Materials); + } + } + + [PublicAPI] + public Color ColorValue + { + get + { + return MaterialProperty.colorValue; + } + set + { + MaterialProperty.colorValue = value; + ExecuteOnValueActions(ShaderEditor.Active.Materials); + MaterialEditor.ApplyMaterialPropertyDrawers(ShaderEditor.Active.Materials); + } + } + + [PublicAPI] + public Texture TextureValue + { + get + { + return MaterialProperty.textureValue; + } + set + { + MaterialProperty.textureValue = value; + MaterialEditor.ApplyMaterialPropertyDrawers(ShaderEditor.Active.Materials); + } + } + + public override void CopyFromMaterial(Material m, bool isTopCall = false) + { + MaterialHelper.CopyPropertyValueFromMaterial(MaterialProperty, m); + CopyReferencePropertiesFromMaterial(m); + + if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, m.GetNumber(MaterialProperty) == 1); + if (IsAnimatable) + { + ShaderOptimizer.CopyAnimatedTagFromMaterial(m, MaterialProperty); + } + this.IsAnimated = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) != ""; + this.IsRenaming = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) == "2"; + + ExecuteOnValueActions(ShaderEditor.Active.Materials); + + if (isTopCall) ActiveShaderEditor.ApplyDrawers(); + } + + public override void CopyToMaterial(Material m, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + if (ShouldSkipProperty(MaterialProperty, skipPropertyTypes)) return; + + MaterialHelper.CopyPropertyValueToMaterial(MaterialProperty, m); + CopyReferencePropertiesToMaterial(m); + + if (Keyword != null) SetKeyword(m, MaterialProperty.GetNumber() == 1); + if (IsAnimatable) + ShaderOptimizer.CopyAnimatedTagToMaterials(new Material[] { m }, MaterialProperty); + + ExecuteOnValueActions(new Material[] { m }); + + if (isTopCall) MaterialEditor.ApplyMaterialPropertyDrawers(m); + } + + private void SetKeyword(Material[] materials, bool enabled) + { + if (enabled) foreach (Material m in materials) m.EnableKeyword(Keyword); + else foreach (Material m in materials) m.DisableKeyword(Keyword); + } + + private void SetKeyword(Material m, bool enabled) + { + if (enabled) m.EnableKeyword(Keyword); + else m.DisableKeyword(Keyword); + } + + public void UpdateKeywordFromValue() + { + if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, MaterialProperty.GetNumber() == 1); + } + + void InitializeDrawers() + { + DrawingData.ResetLastDrawerData(); + DrawingData.IsCollectingProperties = true; + ShaderEditor.Active.Editor.GetPropertyHeight(MaterialProperty, MaterialProperty.displayName); + + this.IsAnimatable = !DrawingData.LastPropertyDoesntAllowAnimation && IsAnimatable; // &&, so that IsAnimatable can be set to false before InitializeDrawers + this._hasDrawer = DrawingData.LastPropertyUsedCustomDrawer; + + if (MaterialProperty.type == MaterialProperty.PropType.Vector && _doForceIntoOneLine == false) + { + this.DoCustomHeightOffset = !DrawingData.LastPropertyUsedCustomDrawer; + this.CustomHeightOffset = -EditorGUIUtility.singleLineHeight; + } + if (DrawingData.LastPropertyDecorators.Count > 0) + { + _customDecorators = DrawingData.LastPropertyDecorators.ToArray(); + _customDecoratorRects = new Rect[DrawingData.LastPropertyDecorators.Count]; + } + + // Animatable Stuff + bool propHasDuplicate = ShaderEditor.Active.GetMaterialProperty(MaterialProperty.name + "_" + ShaderEditor.Active.RenamedPropertySuffix) != null; + string tag = null; + //If prop is og, but is duplicated (locked) dont have it animateable + if (propHasDuplicate) + { + this.IsAnimatable = false; + } + else + { + //if prop is a duplicated or renamed get og property to check for animted status + if (MaterialProperty.name.Contains(ShaderEditor.Active.RenamedPropertySuffix)) + { + string ogName = MaterialProperty.name.Substring(0, MaterialProperty.name.Length - ShaderEditor.Active.RenamedPropertySuffix.Length - 1); + tag = ShaderOptimizer.GetAnimatedTag(MaterialProperty.targets[0] as Material, ogName); + } + else + { + tag = ShaderOptimizer.GetAnimatedTag(MaterialProperty); + } + } + + this.IsAnimated = IsAnimatable && tag != ""; + this.IsRenaming = IsAnimatable && tag == "2"; + + DrawingData.IsCollectingProperties = false; + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + ActiveShaderEditor.CurrentProperty = this; + UpdatedMaterialPropertyReference(); + + if (_needsDrawerInitlization) + { + InitializeDrawers(); + _needsDrawerInitlization = false; + } + + PreDraw(); + if (ActiveShaderEditor.IsLockedMaterial) + EditorGUI.BeginDisabledGroup(!(IsAnimatable && (IsAnimated || IsRenaming)) && !IsExemptFromLockedDisabling); + + int oldIndentLevel = EditorGUI.indentLevel; + if (!useEditorIndent) + EditorGUI.indentLevel = XOffset + 1; + + if (_customDecorators != null && _doCustomDrawLogic) + { + for (int i = 0; i < _customDecorators.Length; i++) + { + _customDecoratorRects[i] = EditorGUILayout.GetControlRect(false, GUILayout.Height(_customDecorators[i].GetPropertyHeight(MaterialProperty, content.text, ActiveShaderEditor.Editor))); + } + } + + if (_doCustomDrawLogic) + { + DrawDefault(); + } + else if (_doDrawTwoFields) + { + Rect r = GUILayoutUtility.GetRect(content, Styles.vectorPropertyStyle); + float labelWidth = (r.width - EditorGUIUtility.labelWidth) / 2; ; + r.width -= labelWidth; + ActiveShaderEditor.Editor.ShaderProperty(r, this.MaterialProperty, content); + + r.x += r.width; + r.width = labelWidth; + float prevLabelW = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = 0; + ActiveShaderEditor.PropertyDictionary[Options.reference_property].Draw(r, new GUIContent()); + EditorGUIUtility.labelWidth = prevLabelW; + } + else if (_doForceIntoOneLine) + { + ActiveShaderEditor.Editor.ShaderProperty(GUILayoutUtility.GetRect(content, Styles.vectorPropertyStyle), this.MaterialProperty, content); + } + else if (DoCustomHeightOffset) + { + ActiveShaderEditor.Editor.ShaderProperty( + GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, ActiveShaderEditor.Editor.GetPropertyHeight(this.MaterialProperty, content.text) + CustomHeightOffset) + , this.MaterialProperty, content); + } + else if (rect != null) + { + // Custom Drawing for Range, because it doesnt draw correctly if inside the big texture property + if (!_hasDrawer && MaterialProperty.type == MaterialProperty.PropType.Range) + { + MaterialProperty.floatValue = EditorGUI.Slider(rect.Value, content, MaterialProperty.floatValue, 0, MaterialProperty.rangeLimits.y); + } + else + { + ActiveShaderEditor.Editor.ShaderProperty(rect.Value, this.MaterialProperty, content); + } + } + else + { + ActiveShaderEditor.Editor.ShaderProperty(this.MaterialProperty, content); + } + + if (_customDecorators != null && _doCustomDrawLogic) + { + for (int i = 0; i < _customDecorators.Length; i++) + { + _customDecorators[i].OnGUI(_customDecoratorRects[i], MaterialProperty, content, ShaderEditor.Active.Editor); + } + } + + EditorGUI.indentLevel = oldIndentLevel; + if (rect == null) DrawingData.LastGuiObjectRect = GUILayoutUtility.GetLastRect(); + else DrawingData.LastGuiObjectRect = rect.Value; + if (ActiveShaderEditor.IsLockedMaterial) + EditorGUI.EndDisabledGroup(); + } + + public virtual void PreDraw() { } + + public virtual void DrawDefault() { } + + public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + if (ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) return; + if (MaterialProperty.type != p.MaterialProperty.type) return; + MaterialHelper.CopyMaterialValueFromProperty(MaterialProperty, p.MaterialProperty); + if (Keyword != null) SetKeyword(ActiveShaderEditor.Materials, m.GetNumber(p.MaterialProperty) == 1); + if (IsAnimatable && p.IsAnimatable) + ShaderOptimizer.CopyAnimatedTagFromProperty(p.MaterialProperty, MaterialProperty); + this.IsAnimated = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) != ""; + this.IsRenaming = IsAnimatable && ShaderOptimizer.GetAnimatedTag(MaterialProperty) == "2"; + + if (isTopCall) ActiveShaderEditor.ApplyDrawers(); + } + + public override void FindUnusedTextures(List unusedList, bool isEnabled) + { + if (isEnabled && Options.condition_enable != null) + { + isEnabled &= Options.condition_enable.Test(); + } + if (!isEnabled && MaterialProperty != null && MaterialProperty.type == MaterialProperty.PropType.Texture && MaterialProperty.textureValue != null) + { + unusedList.Add(MaterialProperty.name); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs.meta new file mode 100644 index 00000000..f49eb468 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 514c10ee393975242aef365fb9b66428 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs new file mode 100644 index 00000000..3c3403bf --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderSection : ShaderGroup + { + + const int BORDER_WIDTH = 3; + const int HEADER_HEIGHT = 20; + const int CHECKBOX_OFFSET = 20; + + public ShaderSection(ShaderEditor shaderEditor, MaterialProperty prop, MaterialEditor materialEditor, string displayName, int xOffset, string optionsRaw, int propertyIndex) : base(shaderEditor, prop, materialEditor, displayName, xOffset, optionsRaw, propertyIndex) + { + } + + public override void DrawInternal(GUIContent content, Rect? rect = null, bool useEditorIndent = false, bool isInHeader = false) + { + if (Options.margin_top > 0) + { + GUILayoutUtility.GetRect(0, Options.margin_top); + } + + ShaderProperty reference = Options.reference_property != null ? ActiveShaderEditor.PropertyDictionary[Options.reference_property] : null; + bool has_header = string.IsNullOrWhiteSpace(this.Content.text) == false || reference != null; + + int headerTextX = 18; + int height = (has_header ? HEADER_HEIGHT : 0) + 4; // 4 for border margin + + // Draw border + Rect border = EditorGUILayout.BeginVertical(); + border = new RectOffset(this.XOffset * -15 - 12, 3, -2, -2).Add(border); + if (IsExpanded) + { + // Draw as border line + Vector4 borderWidths = new Vector4(3, (has_header ? HEADER_HEIGHT : 3), 3, 3); + GUI.DrawTexture(border, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, borderWidths, 5); + } + else + { + // Draw as solid + GUI.DrawTexture(border, Texture2D.whiteTexture, ScaleMode.StretchToFill, true, 0, Styles.COLOR_BACKGROUND_1, Vector4.zero, 5); + } + + // Draw Reference + Rect clickCheckRect = GUILayoutUtility.GetRect(0, height); + if (reference != null) + { + EditorGUI.BeginChangeCheck(); + Rect referenceRect = new Rect(border.x + CHECKBOX_OFFSET, border.y + 1, HEADER_HEIGHT - 2, HEADER_HEIGHT - 2); + reference.Draw(referenceRect, new GUIContent(), isInHeader: true, useEditorIndent: true); + headerTextX = CHECKBOX_OFFSET + HEADER_HEIGHT; + // Change expand state if reference is toggled + if (EditorGUI.EndChangeCheck() && Options.ref_float_toggles_expand) + { + IsExpanded = reference.MaterialProperty.GetNumber() == 1; + } + } + + // Draw Header (GUIContent) + Rect top_border = new Rect(border.x, border.y - 2, border.width - 16, 22); + if (has_header) + { + Rect header_rect = new RectOffset(headerTextX, 0, 0, 0).Remove(top_border); + GUI.Label(header_rect, this.Content, EditorStyles.label); + } + + // Toggling + Draw Arrow + FoldoutArrow(top_border, Event.current); + if (Event.current.type == EventType.MouseDown && clickCheckRect.Contains(Event.current.mousePosition)) + { + IsExpanded = !IsExpanded; + Event.current.Use(); + } + + // Draw Children + if (IsExpanded) + { + EditorGUI.BeginDisabledGroup(DoDisableChildren); + foreach (ShaderPart part in parts) + { + part.Draw(); + } + EditorGUI.EndDisabledGroup(); + GUILayoutUtility.GetRect(0, 5); + } + EditorGUILayout.EndVertical(); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs.meta new file mode 100644 index 00000000..ae01d5ae --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderSection.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cbc27e474e73c3b4595aa173e66da3ff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs new file mode 100644 index 00000000..b9c6f99b --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Thry.ThryEditor; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Thry +{ + public class ShaderTextureProperty : ShaderProperty + { + public bool showFoldoutProperties = false; + public bool hasFoldoutProperties = false; + public bool hasScaleOffset = false; + public string VRAMString = ""; + bool _isVRAMDirty = true; + + public ShaderTextureProperty(ShaderEditor shaderEditor, MaterialProperty materialProperty, string displayName, int xOffset, string optionsRaw, bool hasScaleOffset, bool forceThryUI, int property_index) : base(shaderEditor, materialProperty, displayName, xOffset, optionsRaw, false, property_index) + { + _doCustomDrawLogic = forceThryUI; + this.hasScaleOffset = hasScaleOffset; + } + + protected override void InitOptions() + { + base.InitOptions(); + this.hasFoldoutProperties = hasScaleOffset || DoReferencePropertiesExist; + } + + void UpdateVRAM() + { + if (MaterialProperty.textureValue != null) + { + var details = TextureHelper.VRAM.CalcSize(MaterialProperty.textureValue); + this.VRAMString = $"{TextureHelper.VRAM.ToByteString(details.size)}"; + } + else + { + VRAMString = null; + } + } + + protected override void OnPropertyValueChanged() + { + base.OnPropertyValueChanged(); + _isVRAMDirty = true; + } + + public override void PreDraw() + { + DrawingData.CurrentTextureProperty = this; + this._doCustomDrawLogic = !this._hasDrawer; + if (this._isVRAMDirty) + { + UpdateVRAM(); + _isVRAMDirty = false; + } + } + + public override void DrawDefault() + { + Rect pos = GUILayoutUtility.GetRect(Content, Styles.vectorPropertyStyle); + GUILib.ConfigTextureProperty(pos, MaterialProperty, Content, ActiveShaderEditor.Editor, hasFoldoutProperties); + DrawingData.LastGuiObjectRect = pos; + } + + public override void TransferFromMaterialAndGroup(Material m, ShaderPart p, bool isTopCall = false, MaterialProperty.PropType[] skipPropertyTypes = null) + { + if (ShouldSkipProperty(p.MaterialProperty, skipPropertyTypes)) return; + if (MaterialProperty.type != p.MaterialProperty.type) return; + MaterialHelper.CopyMaterialValueFromProperty(MaterialProperty, p.MaterialProperty); + TransferReferencePropertiesToMaterial(m, p); + } + private void TransferReferencePropertiesToMaterial(Material target, ShaderPart p) + { + if (p.Options.reference_properties == null || this.Options.reference_properties == null) return; + for (int i = 0; i < p.Options.reference_properties.Length && i < Options.reference_properties.Length; i++) + { + if (ActiveShaderEditor.PropertyDictionary.ContainsKey(this.Options.reference_properties[i]) == false) continue; + + ShaderProperty targetP = ActiveShaderEditor.PropertyDictionary[this.Options.reference_properties[i]]; + ShaderProperty sourceP = p.ActiveShaderEditor.PropertyDictionary[p.Options.reference_properties[i]]; + MaterialHelper.CopyMaterialValueFromProperty(targetP.MaterialProperty, sourceP.MaterialProperty); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs.meta new file mode 100644 index 00000000..44d14d09 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/EditorStructs/ShaderTextureProperty.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c31783d827467a840b719bf24b662225 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs new file mode 100644 index 00000000..51812d30 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text.RegularExpressions; +using UnityEngine; + +namespace Thry +{ + public static class ExpressionParser + { + public static Delegate Parse(string expression) + { + // Clean up the expression + expression = expression.Replace(" ", ""); + + if(double.TryParse(expression, out _)) + { + string oldExpression = expression; + expression = $"x == {expression}"; + Debug.Log($"Expression was {oldExpression} so we assume {expression}"); + } + + // Handle negative numbers by replacing unary minus with a special character + expression = HandleUnaryOperators(expression); + + // Define the parameter for the expression + var parameter = Expression.Parameter(typeof(double), "x"); + + // Tokenize the expression + var tokens = Tokenize(expression); + + // Check if the parameter "x" is used in the expression + bool containsParameter = tokens.Contains("x"); + + // Parse the expression string into an expression tree + var body = ParseExpression(tokens, containsParameter ? parameter : null); + + // Create a lambda expression with the parameter and parsed body + if(containsParameter) + { + return Expression.Lambda>(body, parameter).Compile(); + } + else + { + // If parameter "x" is not used, create a parameter-less lambda + return Expression.Lambda>(body).Compile(); + } + } + + private static string HandleUnaryOperators(string expression) + { + // Replace unary minus and plus with special characters + expression = Regex.Replace(expression, @"(? Tokenize(string expression) + { + var tokens = new List(); + var token = ""; + + for(int i = 0; i < expression.Length; i++) + { + char c = expression[i]; + if(char.IsWhiteSpace(c)) + { + continue; + } + + if(IsParenthesis(c)) + { + if(token.Length > 0) + { + tokens.Add(token); + token = ""; + } + + tokens.Add(c.ToString()); + } + else if(i + 1 < expression.Length && IsOperator(expression.Substring(i, 2))) + { + if(token.Length > 0) + { + tokens.Add(token); + token = ""; + } + + tokens.Add(expression.Substring(i, 2)); + i++; // Skip the next character as it has been processed + } + else if(IsOperator(c.ToString())) + { + if(token.Length > 0) + { + tokens.Add(token); + token = ""; + } + + tokens.Add(c.ToString()); + } + else if(char.IsDigit(c) || c == '.') + { + token += c; + } + else if(c == 'x') + { + if(token.Length > 0) + { + tokens.Add(token); + token = ""; + } + + tokens.Add("x"); + } + else + { + token += c; + } + } + + if(token.Length > 0) + { + tokens.Add(token); + } + + return tokens; + } + + private static Expression ParseExpression(List tokens, ParameterExpression parameter) + { + var stack = new Stack(); + var operatorStack = new Stack(); + + for(int i = 0; i < tokens.Count; i++) + { + var token = tokens[i]; + + if(double.TryParse(token, out var number)) + { + stack.Push(Expression.Constant(number)); + } + else if(token == "x") + { + if(parameter == null) + throw new ArgumentException("Parameter 'x' is not defined."); + stack.Push(parameter); + } + else if(token == "_") + { + stack.Push(Expression.Negate(ParseExpression(tokens.GetRange(i + 1, 1), parameter))); + i++; // Skip the next token as it has been processed + } + else if(IsOperator(token)) + { + while(operatorStack.Count > 0 && GetPrecedence(operatorStack.Peek()) >= GetPrecedence(token)) + { + var op = operatorStack.Pop(); + var right = stack.Pop(); + var left = stack.Pop(); + stack.Push(CreateBinaryExpression(op, left, right)); + } + + operatorStack.Push(token); + } + else if(token == "(") + { + operatorStack.Push(token); + } + else if(token == ")") + { + while(operatorStack.Count > 0 && operatorStack.Peek() != "(") + { + var op = operatorStack.Pop(); + var right = stack.Pop(); + var left = stack.Pop(); + stack.Push(CreateBinaryExpression(op, left, right)); + } + + if(operatorStack.Count > 0 && operatorStack.Peek() == "(") + { + operatorStack.Pop(); + } + } + else + { + throw new ArgumentException($"Invalid token: {token}"); + } + } + + while(operatorStack.Count > 0) + { + var op = operatorStack.Pop(); + var right = stack.Pop(); + var left = stack.Pop(); + stack.Push(CreateBinaryExpression(op, left, right)); + } + + return stack.Pop(); + } + + private static Expression CreateBinaryExpression(string op, Expression left, Expression right) + { + switch(op) + { + case "+": + return Expression.Add(left, right); + case "-": + return Expression.Subtract(left, right); + case "*": + return Expression.Multiply(left, right); + case "/": + return Expression.Divide(left, right); + case "%": + return Expression.Modulo(left, right); + case "^": + return Expression.Power(left, right); + case "==": + return Expression.Equal(left, right); + case "!=": + return Expression.NotEqual(left, right); + case "<": + return Expression.LessThan(left, right); + case "<=": + return Expression.LessThanOrEqual(left, right); + case ">": + return Expression.GreaterThan(left, right); + case ">=": + return Expression.GreaterThanOrEqual(left, right); + case "&&": + return Expression.AndAlso(left, right); + case "||": + return Expression.OrElse(left, right); + default: + throw new ArgumentException($"Invalid operator: {op}"); + } + } + + + static readonly string[] _operators = new string[] { "+", "-", "*", "/", "%", "^", "==", "!=", "<", "<=", ">", ">=", "&&", "||", "_" }; + + private static bool IsOperator(string token) + { + return _operators.Contains(token); + } + + private static bool IsParenthesis(char c) + { + return c == '(' || c == ')'; + } + + private static int GetPrecedence(string op) + { + switch(op) + { + case "||": + return 1; + case "&&": + return 2; + case "==": + case "!=": + return 3; + case "<": + case "<=": + case ">": + case ">=": + return 4; + case "+": + case "-": + return 5; + case "*": + case "/": + case "%": + return 6; + case "^": + return 7; + default: + return 0; + } + } + + private class ExpressionReplacer : ExpressionVisitor + { + protected override Expression VisitParameter(ParameterExpression node) + { + return Expression.Parameter(typeof(double), "x"); + } + } + } +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs.meta new file mode 100644 index 00000000..7a42a977 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/ExpressionParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 34c0e0e89c48d9c448004acf90d14382 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs similarity index 94% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs index 706e97f5..bac26005 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUIHelper.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs @@ -7,7 +7,7 @@ namespace Thry { - public class GuiHelper + public class GUILib { public const float SMALL_TEXTURE_VRAM_DISPLAY_WIDTH = 80; @@ -76,8 +76,8 @@ public static void SmallTextureProperty(Rect position, MaterialProperty prop, GU r.width -= EditorGUIUtility.labelWidth - CurrentIndentWidth(); r.width -= vramPos.width; foloutClickCheck.width -= r.width; - property.Draw(new CRect(r), new GUIContent()); - property.tooltip.ConditionalDraw(r); + property.Draw(r, new GUIContent()); + property.Tooltip.ConditionalDraw(r); } //Foldouts if (hasFoldoutProperties && DrawingData.CurrentTextureProperty != null) @@ -106,7 +106,8 @@ public static void SmallTextureProperty(Rect position, MaterialProperty prop, GU iconsPositioningHeight = lastRect.y; } //In case of locked material end disabled group here to allow editing of sub properties - if (ShaderEditor.Active.IsLockedMaterial) EditorGUI.EndDisabledGroup(); + + if (ShaderEditor.Active.IsLockedMaterial) GUI.enabled = DrawingData.IsEnabled; PropertyOptions options = DrawingData.CurrentTextureProperty.Options; if (options.reference_properties != null) @@ -116,9 +117,6 @@ public static void SmallTextureProperty(Rect position, MaterialProperty prop, GU property.Draw(useEditorIndent: true); } - //readd disabled group - if (ShaderEditor.Active.IsLockedMaterial) EditorGUI.BeginDisabledGroup(false); - EditorGUI.indentLevel -= 2; } if (ShaderEditor.Input.LeftClick_IgnoreLockedAndUnityUses && foloutClickCheck.Contains(Event.current.mousePosition)) @@ -133,7 +131,7 @@ public static void SmallTextureProperty(Rect position, MaterialProperty prop, GU object_rect.height = GUILayoutUtility.GetLastRect().y - object_rect.y + GUILayoutUtility.GetLastRect().height; DrawingData.LastGuiObjectRect = object_rect; DrawingData.TooltipCheckRect = tooltipRect; - DrawingData.IconsPositioningHeight = iconsPositioningHeight; + DrawingData.IconsPositioningHeights[0] = iconsPositioningHeight; // Border Code start if(isFoldedOut) @@ -261,7 +259,7 @@ public static void StylizedBigTextureProperty(Rect position, MaterialProperty pr ShaderProperty property = ShaderEditor.Active.PropertyDictionary[options.reference_property]; Rect r = additionRects[additionRects.Length - 1]; r.width = optionsSide.width; - property.Draw(new CRect(r)); + property.Draw(r); } if (options.reference_properties != null) { @@ -271,7 +269,7 @@ public static void StylizedBigTextureProperty(Rect position, MaterialProperty pr ShaderProperty property = ShaderEditor.Active.PropertyDictionary[r_property]; Rect r = additionRects[i++]; r.width = optionsSide.width; - property.Draw(new CRect(r)); + property.Draw(r); } } EditorGUIUtility.labelWidth = labelWith; @@ -298,7 +296,7 @@ public static void StylizedBigTextureProperty(Rect position, MaterialProperty pr DrawingData.LastGuiObjectRect = border; DrawingData.TooltipCheckRect = Rect.MinMaxRect(border.x, border.y, scale_offset_rect.xMax, scale_offset_rect.yMax); - DrawingData.IconsPositioningHeight = scale_offset_rect.y; + DrawingData.IconsPositioningHeights[0] = scale_offset_rect.y; } public static void BigTexturePropertyBasic(Rect position, MaterialProperty prop, GUIContent label, MaterialEditor editor, bool hasFoldoutProperties, bool skip_drag_and_drop_handling = false) @@ -338,7 +336,7 @@ public static void BigTexturePropertyBasic(Rect position, MaterialProperty prop, DrawingData.LastGuiObjectRect = position; DrawingData.TooltipCheckRect = tooltipCheckRect; - DrawingData.IconsPositioningHeight = iconsPositioningHeight; + DrawingData.IconsPositioningHeights[0] = iconsPositioningHeight; } public static void OpenTexturePicker(MaterialProperty prop) @@ -633,56 +631,17 @@ public static bool Button(Rect r, string tooltip, GUIStyle style) return GUI.Button(r, new GUIContent("", tooltip), style); } - public static bool Button(GUIStyle style, int width, int height) - { - Rect r = GUILayoutUtility.GetRect(width, height); - return Button(r, style); - } - - public static bool ButtonWithCursor(GUIStyle style, int width, int height) - { - Rect r = GUILayoutUtility.GetRect(width, height); - EditorGUIUtility.AddCursorRect(r, MouseCursor.Link); - return Button(r, style); - } - - public static bool ButtonWithCursor(GUIStyle style, string tooltip, int width, int height) + public static bool ButtonWithCursor(Rect r, GUIStyle style, string tooltip) { - Rect r = GUILayoutUtility.GetRect(width, height); EditorGUIUtility.AddCursorRect(r, MouseCursor.Link); return Button(r, tooltip, style); } - public static bool ButtonWithCursor(GUIStyle style, string tooltip, int width, int height, out Rect r) - { - r = GUILayoutUtility.GetRect(width, height); - EditorGUIUtility.AddCursorRect(r, MouseCursor.Link); - return Button(r, tooltip, style); - } - - public static bool Button(Rect r, string tooltip, GUIStyle style, Color c) - { - Color prevColor = GUI.backgroundColor; - GUI.backgroundColor = c; - bool b = GuiHelper.Button(r, tooltip, style); - GUI.backgroundColor = prevColor; - return b; - } - - public static bool Button(GUIStyle style, int width, int height, Color c) - { - Color prevColor = GUI.backgroundColor; - GUI.backgroundColor = c; - bool b = GuiHelper.Button(style, width, height); - GUI.backgroundColor = prevColor; - return b; - } - public static bool Button(Rect r, GUIStyle style, Color c, bool doColor) { Color prevColor = GUI.backgroundColor; if(doColor) GUI.backgroundColor = c; - bool b = GuiHelper.Button(r, style); + bool b = GUILib.Button(r, style); GUI.backgroundColor = prevColor; return b; } @@ -748,6 +707,41 @@ private void OnGUI() #endregion } + public class RectifiedLayout + { + /// + /// Returns recitfied for 2022 rect + /// + /// + /// + public static Rect GetRect(int height) + { + Rect r = EditorGUILayout.GetControlRect(false, height); +#if UNITY_2022_1_OR_NEWER + r.x -= 30; + r.width += 30; +#endif + return r; + } + + public static bool Button(string text) + { + Rect r = GetRect(25); + return GUI.Button(r, text); + } + + public static bool ButtonWithCursor(string text) + { + Rect r = GetRect(25); + EditorGUIUtility.AddCursorRect(r, MouseCursor.Link); + return GUI.Button(r, text); + } + + public static void Seperator() + { + EditorGUI.DrawRect(RectifiedLayout.GetRect(1), Styles.COLOR_FG); + } + } public class BetterTooltips { private static Tooltip activeTooltip; diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs.meta new file mode 100644 index 00000000..546f9115 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GUILib.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73406a9bda79dfe4486c7db493c60280 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GradiantEditor.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GradiantEditor.cs index f9208fce..b4ab7776 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/GradiantEditor.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/GradiantEditor.cs @@ -11,7 +11,11 @@ namespace Thry { public class GradientEditor : EditorWindow { - + public class GradientData + { + public Texture PreviewTexture; + public Gradient Gradient; + } public static void Open(GradientData data, MaterialProperty prop, TextureData predefinedTextureSettings, bool force_texture_options = false, bool show_texture_options=true) { texture_settings_data = LoadTextureSettings(prop, predefinedTextureSettings, force_texture_options); @@ -217,7 +221,7 @@ private void TextureSettingsGUI() EditorGUIUtility.labelWidth = 100; EditorGUIUtility.fieldWidth = 150; EditorGUILayout.LabelField("Texture options:",EditorStyles.boldLabel); - bool changed = GuiHelper.GUIDataStruct(textureSettings, new string[]{"name"}); + bool changed = GUILib.GUIDataStruct(textureSettings, new string[]{"name"}); if (changed) { FileHelper.SaveValueToFile("gradient_texture_options_" + prop.name, Parser.ObjectToString(textureSettings), PATH.PERSISTENT_DATA); diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs deleted file mode 100644 index d06b18cd..00000000 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs +++ /dev/null @@ -1,1961 +0,0 @@ -// Material/Shader Inspector for Unity 2017/2018 -// Copyright (C) 2019 Thryrallo - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEngine; -using UnityEngine.Profiling; - -namespace Thry -{ - static class StringExtensions - { - public static string ReplaceVariables(this string s, params object[] values) - { - for(int i = 0; i < values.Length;i++) - { - s = s.Replace("{" + i + "}", values[i].ToString()); - } - return s; - } - } - - public class Helper - { - static bool s_didTryRegsiterThisSession = false; - - public static bool ClassWithNamespaceExists(string classname) - { - return (from assembly in AppDomain.CurrentDomain.GetAssemblies() - from type in assembly.GetTypes() - where type.FullName == classname - select type).Count() > 0; - } - - public static Type FindTypeByFullName(string fullname) - { - return (from assembly in AppDomain.CurrentDomain.GetAssemblies() - from type in assembly.GetTypes() - where type.FullName == fullname - select type).FirstOrDefault(); - } - - private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - - public static long GetCurrentUnixTimestampMillis() - { - return (long)(DateTime.UtcNow - UnixEpoch).TotalMilliseconds; - } - - public static long DatetimeToUnixSeconds(DateTime time) - { - return (long)(time - UnixEpoch).TotalSeconds; - } - - public static long GetUnityStartUpTimeStamp() - { - return GetCurrentUnixTimestampMillis() - (long)EditorApplication.timeSinceStartup * 1000; - } - - public static void RegisterEditorUse() - { - if (s_didTryRegsiterThisSession) return; - if (!EditorPrefs.GetBool("thry_has_counted_user", false)) - { - WebHelper.DownloadStringASync(URL.COUNT_USER, delegate (string s) - { - if (s == "true") - EditorPrefs.SetBool("thry_has_counted_user", true); - }); - } - - string projectPrefix = PlayerSettings.companyName + "." + PlayerSettings.productName; - if (!EditorPrefs.GetBool(projectPrefix + "_thry_has_counted_project", false)) - { - WebHelper.DownloadStringASync(URL.COUNT_PROJECT, delegate (string s) - { - if (s == "true") - EditorPrefs.SetBool(projectPrefix + "_thry_has_counted_project", true); - }); - } - s_didTryRegsiterThisSession = true; - } - - //-------------------Comparetors---------------------- - - public static int CompareVersions(string v1, string v2) - { - //fix the string - v1 = v1.Replace(",", "."); - v2 = v2.Replace(",", "."); - Match v1_match = Regex.Match(v1, @"(a|b)?\d+((\.|a|b)\d+)*(a|b)?"); - Match v2_match = Regex.Match(v2, @"(a|b)?\d+((\.|a|b)\d+)*(a|b)?"); - if (!v1_match.Success && !v2_match.Success) return 0; - else if (!v1_match.Success) return 1; - else if (!v2_match.Success) return -1; - v1 = v1_match.Value; - v2 = v2_match.Value; - - int index_v1 = 0; - int index_v2 = 0; - string chunk_v1; - string chunk_v2; - while (index_v1 < v1.Length || index_v2 < v2.Length) - { - //get a chunk of the strings - if (index_v1 < v1.Length) - { - chunk_v1 = ""; - if (v1[index_v1] == 'a') - chunk_v1 = "-2"; - else if (v1[index_v1] == 'b') - chunk_v1 = "-1"; - else - { - while (index_v1 < v1.Length && v1[index_v1] != 'a' && v1[index_v1] != 'b' && v1[index_v1] != '.') - chunk_v1 += v1[index_v1++]; - if (index_v1 < v1.Length && (v1[index_v1] == 'a' || v1[index_v1] == 'b')) - index_v1--; - } - index_v1++; - } - else - chunk_v1 = "0"; - - if (index_v2 < v2.Length) - { - chunk_v2 = ""; - if (v2[index_v2] == 'a') - chunk_v2 = "-2"; - else if (v2[index_v2] == 'b') - chunk_v2 = "-1"; - else - { - while (index_v2 < v2.Length && v2[index_v2] != 'a' && v2[index_v2] != 'b' && v2[index_v2] != '.') - chunk_v2 += v2[index_v2++]; - if (index_v2 < v2.Length && (v2[index_v2] == 'a' || v2[index_v2] == 'b')) - index_v2--; - } - index_v2++; - } - else - chunk_v2 = "0"; - - //compare chunks - int v1P = int.Parse(chunk_v1); - int v2P = int.Parse(chunk_v2); - if (v1P > v2P) return -1; - else if (v1P < v2P) return 1; - } - return 0; - } - - public static bool IsPrimitive(Type t) - { - return t.IsPrimitive || t == typeof(Decimal) || t == typeof(String); - } - - public static string GetStringBetweenBracketsAndAfterId(string input, string id, char[] brackets) - { - string[] parts = Regex.Split(input, id); - if (parts.Length > 1) - { - char[] behind_id = parts[1].ToCharArray(); - int i = 0; - int begin = 0; - int end = behind_id.Length - 1; - int depth = 0; - bool escaped = false; - while (i < behind_id.Length) - { - if (behind_id[i] == brackets[0] && !escaped) - { - if (depth == 0) - begin = i; - depth++; - } - else if (behind_id[i] == brackets[1] && !escaped) - { - depth--; - if (depth == 0) - { - end = i; - break; - } - } - - if (behind_id[i] == '\\') - escaped = !escaped; - else - escaped = false; - i++; - } - return parts[1].Substring(begin, end); - } - return input; - } - - public static float SolveMath(string exp, float parameter) - { - exp = exp.Replace("x", parameter.ToString(CultureInfo.InvariantCulture)); - exp = exp.Replace(" ", ""); - float f; - if (ExpressionEvaluator.Evaluate(exp, out f)) return f; - return 0; - } - - public static float Mod(float a, float b) - { - return a - b * Mathf.Floor(a / b); - } - - // This code is an implementation of the pseudocode from the Wikipedia, - // showing a naive implementation. - // You should research an algorithm with better space complexity. - public static int LevenshteinDistance(string s, string t) - { - int n = s.Length; - int m = t.Length; - int[,] d = new int[n + 1, m + 1]; - if (n == 0) - { - return m; - } - if (m == 0) - { - return n; - } - for (int i = 0; i <= n; d[i, 0] = i++) - ; - for (int j = 0; j <= m; d[0, j] = j++) - ; - for (int i = 1; i <= n; i++) - { - for (int j = 1; j <= m; j++) - { - int cost = (t[j - 1] == s[i - 1]) ? 0 : 1; - d[i, j] = Math.Min( - Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), - d[i - 1, j - 1] + cost); - } - } - return d[n, m]; - } - - // Start of Detour methods - // Modified from: https://github.com/apkd/UnityStaticBatchingSortingPatch/blob/e83bed8cf31fc98097586c4e47af77fa79d9bed5/StaticBatchingSortingPatch.cs - // Modified by Behemoth/hill - static Dictionary s_patchedData = new Dictionary(); - public static unsafe void TryDetourFromTo(MethodInfo src, MethodInfo dst) - { - try - { - if (IntPtr.Size == sizeof(Int64)) - { - // 64-bit systems use 64-bit absolute address and jumps - // 12 byte destructive - - // Get function pointers - long Source_Base = src .MethodHandle.GetFunctionPointer().ToInt64(); - long Destination_Base = dst.MethodHandle.GetFunctionPointer().ToInt64(); - - // Backup Source Data - IntPtr Source_IntPtr = src.MethodHandle.GetFunctionPointer(); - var backup = new byte[0xC]; - Marshal.Copy(Source_IntPtr, backup, 0, 0xC); - s_patchedData.Add(src, backup); - - // Native source address - byte* Pointer_Raw_Source = (byte*)Source_Base; - - // Pointer to insert jump address into native code - long* Pointer_Raw_Address = (long*)( Pointer_Raw_Source + 0x02 ); - - // Insert 64-bit absolute jump into native code (address in rax) - // mov rax, immediate64 - // jmp [rax] - *( Pointer_Raw_Source + 0x00 ) = 0x48; - *( Pointer_Raw_Source + 0x01 ) = 0xB8; - *Pointer_Raw_Address = Destination_Base; // ( Pointer_Raw_Source + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 ) - *( Pointer_Raw_Source + 0x0A ) = 0xFF; - *( Pointer_Raw_Source + 0x0B ) = 0xE0; - } - else - { - // 32-bit systems use 32-bit relative offset and jump - // 5 byte destructive - - // Get function pointers - int Source_Base = src .MethodHandle.GetFunctionPointer().ToInt32(); - int Destination_Base = dst.MethodHandle.GetFunctionPointer().ToInt32(); - - // Backup Source Data - IntPtr Source_IntPtr = src.MethodHandle.GetFunctionPointer(); - var backup = new byte[0x5]; - Marshal.Copy(Source_IntPtr, backup, 0, 0x5); - s_patchedData.Add(src, backup); - - // Native source address - byte* Pointer_Raw_Source = (byte*)Source_Base; - - // Pointer to insert jump address into native code - int* Pointer_Raw_Address = (int*)( Pointer_Raw_Source + 1 ); - - // Jump offset (less instruction size) - int offset = ( Destination_Base - Source_Base ) - 5; - - // Insert 32-bit relative jump into native code - *Pointer_Raw_Source = 0xE9; - *Pointer_Raw_Address = offset; - } - } - catch (Exception ex) - { - Debug.LogError($"Unable to detour: {src?.Name ?? "UnknownSrc"} -> {dst?.Name ?? "UnknownDst"}\n{ex}"); - throw; - } - } - - public static unsafe void RestoreDetour(MethodInfo src) { - var Source_IntPtr = src.MethodHandle.GetFunctionPointer(); - var backup = s_patchedData[src]; - Marshal.Copy(backup, 0, Source_IntPtr, backup.Length); - s_patchedData.Remove(src); - } - // End of Detour Methods - } - - public class PersistentData - { - public static string Get(string key) - { - return FileHelper.LoadValueFromFile(key, PATH.PERSISTENT_DATA); - } - - public static void Set(string key, string value) - { - FileHelper.SaveValueToFile(key, value, PATH.PERSISTENT_DATA); - } - - public static T Get(string key, T defaultValue) - { - string s = FileHelper.LoadValueFromFile(key, PATH.PERSISTENT_DATA); - if (string.IsNullOrEmpty(s)) return defaultValue; - T obj = Parser.Deserialize(s); - if (obj == null) return defaultValue; - return obj; - } - - public static void Set(string key, object value) - { - FileHelper.SaveValueToFile(key, Parser.Serialize(value), PATH.PERSISTENT_DATA); - } - } - - public class FileHelper - { - public static string FindFile(string name, string type=null) - { - string[] guids; - if (type != null) - guids = AssetDatabase.FindAssets(name + " t:" + type); - else - guids = AssetDatabase.FindAssets(name); - if (guids.Length == 0) - return null; - return AssetDatabase.GUIDToAssetPath(guids[0]); - } - - //-----------------------Value To File Saver---------------------- - - private static Dictionary> s_textFileData = new Dictionary>(); - - public static string LoadValueFromFile(string key, string path) - { - if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); - if (s_textFileData[path].ContainsKey(key)) - return s_textFileData[path][key]; - return null; - } - - private static void ReadFileIntoTextFileData(string path) - { - string data = ReadFileIntoString(path); - Dictionary dictionary = new Dictionary(); - MatchCollection matchCollection = Regex.Matches(data, @".*\s*:=.*(?=\r?\n)"); - foreach(Match m in matchCollection) - { - string[] keyvalue = m.Value.Split(new string[] { ":=" }, 2, StringSplitOptions.RemoveEmptyEntries); - if(keyvalue.Length>1) - dictionary[keyvalue[0]] = keyvalue[1]; - } - s_textFileData[path] = dictionary; - } - - public static bool SaveValueToFile(string key, string value, string path) - { - if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); - s_textFileData[path][key] = value; - return SaveDictionaryToFile(path, s_textFileData[path]); - } - - public static void RemoveValueFromFile(string key, string path) - { - if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); - if (s_textFileData[path].ContainsKey(key)) s_textFileData[path].Remove(key); - } - - private static bool SaveDictionaryToFile(string path, Dictionary dictionary) - { - s_textFileData[path] = dictionary; - string data = s_textFileData[path].Aggregate("", (d1, d2) => d1 + d2.Key + ":=" + d2.Value + "\n"); - WriteStringToFile(data, path); - return true; - } - - //-----------------------File Interaction--------------------- - - public static string FindFileAndReadIntoString(string fileName) - { - string[] guids = AssetDatabase.FindAssets(fileName); - if (guids.Length > 0) - return ReadFileIntoString(AssetDatabase.GUIDToAssetPath(guids[0])); - else return ""; - } - - public static void FindFileAndWriteString(string fileName, string s) - { - string[] guids = AssetDatabase.FindAssets(fileName); - if (guids.Length > 0) - WriteStringToFile(s, AssetDatabase.GUIDToAssetPath(guids[0])); - } - - public static string ReadFileIntoString(string path) - { - if (!File.Exists(path)) - { - CreateFileWithDirectories(path); - return ""; - } - StreamReader reader = new StreamReader(path); - string ret = reader.ReadToEnd(); - reader.Close(); - return ret; - } - - public static void WriteStringToFile(string s, string path) - { - if (!File.Exists(path)) CreateFileWithDirectories(path); - StreamWriter writer = new StreamWriter(path, false); - writer.Write(s); - writer.Close(); - } - - public static bool WriteBytesToFile(byte[] bytes, string path) - { - if (!File.Exists(path)) CreateFileWithDirectories(path); - try - { - using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) - { - fs.Write(bytes, 0, bytes.Length); - return true; - } - } - catch (Exception ex) - { - Debug.Log("Exception caught in process: " + ex.ToString()); - return false; - } - } - - public static void CreateFileWithDirectories(string path) - { - string dir_path = Path.GetDirectoryName(path); - if (dir_path != "") - Directory.CreateDirectory(dir_path); - File.Create(path).Close(); - } - } - - public class TrashHandler - { - public static void EmptyThryTrash() - { - if (Directory.Exists(PATH.DELETING_DIR)) - { - DeleteDirectory(PATH.DELETING_DIR); - } - } - - public static void MoveDirectoryToTrash(string path) - { - string name = Path.GetFileName(path); - if (!Directory.Exists(PATH.DELETING_DIR)) - Directory.CreateDirectory(PATH.DELETING_DIR); - int i = 0; - string newpath = PATH.DELETING_DIR + "/" + name + i; - while (Directory.Exists(newpath)) - newpath = PATH.DELETING_DIR + "/" + name + (++i); - Directory.Move(path, newpath); - } - - static void DeleteDirectory(string path) - { - foreach (string f in Directory.GetFiles(path)) - DeleteFile(f); - foreach (string d in Directory.GetDirectories(path)) - DeleteDirectory(d); - if (Directory.GetFiles(path).Length + Directory.GetDirectories(path).Length == 0) - Directory.Delete(path); - } - static void DeleteFile(string path) - { - try - { - File.Delete(path); - } - catch (Exception e) - { - e.GetType(); - } - } - } - - public class TextureHelper - { - public static Gradient GetGradient(Texture texture) - { - if (texture != null) - { - string path = AssetDatabase.GetAssetPath(texture); - string gradient_data_string = null; - if(path != null) gradient_data_string = FileHelper.LoadValueFromFile(AssetDatabase.AssetPathToGUID(path), PATH.GRADIENT_INFO_FILE); - //For Backwards compatibility check old id (name) if guid cant be found - if(gradient_data_string == null) gradient_data_string = FileHelper.LoadValueFromFile(texture.name, PATH.GRADIENT_INFO_FILE); - if (gradient_data_string != null) - { - Debug.Log(texture.name + " Gradient loaded from file."); - Gradient g = Parser.Deserialize(gradient_data_string); - return g; - } - Debug.Log(texture.name + " Converted into Gradient."); - return Converter.TextureToGradient(GetReadableTexture(texture)); - } - return new Gradient(); - } - - private static Texture2D s_BackgroundTexture; - - public static Texture2D GetBackgroundTexture() - { - if (s_BackgroundTexture == null) - s_BackgroundTexture = CreateCheckerTexture(32, 4, 4, Color.white, new Color(0.7f, 0.7f, 0.7f)); - return s_BackgroundTexture; - } - - public static Texture2D CreateCheckerTexture(int numCols, int numRows, int cellPixelWidth, Color col1, Color col2) - { - int height = numRows * cellPixelWidth; - int width = numCols * cellPixelWidth; - - Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false); - texture.hideFlags = HideFlags.HideAndDontSave; - Color[] pixels = new Color[width * height]; - - for (int i = 0; i < numRows; i++) - for (int j = 0; j < numCols; j++) - for (int ci = 0; ci < cellPixelWidth; ci++) - for (int cj = 0; cj < cellPixelWidth; cj++) - pixels[(i * cellPixelWidth + ci) * width + j * cellPixelWidth + cj] = ((i + j) % 2 == 0) ? col1 : col2; - - texture.SetPixels(pixels); - texture.Apply(); - return texture; - } - - public static Texture SaveTextureAsPNG(Texture2D texture, string path, TextureData settings = null) - { - if (!path.EndsWith(".png")) - path += ".png"; - byte[] encoding = texture.EncodeToPNG(); - Debug.Log("Texture saved at \"" + path + "\"."); - FileHelper.WriteBytesToFile(encoding, path); - - AssetDatabase.ImportAsset(path); - if (settings != null) - settings.ApplyModes(path); - Texture saved = AssetDatabase.LoadAssetAtPath(path); - return saved; - } - - public static void MakeTextureReadible(string path) - { - TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path); - if (!importer.isReadable) - { - importer.isReadable = true; - importer.SaveAndReimport(); - } - } - - public static Texture2D GetReadableTexture(Texture texture) - { - RenderTexture temp = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); - Graphics.Blit(texture, temp); - RenderTexture previous = RenderTexture.active; - RenderTexture.active = temp; - Texture2D ret = new Texture2D(texture.width, texture.height); - ret.ReadPixels(new Rect(0, 0, temp.width, temp.height), 0, 0); - ret.Apply(); - RenderTexture.active = previous; - RenderTexture.ReleaseTemporary(temp); - return ret; - } - - public static Texture2D Resize(Texture2D texture, int width, int height) - { - Texture2D ret = new Texture2D(width, height, texture.format, texture.mipmapCount > 0); - float scaleX = ((float)texture.width) / width; - float scaleY = ((float)texture.height) / height; - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - ret.SetPixel(x, y, texture.GetPixel((int)(scaleX * x), (int)(scaleY * y))); - } - } - ret.Apply(); - return ret; - } - - //===============TGA Loader by aaro4130 https://forum.unity.com/threads/tga-loader-for-unity3d.172291/============== - - public static Texture2D LoadTGA(string TGAFile, bool displayProgressbar = false) - { - using (BinaryReader r = new BinaryReader(File.Open(TGAFile, FileMode.Open))) - { - byte IDLength = r.ReadByte(); - byte ColorMapType = r.ReadByte(); - byte ImageType = r.ReadByte(); - Int16 CMapStart = r.ReadInt16(); - Int16 CMapLength = r.ReadInt16(); - byte CMapDepth = r.ReadByte(); - Int16 XOffset = r.ReadInt16(); - Int16 YOffset = r.ReadInt16(); - Int16 Width = r.ReadInt16(); - Int16 Height = r.ReadInt16(); - byte PixelDepth = r.ReadByte(); - byte ImageDescriptor = r.ReadByte(); - if (ImageType == 0) - { - EditorUtility.DisplayDialog("Error", "Unsupported TGA file! No image data", "OK"); - Debug.LogError("Unsupported TGA file! No image data"); - } - else if (ImageType == 3 | ImageType == 11) - { - EditorUtility.DisplayDialog("Error", "Unsupported TGA file! 8-bit grayscale images are not supported", "OK"); - Debug.LogError("Unsupported TGA file! Not truecolor"); - } - else if (ImageType == 9 | ImageType == 10) - { - EditorUtility.DisplayDialog("Error", "Unsupported TGA file! Run-length encoded images are not supported", "OK"); - Debug.LogError("Unsupported TGA file! Colormapped"); - - } - bool startsAtTop = (ImageDescriptor & 1 << 5) >> 5 == 1; - bool startsAtRight = (ImageDescriptor & 1 << 4) >> 4 == 1; - // MsgBox("Dimensions are " Width "," Height) - Texture2D b = new Texture2D(Width, Height, TextureFormat.ARGB32, false); - Color[] colors = new Color[Width * Height]; - int texX = 0; - int texY = 0; - int index = 0; - float red = 0, green = 0, blue = 0, alpha = 0; - Byte[] bytes = r.ReadBytes((PixelDepth == 32 ? 4 : 3) * Width * Height); - - int byteIndex = 0; - for (int y = 0; y < b.height; y++) - { - if(displayProgressbar && y % 50 == 0) EditorUtility.DisplayProgressBar("Loading Raw TGA", "Loading " + TGAFile, (float)y / b.height); - for (int x = 0; x < b.width; x++) - { - texX = x; - texY = y; - if(startsAtRight) texX = b.width - x - 1; - if(startsAtTop) texY = b.height - y - 1; - index = texX + texY * b.width; - - blue = Convert.ToSingle(bytes[byteIndex++]); - green = Convert.ToSingle(bytes[byteIndex++]); - red = Convert.ToSingle(bytes[byteIndex++]); - - blue = Mathf.Pow(blue / 255, 0.45454545454f); - green = Mathf.Pow(green / 255, 0.45454545454f); - red = Mathf.Pow(red / 255, 0.45454545454f); - - // blue /= 255; - // green /= 255; - // red /= 255; - - colors[index].r = red; - colors[index].g = green; - colors[index].b = blue; - - if (PixelDepth == 32) - { - alpha = Convert.ToSingle(bytes[byteIndex++]); - alpha /= 255; - colors[index].a = alpha; - } - else - { - colors[index].a = 1; - } - } - } - b.SetPixels(colors); - b.Apply(); - if(displayProgressbar) EditorUtility.ClearProgressBar(); - - return b; - } - } - - public class VRAM - { - static Dictionary BPP = new Dictionary() - { - { TextureImporterFormat.BC7 , 8 }, - { TextureImporterFormat.DXT5 , 8 }, - { TextureImporterFormat.DXT5Crunched , 8 }, - { TextureImporterFormat.RGBA32 , 32 }, - { TextureImporterFormat.RGBA16 , 16 }, - { TextureImporterFormat.DXT1 , 4 }, - { TextureImporterFormat.DXT1Crunched , 4 }, - { TextureImporterFormat.RGB24 , 32 }, - { TextureImporterFormat.RGB16 , 16 }, - { TextureImporterFormat.BC5 , 8 }, - { TextureImporterFormat.BC4 , 4 }, - { TextureImporterFormat.R8 , 8 }, - { TextureImporterFormat.R16 , 16 }, - { TextureImporterFormat.Alpha8 , 8 }, - { TextureImporterFormat.RGBAHalf , 64 }, - { TextureImporterFormat.BC6H , 8 }, - { TextureImporterFormat.RGB9E5 , 32 }, - { TextureImporterFormat.ETC2_RGBA8Crunched , 8 }, - { TextureImporterFormat.ETC2_RGB4 , 4 }, - { TextureImporterFormat.ETC2_RGBA8 , 8 }, - { TextureImporterFormat.ETC2_RGB4_PUNCHTHROUGH_ALPHA , 4 }, - { TextureImporterFormat.PVRTC_RGB2 , 2 }, - { TextureImporterFormat.PVRTC_RGB4 , 4 }, - { TextureImporterFormat.ARGB32 , 32 }, - { TextureImporterFormat.ARGB16 , 16 }, - #if (UNITY_2020_1_OR_NEWER || UNITY_2019_4_23 || UNITY_2019_4_24 || UNITY_2019_4_25 || UNITY_2019_4_26 || UNITY_2019_4_27 || UNITY_2019_4_28 || UNITY_2019_4_29 || UNITY_2019_4_30 || UNITY_2019_4_31 || UNITY_2019_4_32 || UNITY_2019_4_33 || UNITY_2019_4_34 || UNITY_2019_4_35 || UNITY_2019_4_36 || UNITY_2019_4_37 || UNITY_2019_4_38 || UNITY_2019_4_39 || UNITY_2019_4_40) - { TextureImporterFormat.RGBA64 , 64 }, - { TextureImporterFormat.RGB48 , 64 }, - { TextureImporterFormat.RG32 , 32 }, - #endif - }; - - static Dictionary RT_BPP = new Dictionary() - { - { RenderTextureFormat.ARGB32 , 32 }, - { RenderTextureFormat.Depth , 0 }, - { RenderTextureFormat.ARGBHalf , 64 }, - { RenderTextureFormat.Shadowmap , 8 }, //guessed bpp - { RenderTextureFormat.RGB565 , 32 }, //guessed bpp - { RenderTextureFormat.ARGB4444 , 16 }, - { RenderTextureFormat.ARGB1555 , 16 }, - { RenderTextureFormat.Default , 32 }, - { RenderTextureFormat.ARGB2101010 , 32 }, - { RenderTextureFormat.DefaultHDR , 128 }, - { RenderTextureFormat.ARGB64 , 64 }, - { RenderTextureFormat.ARGBFloat , 128 }, - { RenderTextureFormat.RGFloat , 64 }, - { RenderTextureFormat.RGHalf , 32 }, - { RenderTextureFormat.RFloat , 32 }, - { RenderTextureFormat.RHalf , 16 }, - { RenderTextureFormat.R8 , 8 }, - { RenderTextureFormat.ARGBInt , 128 }, - { RenderTextureFormat.RGInt , 64 }, - { RenderTextureFormat.RInt , 32 }, - { RenderTextureFormat.BGRA32 , 32 }, - { RenderTextureFormat.RGB111110Float , 32 }, - { RenderTextureFormat.RG32 , 32 }, - { RenderTextureFormat.RGBAUShort , 64 }, - { RenderTextureFormat.RG16 , 16 }, - { RenderTextureFormat.BGRA10101010_XR , 40 }, - { RenderTextureFormat.BGR101010_XR , 30 }, - { RenderTextureFormat.R16 , 16 } - }; - - public static string ToByteString(long l) - { - if (l < 1000) return l + " B"; - if (l < 1000000) return (l / 1000f).ToString("n2") + " KB"; - if (l < 1000000000) return (l / 1000000f).ToString("n2") + " MB"; - else return (l / 1000000000f).ToString("n2") + " GB"; - } - - public static (long size, string format) CalcSize(Texture t) - { - string add = ""; - long bytesCount = 0; - - string path = AssetDatabase.GetAssetPath(t); - if (t != null && path != null && t is RenderTexture == false && t.dimension == UnityEngine.Rendering.TextureDimension.Tex2D) - { - AssetImporter assetImporter = AssetImporter.GetAtPath(path); - if (assetImporter is TextureImporter) - { - TextureImporter textureImporter = (TextureImporter)assetImporter; - TextureImporterFormat textureFormat = textureImporter.GetPlatformTextureSettings("PC").format; -#pragma warning disable CS0618 - if (textureFormat == TextureImporterFormat.AutomaticCompressed) textureFormat = textureImporter.GetAutomaticFormat("PC"); -#pragma warning restore CS0618 - - if (BPP.ContainsKey(textureFormat)) - { - add = textureFormat.ToString(); - double mipmaps = 1; - for (int i = 0; i < t.mipmapCount; i++) mipmaps += Math.Pow(0.25, i + 1); - bytesCount = (long)(BPP[textureFormat] * t.width * t.height * (textureImporter.mipmapEnabled ? mipmaps : 1) / 8); - //Debug.Log(bytesCount); - } - else - { - Debug.LogWarning("[Thry][VRAM] Does not have BPP for " + textureFormat); - } - } - else - { - bytesCount = Profiler.GetRuntimeMemorySizeLong(t); - } - } - else if (t is RenderTexture) - { - RenderTexture rt = t as RenderTexture; - double mipmaps = 1; - for (int i = 0; i < rt.mipmapCount; i++) mipmaps += Math.Pow(0.25, i + 1); - bytesCount = (long)((RT_BPP[rt.format] + rt.depth) * rt.width * rt.height * (rt.useMipMap ? mipmaps : 1) / 8); - } - else - { - bytesCount = Profiler.GetRuntimeMemorySizeLong(t); - } - - return (bytesCount, add); - } - } - } - - public class MaterialHelper - { - public static void ToggleKeyword(Material material, string keyword, bool turn_on) - { - bool is_on = material.IsKeywordEnabled(keyword); - if (is_on && !turn_on) - material.DisableKeyword(keyword); - else if (!is_on && turn_on) - material.EnableKeyword(keyword); - } - - public static void ToggleKeyword(Material[] materials, string keyword, bool on) - { - foreach (Material m in materials) - ToggleKeyword(m, keyword, on); - } - - public static void ToggleKeyword(MaterialProperty p, string keyword, bool on) - { - ToggleKeyword(p.targets as Material[], keyword, on); - } - - /// - /// Set Material Property value or Renderqueue of current Editor. - /// - /// Property Name or "render_queue" - /// - public static void SetMaterialValue(string key, string value) - { - Material[] materials = ShaderEditor.Active.Materials; - if (ShaderEditor.Active.PropertyDictionary.TryGetValue(key, out ShaderProperty p)) - { - MaterialHelper.SetMaterialPropertyValue(p.MaterialProperty, value); - p.UpdateKeywordFromValue(); - } - else if (key == "render_queue") - { - int q = 0; - if (int.TryParse(value, out q)) - { - foreach (Material m in materials) m.renderQueue = q; - } - } - else if (key == "render_type") - { - foreach (Material m in materials) m.SetOverrideTag("RenderType", value); - } - else if (key == "preview_type") - { - foreach (Material m in materials) m.SetOverrideTag("PreviewType", value); - } - else if (key == "ignore_projector") - { - foreach (Material m in materials) m.SetOverrideTag("IgnoreProjector", value); - } - } - - public static void SetMaterialPropertyValue(MaterialProperty p, string value) - { - object prev = null; - if (p.type == MaterialProperty.PropType.Texture) - { - prev = p.textureValue; - p.textureValue = AssetDatabase.LoadAssetAtPath(value); - } - else if (p.type == MaterialProperty.PropType.Float || p.type == MaterialProperty.PropType.Range) - { - prev = p.floatValue; - p.floatValue = Parser.ParseFloat(value, p.floatValue); - } -#if UNITY_2022_1_OR_NEWER - else if (p.type == MaterialProperty.PropType.Int) - { - prev = p.intValue; - p.intValue = (int)Parser.ParseFloat(value, p.intValue); - } -#endif - else if (p.type == MaterialProperty.PropType.Vector) - { - prev = p.vectorValue; - p.vectorValue = Converter.StringToVector(value); - } - else if (p.type == MaterialProperty.PropType.Color) - { - prev = p.colorValue; - p.colorValue = Converter.StringToColor(value); - } - if (p.applyPropertyCallback != null) - p.applyPropertyCallback.Invoke(p, 1, prev); - } - - public static void CopyPropertyValueFromMaterial(MaterialProperty p, Material source) - { - if (!source.HasProperty(p.name)) return; - object prev = null; - switch (p.type) - { - case MaterialProperty.PropType.Float: - case MaterialProperty.PropType.Range: - prev = p.floatValue; - p.floatValue = source.GetNumber(p); - break; -#if UNITY_2022_1_OR_NEWER - case MaterialProperty.PropType.Int: - prev = p.intValue; - p.intValue = source.GetInt(p.name); - break; -#endif - case MaterialProperty.PropType.Color: - prev = p.colorValue; - p.colorValue = source.GetColor(p.name); - break; - case MaterialProperty.PropType.Vector: - prev = p.vectorValue; - p.vectorValue = source.GetVector(p.name); - break; - case MaterialProperty.PropType.Texture: - prev = p.textureValue; - p.textureValue = source.GetTexture(p.name); - Vector2 offset = source.GetTextureOffset(p.name); - Vector2 scale = source.GetTextureScale(p.name); - p.textureScaleAndOffset = new Vector4(scale.x, scale.y, offset.x, offset.y); - break; - } - if (p.applyPropertyCallback != null) - p.applyPropertyCallback.Invoke(p, 1, prev); - } - - public static void CopyMaterialValueFromProperty(MaterialProperty target, MaterialProperty source) - { - object prev = null; - switch (target.type) - { - case MaterialProperty.PropType.Float: - case MaterialProperty.PropType.Range: - prev = target.floatValue; - target.floatValue = source.floatValue; - break; -#if UNITY_2022_1_OR_NEWER - case MaterialProperty.PropType.Int: - prev = target.intValue; - target.intValue = source.intValue; - break; -#endif - case MaterialProperty.PropType.Color: - prev = target.colorValue; - target.colorValue = source.colorValue; - break; - case MaterialProperty.PropType.Vector: - prev = target.vectorValue; - target.vectorValue = source.vectorValue; - break; - case MaterialProperty.PropType.Texture: - prev = target.textureValue; - target.textureValue = source.textureValue; - target.textureScaleAndOffset = source.textureScaleAndOffset; - break; - } - if (target.applyPropertyCallback != null) - target.applyPropertyCallback.Invoke(target, 1, prev); - } - - public static void CopyPropertyValueToMaterial(MaterialProperty source, Material target) - { - CopyMaterialValueFromProperty(MaterialEditor.GetMaterialProperty(new Material[] { target }, source.name), source); - } - } - - public class ColorHelper - { - public static Color Subtract(Color col1, Color col2) - { - return ColorMath(col1, col2, 1, -1); - } - - public static Color ColorMath(Color col1, Color col2, float multiplier1, float multiplier2) - { - return new Color(col1.r * multiplier1 + col2.r * multiplier2, col1.g * multiplier1 + col2.g * multiplier2, col1.b * multiplier1 + col2.b * multiplier2); - } - - public static float ColorDifference(Color col1, Color col2) - { - return Math.Abs(col1.r - col2.r) + Math.Abs(col1.g - col2.g) + Math.Abs(col1.b - col2.b) + Math.Abs(col1.a - col2.a); - } - } - - public class Converter - { - - public static Color StringToColor(string s) - { - s = s.Trim(new char[] { '(', ')' }); - string[] split = s.Split(",".ToCharArray()); - float[] rgba = new float[4] { 1, 1, 1, 1 }; - for (int i = 0; i < split.Length; i++) if (string.IsNullOrWhiteSpace(split[i]) == false) rgba[i] = float.Parse(split[i]); - return new Color(rgba[0], rgba[1], rgba[2], rgba[3]); - - } - - public static Vector4 StringToVector(string s) - { - s = s.Trim(new char[] { '(', ')' }); - string[] split = s.Split(",".ToCharArray()); - float[] xyzw = new float[4]; - for (int i = 0; i < 4 && i < split.Length; i++) if (string.IsNullOrWhiteSpace(split[i]) == false) xyzw[i] = float.Parse(split[i]); else xyzw[i] = 0; - return new Vector4(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); - } - - public static string ArrayToString(object[] a) - { - string ret = ""; - foreach (object o in a) - ret += o.ToString() + ","; - return ret.TrimEnd(new char[] { ',' }); - } - - public static string ArrayToString(Array a) - { - string ret = ""; - foreach (object o in a) - ret += o.ToString() + ","; - return ret.TrimEnd(new char[] { ',' }); - } - - //--Start--Gradient - public static Gradient TextureToGradient(Texture2D texture) - { - texture = Gradient_Resize(texture); - Color[] values = Gradient_Sample(texture); - //values = Gradient_Smooth(values); - Color[] delta = CalcDelta(values); - delta[0] = delta[1]; - Color[] delta_delta = CalcDelta(delta); - //PrintColorArray(delta_delta); - List changes = DeltaDeltaToChanges(delta_delta, values); - changes = RemoveChangesUnderDistanceThreshold(changes); - SortChanges(changes); - //PrintColorList(changes); - return ConstructGradient(changes, values); - } - - private static Texture2D Gradient_Resize(Texture2D texture) - { - return TextureHelper.Resize(texture, 512, 512); - } - - private static Color[] Gradient_Sample(Texture2D texture) - { - texture.wrapMode = TextureWrapMode.Clamp; - int length = texture.width; - Color[] ar = new Color[length]; - for (int i = 0; i < length; i++) - { - ar[i] = texture.GetPixel(i, i); - } - return ar; - } - - private static Color[] Gradient_Smooth(Color[] values) - { - Color[] ar = new Color[values.Length]; - ar[0] = values[0]; - ar[ar.Length - 1] = values[ar.Length - 1]; - for (int i = 1; i < values.Length - 1; i++) - { - ar[i] = new Color(); - ar[i].r = (values[i - 1].r + values[i].r + values[i + 1].r) / 3; - ar[i].g = (values[i - 1].g + values[i].g + values[i + 1].g) / 3; - ar[i].b = (values[i - 1].b + values[i].b + values[i + 1].b) / 3; - } - return ar; - } - - private static Color[] CalcDelta(Color[] values) - { - Color[] delta = new Color[values.Length]; - delta[0] = new Color(0, 0, 0); - for (int i = 1; i < values.Length; i++) - { - delta[i] = ColorSubtract(values[i - 1], values[i]); - } - return delta; - } - - private static List DeltaDeltaToChanges(Color[] deltadelta, Color[] values) - { - List changes = new List(); - for (int i = 0; i < deltadelta.Length; i++) - { - if (deltadelta[i].r != 0 || deltadelta[i].g != 0 || deltadelta[i].b != 0) - { - deltadelta[i].a = i / 512.0f; - Color[] new_change = new Color[2]; - new_change[0] = deltadelta[i]; - new_change[1] = values[i]; - changes.Add(new_change); - } - } - return changes; - } - - const float GRADIENT_DISTANCE_THRESHOLD = 0.05f; - private static List RemoveChangesUnderDistanceThreshold(List changes) - { - List new_changes = new List(); - new_changes.Add(changes[0]); - for (int i = 1; i < changes.Count; i++) - { - - if (changes[i][0].a - new_changes[new_changes.Count - 1][0].a < GRADIENT_DISTANCE_THRESHOLD) - { - if (ColorValueForDelta(new_changes[new_changes.Count - 1][0]) < ColorValueForDelta(changes[i][0])) - { - new_changes.RemoveAt(new_changes.Count - 1); - new_changes.Add(changes[i]); - } - } - else - { - new_changes.Add(changes[i]); - } - } - return new_changes; - } - - private static void SortChanges(List changes) - { - changes.Sort(delegate (Color[] x, Color[] y) - { - float sizeX = ColorValueForDelta(x[0]); - float sizeY = ColorValueForDelta(y[0]); - if (sizeX < sizeY) return 1; - else if (sizeY < sizeX) return -1; - return 0; - }); - } - - private static Gradient ConstructGradient(List changes, Color[] values) - { - List alphas = new List(); - List colors = new List(); - for (int i = 0; i < 6 && i < changes.Count; i++) - { - colors.Add(new GradientColorKey(changes[i][1], changes[i][0].a)); - //Debug.Log("key " + changes[i][0].a); - } - colors.Add(new GradientColorKey(values[0], 0)); - colors.Add(new GradientColorKey(values[values.Length - 1], 1)); - alphas.Add(new GradientAlphaKey(1, 0)); - alphas.Add(new GradientAlphaKey(1, 1)); - Gradient gradient = new Gradient(); - gradient.SetKeys(colors.ToArray(), alphas.ToArray()); - return gradient; - } - - private static void PrintColorArray(Color[] ar) - { - foreach (Color c in ar) - Debug.Log(c.ToString()); - } - private static void PrintColorList(List ar) - { - foreach (Color[] x in ar) - Debug.Log(ColorValueForDelta(x[0]) + ":" + x[0].ToString()); - } - - private static float ColorValueForDelta(Color col) - { - return Mathf.Abs(col.r) + Mathf.Abs(col.g) + Mathf.Abs(col.b); - } - - private static Color ColorAdd(Color col1, Color col2) - { - return new Color(col1.r + col2.r, col1.g + col2.g, col1.b + col2.b); - } - private static Color ColorSubtract(Color col1, Color col2) - { - return new Color(col1.r - col2.r, col1.g - col2.g, col1.b - col2.b); - } - - public static Texture2D ColorToTexture(Color color, int width, int height) - { - width = Mathf.Max(0, Mathf.Min(8192, width)); - height = Mathf.Max(0, Mathf.Min(8192, height)); - Texture2D texture = new Texture2D(width, height); - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - texture.SetPixel(x, y, color); - } - } - texture.Apply(); - return texture; - } - - public static Texture2D GradientToTexture(Gradient gradient, int width, int height, bool vertical = false) - { - width = Mathf.Max(0, Mathf.Min(8192, width)); - height = Mathf.Max(0, Mathf.Min(8192, height)); - Texture2D texture = new Texture2D(width, height); - Color col; - if(vertical) - { - for (int y = 0; y < height; y++) - { - col = gradient.Evaluate((float)y / height); - for (int x = 0; x < width; x++) texture.SetPixel(x, y, col); - } - }else - { - for (int x = 0; x < width; x++) - { - col = gradient.Evaluate((float)x / width); - for (int y = 0; y < height; y++) texture.SetPixel(x, y, col); - } - } - texture.wrapMode = TextureWrapMode.Clamp; - texture.filterMode = FilterMode.Bilinear; - texture.Apply(); - return texture; - } - - //--End--Gradient - - public static Texture2D CurveToTexture(AnimationCurve curve, TextureData texture_settings) - { - Texture2D texture = new Texture2D(texture_settings.width, texture_settings.height); - for (int i = 0; i < texture_settings.width; i++) - { - Color color = new Color(); - float value = curve.Evaluate((float)i / texture_settings.width); - value = Mathf.Clamp01(value); - if (texture_settings.channel == 'r') - color.r = value; - else if (texture_settings.channel == 'g') - color.g = value; - else if (texture_settings.channel == 'b') - color.b = value; - else if (texture_settings.channel == 'a') - color.a = value; - if (texture_settings.channel != 'a') - color.a = 1; - for (int y = 0; y < texture_settings.height; y++) - texture.SetPixel(i, y, color); - } - texture.Apply(); - texture_settings.ApplyModes(texture); - return texture; - } - - //==============Texture Array================= - - [MenuItem("Assets/Thry/Flipbooks/Images 2 TextureArray",false, 303)] - static void SelectionImagesToTextureArray() - { - string[] paths = Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)).ToArray(); - PathsToTexture2DArray(paths); - } - - [MenuItem("Assets/Thry/Flipbooks/Images 2 TextureArray", true)] - static bool SelectionImagesToTextureArrayValidator() - { - if (Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 0) - { - return Selection.assetGUIDs.All(g => Regex.IsMatch(AssetDatabase.GUIDToAssetPath(g), @".*\.(png)|(jpg)")); - } - return false; - } - - public static Texture2DArray PathsToTexture2DArray(string[] paths) - { - if (paths.Length == 0) - return null; - if (paths[0].EndsWith(".gif")) - { - return Converter.GifToTextureArray(paths[0]); - } - else - { -#if SYSTEM_DRAWING - Texture2D[] wew = paths.Where(p=> AssetDatabase.GetMainAssetTypeAtPath(p).IsAssignableFrom(typeof(Texture2D))).Select(p => AssetDatabase.LoadAssetAtPath(p)).ToArray(); - Array.Sort(wew, (UnityEngine.Object one, UnityEngine.Object two) => one.name.CompareTo(two.name)); - Selection.objects = wew; - Texture2DArray texture2DArray = new Texture2DArray(wew[0].width, wew[0].height, wew.Length, wew[0].format, true); - - string assetPath = AssetDatabase.GetAssetPath(wew[0]); - assetPath = assetPath.Remove(assetPath.LastIndexOf('/')) + "/Texture2DArray.asset"; - - for (int i = 0; i < wew.Length; i++) - { - for (int m = 0; m < wew[i].mipmapCount; m++) - { - Graphics.CopyTexture(wew[i], 0, m, texture2DArray, i, m); - } - } - - texture2DArray.anisoLevel = wew[0].anisoLevel; - texture2DArray.wrapModeU = wew[0].wrapModeU; - texture2DArray.wrapModeV = wew[0].wrapModeV; - texture2DArray.Apply(false, true); - - AssetDatabase.CreateAsset(texture2DArray, assetPath); - AssetDatabase.SaveAssets(); - - Selection.activeObject = texture2DArray; - return texture2DArray; -#else - return null; -#endif - } - } - - [MenuItem("Assets/Thry/Flipbooks/Gif 2 TextureArray",false, 303)] - static void SelectionGifToTextureArray() - { - GifToTextureArray(AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0])); - } - - [MenuItem("Assets/Thry/Flipbooks/Gif 2 TextureArray", true)] - static bool SelectionGifToTextureArrayValidator() - { - if (Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 0) - { - return AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]).EndsWith(".gif"); - } - return false; - } - - public static Texture2DArray GifToTextureArray(string path) - { - List array = GetGifFrames(path); - if (array == null) return null; - if (array.Count == 0) - { - Debug.LogError("Gif is empty or System.Drawing is not working. Try right clicking and reimporting the \"Thry Editor\" Folder!"); - return null; - } - Texture2DArray arrayTexture = Textre2DArrayToAsset(array.ToArray()); - AssetDatabase.CreateAsset(arrayTexture, path.Replace(".gif", ".asset")); - AssetDatabase.SaveAssets(); - return arrayTexture; - } - - public static List GetGifFrames(string path) - { - List gifFrames = new List(); -#if SYSTEM_DRAWING - var gifImage = System.Drawing.Image.FromFile(path); - var dimension = new System.Drawing.Imaging.FrameDimension(gifImage.FrameDimensionsList[0]); - - int width = Mathf.ClosestPowerOfTwo(gifImage.Width - 1); - int height = Mathf.ClosestPowerOfTwo(gifImage.Height - 1); - - bool hasAlpha = false; - - int frameCount = gifImage.GetFrameCount(dimension); - - float totalProgress = frameCount * width; - for (int i = 0; i < frameCount; i++) - { - gifImage.SelectActiveFrame(dimension, i); - var ogframe = new System.Drawing.Bitmap(gifImage.Width, gifImage.Height); - System.Drawing.Graphics.FromImage(ogframe).DrawImage(gifImage, System.Drawing.Point.Empty); - var frame = ResizeBitmap(ogframe, width, height); - - Texture2D frameTexture = new Texture2D(frame.Width, frame.Height); - - float doneProgress = i * width; - for (int x = 0; x < frame.Width; x++) - { - if (x % 20 == 0) - if (EditorUtility.DisplayCancelableProgressBar("From GIF", "Frame " + i + ": " + (int)((float)x / width * 100) + "%", (doneProgress + x + 1) / totalProgress)) - { - EditorUtility.ClearProgressBar(); - return null; - } - - for (int y = 0; y < frame.Height; y++) - { - System.Drawing.Color sourceColor = frame.GetPixel(x, y); - frameTexture.SetPixel(x, frame.Height - 1 - y, new UnityEngine.Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A)); - if (sourceColor.A < 255.0f) - { - hasAlpha = true; - } - } - } - - frameTexture.Apply(); - gifFrames.Add(frameTexture); - } - EditorUtility.ClearProgressBar(); - //Debug.Log("has alpha? " + hasAlpha); - for (int i = 0; i < frameCount; i++) - { - EditorUtility.CompressTexture(gifFrames[i], hasAlpha ? TextureFormat.DXT5 : TextureFormat.DXT1, UnityEditor.TextureCompressionQuality.Normal); - gifFrames[i].Apply(true, false); - } -#endif - return gifFrames; - } - -#if SYSTEM_DRAWING - public static System.Drawing.Bitmap ResizeBitmap(System.Drawing.Image image, int width, int height) - { - var destRect = new System.Drawing.Rectangle(0, 0, width, height); - var destImage = new System.Drawing.Bitmap(width, height); - - destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); - - using (var graphics = System.Drawing.Graphics.FromImage(destImage)) - { - graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; - graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; - graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; - graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; - graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; - - using (var wrapMode = new System.Drawing.Imaging.ImageAttributes()) - { - wrapMode.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); - graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel, wrapMode); - } - } - - return destImage; - } -#endif - - private static Texture2DArray Textre2DArrayToAsset(Texture2D[] array) - { - Texture2DArray texture2DArray = new Texture2DArray(array[0].width, array[0].height, array.Length, array[0].format, true); - -#if SYSTEM_DRAWING - for (int i = 0; i < array.Length; i++) - { - for (int m = 0; m < array[i].mipmapCount; m++) - { - UnityEngine.Graphics.CopyTexture(array[i], 0, m, texture2DArray, i, m); - } - } -#endif - - texture2DArray.anisoLevel = array[0].anisoLevel; - texture2DArray.wrapModeU = array[0].wrapModeU; - texture2DArray.wrapModeV = array[0].wrapModeV; - - texture2DArray.Apply(false, true); - - return texture2DArray; - } - } - - public class ShaderHelper - { - - private static Dictionary> shader_property_drawers = new Dictionary>(); - public static string[] GetDrawer(MaterialProperty property) - { - Shader shader = ((Material)property.targets[0]).shader; - - if (!shader_property_drawers.ContainsKey(shader)) - LoadShaderPropertyDrawers(shader); - - Dictionary property_drawers = shader_property_drawers[shader]; - if (property_drawers.ContainsKey(property.name)) - return property_drawers[property.name]; - return null; - } - - public static void LoadShaderPropertyDrawers(Shader shader) - { - string path = AssetDatabase.GetAssetPath(shader); - string code = FileHelper.ReadFileIntoString(path); - code = Helper.GetStringBetweenBracketsAndAfterId(code, "Properties", new char[] { '{', '}' }); - MatchCollection matchCollection = Regex.Matches(code, @"\[.*\].*(?=\()"); - Dictionary property_drawers = new Dictionary(); - foreach (Match match in matchCollection) - { - string[] drawers_or_flag_code = GetDrawersFlagsCode(match.Value); - string drawer_code = GetNonFlagDrawer(drawers_or_flag_code); - if (drawer_code == null) - continue; - - string property_name = Regex.Match(match.Value, @"(?<=\])[^\[]*$").Value.Trim(); - - List drawer_and_parameters = new List(); - drawer_and_parameters.Add(Regex.Split(drawer_code, @"\(")[0]); - - GetDrawerParameters(drawer_code, drawer_and_parameters); - - property_drawers[property_name] = drawer_and_parameters.ToArray(); - } - shader_property_drawers[shader] = property_drawers; - } - - private static void GetDrawerParameters(string code, List list) - { - MatchCollection matchCollection = Regex.Matches(code, @"(?<=\(|,).*?(?=\)|,)"); - foreach (Match m in matchCollection) - list.Add(m.Value); - } - - private static string GetNonFlagDrawer(string[] codes) - { - foreach (string c in codes) - if (!DrawerIsFlag(c)) - return c; - return null; - } - - private static bool DrawerIsFlag(string code) - { - return (code == "HideInInspector" || code == "NoScaleOffset" || code == "Normal" || code == "HDR" || code == "Gamma" || code == "PerRendererData"); - } - - private static string[] GetDrawersFlagsCode(string line) - { - MatchCollection matchCollection = Regex.Matches(line, @"(?<=\[).*?(?=\])"); - string[] codes = new string[matchCollection.Count]; - int i = 0; - foreach (Match m in matchCollection) - codes[i++] = m.Value; - return codes; - } - //------------Track ShaderEditor shaders------------------- - - // [MenuItem("Thry/Shader Editor/Test")] - // public static void Test() - // { - // Shader shader = Shader.Find(".poiyomi/Poiyomi 8.1/Poiyomi Pro"); - // Debug.Log(IsShaderUsingThryEditor(shader)); - // } - - public static bool IsShaderUsingThryEditor(Shader shader) - { - return IsShaderUsingThryEditor(new Material(shader)); - } - public static bool IsShaderUsingThryEditor(Material material) - { - return IsShaderUsingThryEditor(MaterialEditor.CreateEditor(material) as MaterialEditor); - } - public static bool IsShaderUsingThryEditor(MaterialEditor materialEditor) - { - PropertyInfo shaderGUIProperty = typeof(MaterialEditor).GetProperty("customShaderGUI"); - var gui = shaderGUIProperty.GetValue(materialEditor); - // gui is null for some shaders. I think it has to do with packages maybe - return (gui != null) && gui.GetType() == typeof(ShaderEditor); - } - - internal static List<(string prop, List keywords)> GetPropertyKeywordsForShader(Shader s) - { - List<(string prop, List keywords)> list = new List<(string prop, List keywords)>(); - - for (int i = 0; i < s.GetPropertyCount(); i++) - { - if (s.GetPropertyType(i) == UnityEngine.Rendering.ShaderPropertyType.Float) - { - string prop = s.GetPropertyName(i); - List keywords = null; - keywords = GetKeywordsFromShaderProperty(s, prop); - - if(keywords.Count == 0) - continue; - else - list.Add((prop, keywords)); - } - } - - return list; - } - - // Logic Adapted from unity's reference implementation - /// Returns a list of keywords for a given shader property. - internal static List GetKeywordsFromShaderProperty(Shader shader, string propertyName) - { - List keywords = new List(); - if (string.IsNullOrEmpty(propertyName)) - return keywords; - - int propertyIndex = shader.FindPropertyIndex(propertyName); - if (propertyIndex < 0) - return keywords; - - string[] attributes = shader.GetPropertyAttributes(propertyIndex); - if (attributes.Length == 0 || attributes == null) - return keywords; - - foreach (string attribute in attributes) - { - string args = ""; - // Regex based on Unity's reference implementation: Match a string of the form Keyword(Argument) and capture its components - // (\w+) - Match a word (keyword name) - // \s*\(\s* - Match an opening parenthesis, allowing whitespace before and after - // ([^)]*) - Match any number of characters that are not a closing parenthesis, and capture them into a group - // \s*\) - Match a closing parenthesis, allowing whitespace before and after - const string propertyDrawerRegex = @"(\w+)\s*\(\s*([^)]*)\s*\)"; - - Match regexMatch = Regex.Match(attribute, propertyDrawerRegex); - if (regexMatch.Success) - { - string className = regexMatch.Groups[1].Value; - args = regexMatch.Groups[2].Value.Trim(); - - // Note that we don't handle ToggleOff as it would require extra logic to differentiate - if(className == "Toggle") // Unity Toggle drawer, toggles a keyword directly if provided as [Toggle(KEYWORD)] and toggles PropertyName - { - if(string.IsNullOrEmpty(args)) - keywords.Add(GetUnityKeywordName(propertyName, "ON")); - else - keywords.Add(args); - break; - } - else if(className == "ThryToggle") // Thry Toggle drawer, toggles a keyword directly if provided as [Toggle(KEYWORD)] - { - // We only care about the first argument, the second is for UI - if(args.Contains(",")) - args = args.Split(',')[0]; - - // Ignore ThryToggle's bools, since otherwise we get keywords that have the same name as HLSL language keywords - if(args != "false" && args != "true") - keywords.Add(args); - - break; - } - else if(className == "KeywordEnum") // Keyword enum, enables one keyword out of a list of keywords provided as [KeywordEnum(KEYWORD1,KEYWORD2,KEYWORD3)] - { - string[] enumArgs = args.Split(','); - foreach(var enumArg in enumArgs) - { - keywords.Add(GetUnityKeywordName(propertyName, enumArg.Trim())); - } - - break; - } - } - } - return keywords; - } - - // Logic from Unity defaults - /// Gets a formatted Keyword name from a shader property name and a keyword name. - private static string GetUnityKeywordName(string propertyName, string keywordName) => $"{propertyName}_{keywordName}".Replace(' ', '_').ToUpperInvariant(); - } - - public class StringHelper - { - public static string GetBetween(string value, string prefix, string postfix) - { - return GetBetween(value, prefix, postfix, value); - } - - public static string GetBetween(string value, string prefix, string postfix, string fallback) - { - string pattern = @"(?<=" + prefix + ").*?(?=" + postfix + ")"; - Match m = Regex.Match(value, pattern); - if (m.Success) - return m.Value; - return fallback; - } - - //returns data for name:{data} even if data containss brakets - public static string GetBracket(string data, string bracketName) - { - Match m = Regex.Match(data, bracketName + ":"); - if (m.Success) - { - int startIndex = m.Index + bracketName.Length + 2; - int i = startIndex; - int depth = 0; - while (++i < data.Length) - { - if (data[i] == '{') - depth++; - else if (data[i] == '}') - { - if (depth == 0) - break; - depth--; - } - } - return data.Substring(startIndex, i - startIndex); - } - return data; - } - } - - public class VRCInterface - { - private static VRCInterface _Instance; - public static VRCInterface Get() - { - if (_Instance == null) _Instance = new VRCInterface(); - return _Instance; - } - public static void Update() - { - _Instance = new VRCInterface(); - } - - public SDK_Information Sdk_information; - - public class SDK_Information - { - public VRC_SDK_Type type; - public string installed_version = "0"; - } - - public enum VRC_SDK_Type - { - NONE = 0, - SDK_2 = 1, - SDK_3_Avatar = 2, - SDK_3_World = 3 - } - - private VRCInterface() - { - Sdk_information = new SDK_Information(); - Sdk_information.type = GetInstalledSDKType(); - InitInstalledSDKVersionAndPaths(); - } - - private void InitInstalledSDKVersionAndPaths() - { - string[] guids = AssetDatabase.FindAssets("version"); - string path = null; - foreach (string guid in guids) - { - string p = AssetDatabase.GUIDToAssetPath(guid); - if (p.Contains("VRCSDK/version")) - path = p; - } - if (path == null || !File.Exists(path)) - return; - string persistent = PersistentData.Get("vrc_sdk_version"); - if (persistent != null) - Sdk_information.installed_version = persistent; - else - Sdk_information.installed_version = Regex.Replace(FileHelper.ReadFileIntoString(path), @"\n?\r", ""); - } - - public static VRC_SDK_Type GetInstalledSDKType() - { -#if VRC_SDK_VRCSDK3 && UDON - return VRC_SDK_Type.SDK_3_World; -#elif VRC_SDK_VRCSDK3 - return VRC_SDK_Type.SDK_3_Avatar; -#elif VRC_SDK_VRCSDK2 - return VRC_SDK_Type.SDK_2; -#else - return VRC_SDK_Type.NONE; -#endif - } - - public static bool IsVRCSDKInstalled() - { -#if VRC_SDK_VRCSDK3 - return true; -#elif VRC_SDK_VRCSDK2 - return true; -#else - return false; -#endif - } - } - - //Adapted from https://github.com/lukis101/VRCUnityStuffs/blob/master/Scripts/Editor/MaterialCleaner.cs - //MIT License - - //Copyright (c) 2019 Dj Lukis.LT - - //Permission is hereby granted, free of charge, to any person obtaining a copy - //of this software and associated documentation files (the "Software"), to deal - //in the Software without restriction, including without limitation the rights - //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - //copies of the Software, and to permit persons to whom the Software is - //furnished to do so, subject to the following conditions: - - //The above copyright notice and this permission notice shall be included in all - //copies or substantial portions of the Software. - - //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - //SOFTWARE. - public class MaterialCleaner - { - public enum CleanPropertyType { Texture,Float,Color } - - private const string PropPath_Tex = "m_SavedProperties.m_TexEnvs"; - private const string PropPath_Float = "m_SavedProperties.m_Floats"; - private const string PropPath_Col = "m_SavedProperties.m_Colors"; - - static string GetPath(CleanPropertyType type) - { - if (type == CleanPropertyType.Float) return PropPath_Float; - if (type == CleanPropertyType.Color) return PropPath_Col; - return PropPath_Tex; - } - public static int CountAllUnusedProperties(params Material[] materials) - {; - return materials.Sum(m => - { - int count = 0; - SerializedObject serObj = new SerializedObject(m); - count += CountUnusedProperties(m, serObj, CleanPropertyType.Texture); - count += CountUnusedProperties(m, serObj, CleanPropertyType.Float); - count += CountUnusedProperties(m, serObj, CleanPropertyType.Color); - return count; - }); - } - private static int CountUnusedProperties(Material mat, SerializedObject serObj, CleanPropertyType type, List list = null) - { - var properties = serObj.FindProperty(GetPath(type)); - int count = 0; - if (properties != null && properties.isArray) - { - for (int i = 0; i < properties.arraySize; i++) - { - string propName = properties.GetArrayElementAtIndex(i).displayName; - if (!mat.HasProperty(propName)) - { - if (list!=null) list.Add(propName); - count++; - } - } - } - return count; - } - public static int ListUnusedProperties(CleanPropertyType type, params Material[] materials) - { - List list = new List(); - int count = materials.Sum(m => CountUnusedProperties(m, new SerializedObject(m), type, list)); - if(count > 0) ShaderEditor.Out($"Unbound properties of type {type}", list.Distinct().Select(s => $"↳{s}")); - return count; - } - public static int CountUnusedProperties(CleanPropertyType type, params Material[] materials) - { - return materials.Sum(m => CountUnusedProperties(m, new SerializedObject(m), type)); - } - - private static int RemoveUnusedProperties(Material mat, SerializedObject serObj, CleanPropertyType type) - { - if (!mat.shader.isSupported) - { - Debug.LogWarning("Skipping \"" + mat.name + "\" cleanup because shader is unsupported!"); - return 0; - } - Undo.RecordObject(mat, "Material property cleanup"); - int removedprops = 0; - string path = PropPath_Tex; - if (type == CleanPropertyType.Float) path = PropPath_Float; - if (type == CleanPropertyType.Color) path = PropPath_Col; - var properties = serObj.FindProperty(path); - if (properties != null && properties.isArray) - { - int amount = properties.arraySize; - for (int i = amount - 1; i >= 0; i--) // reverse loop because array gets modified - { - string propName = properties.GetArrayElementAtIndex(i).displayName; - if (!mat.HasProperty(propName)) - { - properties.DeleteArrayElementAtIndex(i); - removedprops++; - } - } - if (removedprops > 0) - serObj.ApplyModifiedProperties(); - } - return removedprops; - } - public static int RemoveUnusedProperties(CleanPropertyType type, params Material[] materials) - { - return materials.Sum(m => RemoveUnusedProperties(m, new SerializedObject(m), type)); - } - private static int RemoveAllUnusedProperties(Material mat, SerializedObject serObj) - { - int removedprops = 0; - removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Texture); - removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Float); - removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Color); - - Debug.Log("Removed " + removedprops + " unused properties from " + mat.name); - return removedprops; - } - public static int RemoveAllUnusedProperties(CleanPropertyType type, params Material[] materials) - { - return materials.Sum(m => RemoveAllUnusedProperties(m, new SerializedObject(m))); - } - private static void ClearKeywords(Material mat) - { - Undo.RecordObject(mat, "Material keyword clear"); - string[] keywords = mat.shaderKeywords; - mat.shaderKeywords = new string[0]; - } - } -} diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/HelperWeb.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/HelperWeb.cs index 8a5a69a5..204fe64d 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/HelperWeb.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/HelperWeb.cs @@ -41,11 +41,13 @@ public static string GetFinalRedirect(string url) bool fetching = true; while (fetching) { +#pragma warning disable CS0618 // Type or member is obsolete if (request.isHttpError || request.isNetworkError) { fetching = false; Debug.Log(request.error); } +#pragma warning restore CS0618 // Type or member is obsolete if (request.isDone) { fetching = false; diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers.meta new file mode 100644 index 00000000..a68c3d30 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6498eb13f17ca7648b8c38c0db2fbf8c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs new file mode 100644 index 00000000..85af49aa --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class ColorHelper + { + public static Color Subtract(Color col1, Color col2) + { + return ColorMath(col1, col2, 1, -1); + } + + public static Color ColorMath(Color col1, Color col2, float multiplier1, float multiplier2) + { + return new Color(col1.r * multiplier1 + col2.r * multiplier2, col1.g * multiplier1 + col2.g * multiplier2, col1.b * multiplier1 + col2.b * multiplier2); + } + + public static float ColorDifference(Color col1, Color col2) + { + return Math.Abs(col1.r - col2.r) + Math.Abs(col1.g - col2.g) + Math.Abs(col1.b - col2.b) + Math.Abs(col1.a - col2.a); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs.meta new file mode 100644 index 00000000..08b3749d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ColorHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fa0034b2f91cc3e4c95c2f88b96706ca +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs new file mode 100644 index 00000000..9cdac03e --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class Converter + { + + public static Color StringToColor(string s) + { + s = s.Trim(new char[] { '(', ')' }); + string[] split = s.Split(",".ToCharArray()); + float[] rgba = new float[4] { 1, 1, 1, 1 }; + for (int i = 0; i < split.Length; i++) if (string.IsNullOrWhiteSpace(split[i]) == false) rgba[i] = float.Parse(split[i]); + return new Color(rgba[0], rgba[1], rgba[2], rgba[3]); + + } + + public static Vector4 StringToVector(string s) + { + s = s.Trim(new char[] { '(', ')' }); + string[] split = s.Split(",".ToCharArray()); + float[] xyzw = new float[4]; + for (int i = 0; i < 4 && i < split.Length; i++) if (string.IsNullOrWhiteSpace(split[i]) == false) xyzw[i] = float.Parse(split[i]); else xyzw[i] = 0; + return new Vector4(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); + } + + public static string ArrayToString(object[] a) + { + string ret = ""; + foreach (object o in a) + ret += o.ToString() + ","; + return ret.TrimEnd(new char[] { ',' }); + } + + public static string ArrayToString(Array a) + { + string ret = ""; + foreach (object o in a) + ret += o.ToString() + ","; + return ret.TrimEnd(new char[] { ',' }); + } + + //--Start--Gradient + public static Gradient TextureToGradient(Texture2D texture) + { + texture = Gradient_Resize(texture); + Color[] values = Gradient_Sample(texture); + //values = Gradient_Smooth(values); + Color[] delta = CalcDelta(values); + delta[0] = delta[1]; + Color[] delta_delta = CalcDelta(delta); + //PrintColorArray(delta_delta); + List changes = DeltaDeltaToChanges(delta_delta, values); + changes = RemoveChangesUnderDistanceThreshold(changes); + SortChanges(changes); + //PrintColorList(changes); + return ConstructGradient(changes, values); + } + + private static Texture2D Gradient_Resize(Texture2D texture) + { + return TextureHelper.Resize(texture, 512, 512); + } + + private static Color[] Gradient_Sample(Texture2D texture) + { + texture.wrapMode = TextureWrapMode.Clamp; + int length = texture.width; + Color[] ar = new Color[length]; + for (int i = 0; i < length; i++) + { + ar[i] = texture.GetPixel(i, i); + } + return ar; + } + + private static Color[] Gradient_Smooth(Color[] values) + { + Color[] ar = new Color[values.Length]; + ar[0] = values[0]; + ar[ar.Length - 1] = values[ar.Length - 1]; + for (int i = 1; i < values.Length - 1; i++) + { + ar[i] = new Color(); + ar[i].r = (values[i - 1].r + values[i].r + values[i + 1].r) / 3; + ar[i].g = (values[i - 1].g + values[i].g + values[i + 1].g) / 3; + ar[i].b = (values[i - 1].b + values[i].b + values[i + 1].b) / 3; + } + return ar; + } + + private static Color[] CalcDelta(Color[] values) + { + Color[] delta = new Color[values.Length]; + delta[0] = new Color(0, 0, 0); + for (int i = 1; i < values.Length; i++) + { + delta[i] = ColorSubtract(values[i - 1], values[i]); + } + return delta; + } + + private static List DeltaDeltaToChanges(Color[] deltadelta, Color[] values) + { + List changes = new List(); + for (int i = 0; i < deltadelta.Length; i++) + { + if (deltadelta[i].r != 0 || deltadelta[i].g != 0 || deltadelta[i].b != 0) + { + deltadelta[i].a = i / 512.0f; + Color[] new_change = new Color[2]; + new_change[0] = deltadelta[i]; + new_change[1] = values[i]; + changes.Add(new_change); + } + } + return changes; + } + + const float GRADIENT_DISTANCE_THRESHOLD = 0.05f; + private static List RemoveChangesUnderDistanceThreshold(List changes) + { + List new_changes = new List(); + new_changes.Add(changes[0]); + for (int i = 1; i < changes.Count; i++) + { + + if (changes[i][0].a - new_changes[new_changes.Count - 1][0].a < GRADIENT_DISTANCE_THRESHOLD) + { + if (ColorValueForDelta(new_changes[new_changes.Count - 1][0]) < ColorValueForDelta(changes[i][0])) + { + new_changes.RemoveAt(new_changes.Count - 1); + new_changes.Add(changes[i]); + } + } + else + { + new_changes.Add(changes[i]); + } + } + return new_changes; + } + + private static void SortChanges(List changes) + { + changes.Sort(delegate (Color[] x, Color[] y) + { + float sizeX = ColorValueForDelta(x[0]); + float sizeY = ColorValueForDelta(y[0]); + if (sizeX < sizeY) return 1; + else if (sizeY < sizeX) return -1; + return 0; + }); + } + + private static Gradient ConstructGradient(List changes, Color[] values) + { + List alphas = new List(); + List colors = new List(); + for (int i = 0; i < 6 && i < changes.Count; i++) + { + colors.Add(new GradientColorKey(changes[i][1], changes[i][0].a)); + //Debug.Log("key " + changes[i][0].a); + } + colors.Add(new GradientColorKey(values[0], 0)); + colors.Add(new GradientColorKey(values[values.Length - 1], 1)); + alphas.Add(new GradientAlphaKey(1, 0)); + alphas.Add(new GradientAlphaKey(1, 1)); + Gradient gradient = new Gradient(); + gradient.SetKeys(colors.ToArray(), alphas.ToArray()); + return gradient; + } + + private static void PrintColorArray(Color[] ar) + { + foreach (Color c in ar) + Debug.Log(c.ToString()); + } + private static void PrintColorList(List ar) + { + foreach (Color[] x in ar) + Debug.Log(ColorValueForDelta(x[0]) + ":" + x[0].ToString()); + } + + private static float ColorValueForDelta(Color col) + { + return Mathf.Abs(col.r) + Mathf.Abs(col.g) + Mathf.Abs(col.b); + } + + private static Color ColorAdd(Color col1, Color col2) + { + return new Color(col1.r + col2.r, col1.g + col2.g, col1.b + col2.b); + } + private static Color ColorSubtract(Color col1, Color col2) + { + return new Color(col1.r - col2.r, col1.g - col2.g, col1.b - col2.b); + } + + public static Texture2D ColorToTexture(Color color, int width, int height) + { + width = Mathf.Max(0, Mathf.Min(8192, width)); + height = Mathf.Max(0, Mathf.Min(8192, height)); + Texture2D texture = new Texture2D(width, height); + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + texture.SetPixel(x, y, color); + } + } + texture.Apply(); + return texture; + } + + public static Texture2D GradientToTexture(Gradient gradient, int width, int height, bool vertical = false) + { + width = Mathf.Max(0, Mathf.Min(8192, width)); + height = Mathf.Max(0, Mathf.Min(8192, height)); + Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA64, false); + Color col; + if (vertical) + { + for (int y = 0; y < height; y++) + { + col = gradient.Evaluate((float)y / height); + for (int x = 0; x < width; x++) texture.SetPixel(x, y, col); + } + } + else + { + for (int x = 0; x < width; x++) + { + col = gradient.Evaluate((float)x / width); + for (int y = 0; y < height; y++) texture.SetPixel(x, y, col); + } + } + texture.wrapMode = TextureWrapMode.Clamp; + texture.filterMode = FilterMode.Bilinear; + texture.Apply(); + return texture; + } + + //--End--Gradient + + public static Texture2D CurveToTexture(AnimationCurve curve, TextureData texture_settings) + { + Texture2D texture = new Texture2D(texture_settings.width, texture_settings.height); + for (int i = 0; i < texture_settings.width; i++) + { + Color color = new Color(); + float value = curve.Evaluate((float)i / texture_settings.width); + value = Mathf.Clamp01(value); + if (texture_settings.channel == 'r') + color.r = value; + else if (texture_settings.channel == 'g') + color.g = value; + else if (texture_settings.channel == 'b') + color.b = value; + else if (texture_settings.channel == 'a') + color.a = value; + if (texture_settings.channel != 'a') + color.a = 1; + for (int y = 0; y < texture_settings.height; y++) + texture.SetPixel(i, y, color); + } + texture.Apply(); + texture_settings.ApplyModes(texture); + return texture; + } + + //==============Texture Array================= + + [MenuItem("Assets/Thry/Flipbooks/Images 2 TextureArray", false, 303)] + static void SelectionImagesToTextureArray() + { + string[] paths = Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)).ToArray(); + PathsToTexture2DArray(paths); + } + + [MenuItem("Assets/Thry/Flipbooks/Images 2 TextureArray", true)] + static bool SelectionImagesToTextureArrayValidator() + { + if (Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 0) + { + return Selection.assetGUIDs.All(g => Regex.IsMatch(AssetDatabase.GUIDToAssetPath(g), @".*\.(png)|(jpg)")); + } + return false; + } + + public static Texture2DArray PathsToTexture2DArray(string[] paths) + { + if (paths.Length == 0) + return null; + if (paths[0].EndsWith(".gif")) + { + return Converter.GifToTextureArray(paths[0]); + } + else + { +#if SYSTEM_DRAWING + Texture2D[] wew = paths.Where(p => AssetDatabase.GetMainAssetTypeAtPath(p).IsAssignableFrom(typeof(Texture2D))).Select(p => AssetDatabase.LoadAssetAtPath(p)).ToArray(); + Array.Sort(wew, (UnityEngine.Object one, UnityEngine.Object two) => one.name.CompareTo(two.name)); + Selection.objects = wew; + Texture2DArray texture2DArray = new Texture2DArray(wew[0].width, wew[0].height, wew.Length, wew[0].format, true); + + string assetPath = AssetDatabase.GetAssetPath(wew[0]); + assetPath = assetPath.Remove(assetPath.LastIndexOf('/')) + "/Texture2DArray.asset"; + + for (int i = 0; i < wew.Length; i++) + { + for (int m = 0; m < wew[i].mipmapCount; m++) + { + Graphics.CopyTexture(wew[i], 0, m, texture2DArray, i, m); + } + } + + texture2DArray.anisoLevel = wew[0].anisoLevel; + texture2DArray.wrapModeU = wew[0].wrapModeU; + texture2DArray.wrapModeV = wew[0].wrapModeV; + texture2DArray.Apply(false, true); + + AssetDatabase.CreateAsset(texture2DArray, assetPath); + AssetDatabase.SaveAssets(); + + Selection.activeObject = texture2DArray; + return texture2DArray; +#else + return null; +#endif + } + } + + [MenuItem("Assets/Thry/Flipbooks/Gif 2 TextureArray", false, 303)] + static void SelectionGifToTextureArray() + { + GifToTextureArray(AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0])); + } + + [MenuItem("Assets/Thry/Flipbooks/Gif 2 TextureArray", true)] + static bool SelectionGifToTextureArrayValidator() + { + if (Selection.assetGUIDs != null && Selection.assetGUIDs.Length > 0) + { + return AssetDatabase.GUIDToAssetPath(Selection.assetGUIDs[0]).EndsWith(".gif"); + } + return false; + } + + public static Texture2DArray GifToTextureArray(string path) + { + List array = GetGifFrames(path); + if (array == null) return null; + if (array.Count == 0) + { + Debug.LogError("Gif is empty or System.Drawing is not working. Try right clicking and reimporting the \"Thry Editor\" Folder!"); + return null; + } + Texture2DArray arrayTexture = Textre2DArrayToAsset(array.ToArray()); + AssetDatabase.CreateAsset(arrayTexture, path.Replace(".gif", ".asset")); + AssetDatabase.SaveAssets(); + return arrayTexture; + } + + public static List GetGifFrames(string path) + { + List gifFrames = new List(); +#if SYSTEM_DRAWING + var gifImage = System.Drawing.Image.FromFile(path); + var dimension = new System.Drawing.Imaging.FrameDimension(gifImage.FrameDimensionsList[0]); + + int width = Mathf.ClosestPowerOfTwo(gifImage.Width - 1); + int height = Mathf.ClosestPowerOfTwo(gifImage.Height - 1); + + bool hasAlpha = false; + + int frameCount = gifImage.GetFrameCount(dimension); + + float totalProgress = frameCount * width; + for (int i = 0; i < frameCount; i++) + { + gifImage.SelectActiveFrame(dimension, i); + var ogframe = new System.Drawing.Bitmap(gifImage.Width, gifImage.Height); + System.Drawing.Graphics.FromImage(ogframe).DrawImage(gifImage, System.Drawing.Point.Empty); + var frame = ResizeBitmap(ogframe, width, height); + + Texture2D frameTexture = new Texture2D(frame.Width, frame.Height); + + float doneProgress = i * width; + for (int x = 0; x < frame.Width; x++) + { + if (x % 20 == 0) + if (EditorUtility.DisplayCancelableProgressBar("From GIF", "Frame " + i + ": " + (int)((float)x / width * 100) + "%", (doneProgress + x + 1) / totalProgress)) + { + EditorUtility.ClearProgressBar(); + return null; + } + + for (int y = 0; y < frame.Height; y++) + { + System.Drawing.Color sourceColor = frame.GetPixel(x, y); + frameTexture.SetPixel(x, frame.Height - 1 - y, new UnityEngine.Color32(sourceColor.R, sourceColor.G, sourceColor.B, sourceColor.A)); + if (sourceColor.A < 255.0f) + { + hasAlpha = true; + } + } + } + + frameTexture.Apply(); + gifFrames.Add(frameTexture); + } + EditorUtility.ClearProgressBar(); + //Debug.Log("has alpha? " + hasAlpha); + for (int i = 0; i < frameCount; i++) + { + EditorUtility.CompressTexture(gifFrames[i], hasAlpha ? TextureFormat.DXT5 : TextureFormat.DXT1, UnityEditor.TextureCompressionQuality.Normal); + gifFrames[i].Apply(true, false); + } +#endif + return gifFrames; + } + +#if SYSTEM_DRAWING + public static System.Drawing.Bitmap ResizeBitmap(System.Drawing.Image image, int width, int height) + { + var destRect = new System.Drawing.Rectangle(0, 0, width, height); + var destImage = new System.Drawing.Bitmap(width, height); + + destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution); + + using (var graphics = System.Drawing.Graphics.FromImage(destImage)) + { + graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; + graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; + graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality; + + using (var wrapMode = new System.Drawing.Imaging.ImageAttributes()) + { + wrapMode.SetWrapMode(System.Drawing.Drawing2D.WrapMode.TileFlipXY); + graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, System.Drawing.GraphicsUnit.Pixel, wrapMode); + } + } + + return destImage; + } +#endif + + private static Texture2DArray Textre2DArrayToAsset(Texture2D[] array) + { + Texture2DArray texture2DArray = new Texture2DArray(array[0].width, array[0].height, array.Length, array[0].format, true); + +#if SYSTEM_DRAWING + for (int i = 0; i < array.Length; i++) + { + for (int m = 0; m < array[i].mipmapCount; m++) + { + UnityEngine.Graphics.CopyTexture(array[i], 0, m, texture2DArray, i, m); + } + } +#endif + + texture2DArray.anisoLevel = array[0].anisoLevel; + texture2DArray.wrapModeU = array[0].wrapModeU; + texture2DArray.wrapModeV = array[0].wrapModeV; + + texture2DArray.Apply(false, true); + + return texture2DArray; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs.meta new file mode 100644 index 00000000..85c31fb4 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Converter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 829d29f60147def42bedd18b8233500a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs new file mode 100644 index 00000000..8dd69ba2 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class FileHelper + { + public static string FindFile(string name, string type = null) + { + string[] guids; + if (type != null) + guids = AssetDatabase.FindAssets(name + " t:" + type); + else + guids = AssetDatabase.FindAssets(name); + if (guids.Length == 0) + return null; + return AssetDatabase.GUIDToAssetPath(guids[0]); + } + + //-----------------------Value To File Saver---------------------- + + private static Dictionary> s_textFileData = new Dictionary>(); + + public static string LoadValueFromFile(string key, string path) + { + if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); + if (s_textFileData[path].ContainsKey(key)) + return s_textFileData[path][key]; + return null; + } + + private static void ReadFileIntoTextFileData(string path) + { + string data = ReadFileIntoString(path); + Dictionary dictionary = new Dictionary(); + MatchCollection matchCollection = Regex.Matches(data, @".*\s*:=.*(?=\r?\n)"); + foreach (Match m in matchCollection) + { + string[] keyvalue = m.Value.Split(new string[] { ":=" }, 2, StringSplitOptions.RemoveEmptyEntries); + if (keyvalue.Length > 1) + dictionary[keyvalue[0]] = keyvalue[1]; + } + s_textFileData[path] = dictionary; + } + + public static bool SaveValueToFile(string key, string value, string path) + { + if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); + s_textFileData[path][key] = value; + return SaveDictionaryToFile(path, s_textFileData[path]); + } + + public static void RemoveValueFromFile(string key, string path) + { + if (!s_textFileData.ContainsKey(path)) ReadFileIntoTextFileData(path); + if (s_textFileData[path].ContainsKey(key)) s_textFileData[path].Remove(key); + } + + private static bool SaveDictionaryToFile(string path, Dictionary dictionary) + { + s_textFileData[path] = dictionary; + string data = s_textFileData[path].Aggregate("", (d1, d2) => d1 + d2.Key + ":=" + d2.Value + "\n"); + WriteStringToFile(data, path); + return true; + } + + //-----------------------File Interaction--------------------- + + public static string FindFileAndReadIntoString(string fileName) + { + string[] guids = AssetDatabase.FindAssets(fileName); + if (guids.Length > 0) + return ReadFileIntoString(AssetDatabase.GUIDToAssetPath(guids[0])); + else return ""; + } + + public static void FindFileAndWriteString(string fileName, string s) + { + string[] guids = AssetDatabase.FindAssets(fileName); + if (guids.Length > 0) + WriteStringToFile(s, AssetDatabase.GUIDToAssetPath(guids[0])); + } + + public static string ReadFileIntoString(string path) + { + if (!File.Exists(path)) + { + CreateFileWithDirectories(path); + return ""; + } + StreamReader reader = new StreamReader(path); + string ret = reader.ReadToEnd(); + reader.Close(); + return ret; + } + + public static void WriteStringToFile(string s, string path) + { + if (!File.Exists(path)) CreateFileWithDirectories(path); + StreamWriter writer = new StreamWriter(path, false); + writer.Write(s); + writer.Close(); + } + + public static bool WriteBytesToFile(byte[] bytes, string path) + { + if (!File.Exists(path)) CreateFileWithDirectories(path); + try + { + using (var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) + { + fs.Write(bytes, 0, bytes.Length); + return true; + } + } + catch (Exception ex) + { + Debug.Log("Exception caught in process: " + ex.ToString()); + return false; + } + } + + public static void CreateFileWithDirectories(string path) + { + string dir_path = Path.GetDirectoryName(path); + if (dir_path != "") + Directory.CreateDirectory(dir_path); + File.Create(path).Close(); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs.meta new file mode 100644 index 00000000..ff343f2f --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/FileHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e468872a6eba5dc4d86ad5cd724f140e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs new file mode 100644 index 00000000..99804241 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs @@ -0,0 +1,325 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class Helper + { + static bool s_didTryRegsiterThisSession = false; + + public static bool ClassWithNamespaceExists(string classname) + { + return (from assembly in AppDomain.CurrentDomain.GetAssemblies() + from type in assembly.GetTypes() + where type.FullName == classname + select type).Count() > 0; + } + + public static Type FindTypeByFullName(string fullname) + { + return (from assembly in AppDomain.CurrentDomain.GetAssemblies() + from type in assembly.GetTypes() + where type.FullName == fullname + select type).FirstOrDefault(); + } + + private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + public static long GetCurrentUnixTimestampMillis() + { + return (long)(DateTime.UtcNow - UnixEpoch).TotalMilliseconds; + } + + public static long DatetimeToUnixSeconds(DateTime time) + { + return (long)(time - UnixEpoch).TotalSeconds; + } + + public static long GetUnityStartUpTimeStamp() + { + return GetCurrentUnixTimestampMillis() - (long)EditorApplication.timeSinceStartup * 1000; + } + + public static void RegisterEditorUse() + { + if (s_didTryRegsiterThisSession) return; + if (!EditorPrefs.GetBool("thry_has_counted_user", false)) + { + WebHelper.DownloadStringASync(URL.COUNT_USER, delegate (string s) + { + if (s == "true") + EditorPrefs.SetBool("thry_has_counted_user", true); + }); + } + + string projectPrefix = PlayerSettings.companyName + "." + PlayerSettings.productName; + if (!EditorPrefs.GetBool(projectPrefix + "_thry_has_counted_project", false)) + { + WebHelper.DownloadStringASync(URL.COUNT_PROJECT, delegate (string s) + { + if (s == "true") + EditorPrefs.SetBool(projectPrefix + "_thry_has_counted_project", true); + }); + } + s_didTryRegsiterThisSession = true; + } + + //-------------------Comparetors---------------------- + + public static int CompareVersions(string v1, string v2) + { + //fix the string + v1 = v1.Replace(",", "."); + v2 = v2.Replace(",", "."); + Match v1_match = Regex.Match(v1, @"(a|b)?\d+((\.|a|b)\d+)*(a|b)?"); + Match v2_match = Regex.Match(v2, @"(a|b)?\d+((\.|a|b)\d+)*(a|b)?"); + if (!v1_match.Success && !v2_match.Success) return 0; + else if (!v1_match.Success) return 1; + else if (!v2_match.Success) return -1; + v1 = v1_match.Value; + v2 = v2_match.Value; + + int index_v1 = 0; + int index_v2 = 0; + string chunk_v1; + string chunk_v2; + while (index_v1 < v1.Length || index_v2 < v2.Length) + { + //get a chunk of the strings + if (index_v1 < v1.Length) + { + chunk_v1 = ""; + if (v1[index_v1] == 'a') + chunk_v1 = "-2"; + else if (v1[index_v1] == 'b') + chunk_v1 = "-1"; + else + { + while (index_v1 < v1.Length && v1[index_v1] != 'a' && v1[index_v1] != 'b' && v1[index_v1] != '.') + chunk_v1 += v1[index_v1++]; + if (index_v1 < v1.Length && (v1[index_v1] == 'a' || v1[index_v1] == 'b')) + index_v1--; + } + index_v1++; + } + else + chunk_v1 = "0"; + + if (index_v2 < v2.Length) + { + chunk_v2 = ""; + if (v2[index_v2] == 'a') + chunk_v2 = "-2"; + else if (v2[index_v2] == 'b') + chunk_v2 = "-1"; + else + { + while (index_v2 < v2.Length && v2[index_v2] != 'a' && v2[index_v2] != 'b' && v2[index_v2] != '.') + chunk_v2 += v2[index_v2++]; + if (index_v2 < v2.Length && (v2[index_v2] == 'a' || v2[index_v2] == 'b')) + index_v2--; + } + index_v2++; + } + else + chunk_v2 = "0"; + + //compare chunks + int v1P = int.Parse(chunk_v1); + int v2P = int.Parse(chunk_v2); + if (v1P > v2P) return -1; + else if (v1P < v2P) return 1; + } + return 0; + } + + public static bool IsPrimitive(Type t) + { + return t.IsPrimitive || t == typeof(Decimal) || t == typeof(String); + } + + public static string GetStringBetweenBracketsAndAfterId(string input, string id, char[] brackets) + { + string[] parts = Regex.Split(input, id); + if (parts.Length > 1) + { + char[] behind_id = parts[1].ToCharArray(); + int i = 0; + int begin = 0; + int end = behind_id.Length - 1; + int depth = 0; + bool escaped = false; + while (i < behind_id.Length) + { + if (behind_id[i] == brackets[0] && !escaped) + { + if (depth == 0) + begin = i; + depth++; + } + else if (behind_id[i] == brackets[1] && !escaped) + { + depth--; + if (depth == 0) + { + end = i; + break; + } + } + + if (behind_id[i] == '\\') + escaped = !escaped; + else + escaped = false; + i++; + } + return parts[1].Substring(begin, end); + } + return input; + } + + public static float SolveMath(string exp, float parameter) + { + exp = exp.Replace("x", parameter.ToString(CultureInfo.InvariantCulture)); + exp = exp.Replace(" ", ""); + float f; + if (ExpressionEvaluator.Evaluate(exp, out f)) return f; + return 0; + } + + public static float Mod(float a, float b) + { + return a - b * Mathf.Floor(a / b); + } + + // This code is an implementation of the pseudocode from the Wikipedia, + // showing a naive implementation. + // You should research an algorithm with better space complexity. + public static int LevenshteinDistance(string s, string t) + { + int n = s.Length; + int m = t.Length; + int[,] d = new int[n + 1, m + 1]; + if (n == 0) + { + return m; + } + if (m == 0) + { + return n; + } + for (int i = 0; i <= n; d[i, 0] = i++) + ; + for (int j = 0; j <= m; d[0, j] = j++) + ; + for (int i = 1; i <= n; i++) + { + for (int j = 1; j <= m; j++) + { + int cost = (t[j - 1] == s[i - 1]) ? 0 : 1; + d[i, j] = Math.Min( + Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1), + d[i - 1, j - 1] + cost); + } + } + return d[n, m]; + } + + // Start of Detour methods + // Modified from: https://github.com/apkd/UnityStaticBatchingSortingPatch/blob/e83bed8cf31fc98097586c4e47af77fa79d9bed5/StaticBatchingSortingPatch.cs + // Modified by Behemoth/hill + static Dictionary s_patchedData = new Dictionary(); + public static unsafe void TryDetourFromTo(MethodInfo src, MethodInfo dst) + { +#if UNITY_EDITOR_WIN + try + { + if (IntPtr.Size == sizeof(Int64)) + { + // 64-bit systems use 64-bit absolute address and jumps + // 12 byte destructive + + // Get function pointers + long Source_Base = src.MethodHandle.GetFunctionPointer().ToInt64(); + long Destination_Base = dst.MethodHandle.GetFunctionPointer().ToInt64(); + + // Backup Source Data + IntPtr Source_IntPtr = src.MethodHandle.GetFunctionPointer(); + var backup = new byte[0xC]; + Marshal.Copy(Source_IntPtr, backup, 0, 0xC); + s_patchedData.Add(src, backup); + + // Native source address + byte* Pointer_Raw_Source = (byte*)Source_Base; + + // Pointer to insert jump address into native code + long* Pointer_Raw_Address = (long*)(Pointer_Raw_Source + 0x02); + + // Insert 64-bit absolute jump into native code (address in rax) + // mov rax, immediate64 + // jmp [rax] + *(Pointer_Raw_Source + 0x00) = 0x48; + *(Pointer_Raw_Source + 0x01) = 0xB8; + *Pointer_Raw_Address = Destination_Base; // ( Pointer_Raw_Source + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 ) + *(Pointer_Raw_Source + 0x0A) = 0xFF; + *(Pointer_Raw_Source + 0x0B) = 0xE0; + } + else + { + // 32-bit systems use 32-bit relative offset and jump + // 5 byte destructive + + // Get function pointers + int Source_Base = src.MethodHandle.GetFunctionPointer().ToInt32(); + int Destination_Base = dst.MethodHandle.GetFunctionPointer().ToInt32(); + + // Backup Source Data + IntPtr Source_IntPtr = src.MethodHandle.GetFunctionPointer(); + var backup = new byte[0x5]; + Marshal.Copy(Source_IntPtr, backup, 0, 0x5); + s_patchedData.Add(src, backup); + + // Native source address + byte* Pointer_Raw_Source = (byte*)Source_Base; + + // Pointer to insert jump address into native code + int* Pointer_Raw_Address = (int*)(Pointer_Raw_Source + 1); + + // Jump offset (less instruction size) + int offset = (Destination_Base - Source_Base) - 5; + + // Insert 32-bit relative jump into native code + *Pointer_Raw_Source = 0xE9; + *Pointer_Raw_Address = offset; + } + } + catch (Exception ex) + { + Debug.LogError($"Unable to detour: {src?.Name ?? "UnknownSrc"} -> {dst?.Name ?? "UnknownDst"}\n{ex}"); + throw; + } +#endif + } + + public static unsafe void RestoreDetour(MethodInfo src) + { +#if UNITY_EDITOR_WIN + var Source_IntPtr = src.MethodHandle.GetFunctionPointer(); + var backup = s_patchedData[src]; + Marshal.Copy(backup, 0, Source_IntPtr, backup.Length); + s_patchedData.Remove(src); +#endif + } + // End of Detour Methods + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs.meta similarity index 83% rename from _PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs.meta index 7c0c79b5..f038d3f9 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helper.cs.meta +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/Helper.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 878844302fe9a8b498f7002ac13ffc7a +guid: 61ff3cf4d1d0a3f42ade09eb6aba555a MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs new file mode 100644 index 00000000..72d34e80 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + //Adapted from https://github.com/lukis101/VRCUnityStuffs/blob/master/Scripts/Editor/MaterialCleaner.cs + //MIT License + + //Copyright (c) 2019 Dj Lukis.LT + + //Permission is hereby granted, free of charge, to any person obtaining a copy + //of this software and associated documentation files (the "Software"), to deal + //in the Software without restriction, including without limitation the rights + //to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + //copies of the Software, and to permit persons to whom the Software is + //furnished to do so, subject to the following conditions: + + //The above copyright notice and this permission notice shall be included in all + //copies or substantial portions of the Software. + + //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + //SOFTWARE. + public class MaterialCleaner + { + public enum CleanPropertyType { Texture, Float, Color } + + private const string PropPath_Tex = "m_SavedProperties.m_TexEnvs"; + private const string PropPath_Float = "m_SavedProperties.m_Floats"; + private const string PropPath_Col = "m_SavedProperties.m_Colors"; + + static string GetPath(CleanPropertyType type) + { + if (type == CleanPropertyType.Float) return PropPath_Float; + if (type == CleanPropertyType.Color) return PropPath_Col; + return PropPath_Tex; + } + public static int CountAllUnusedProperties(params Material[] materials) + { + ; + return materials.Sum(m => + { + int count = 0; + SerializedObject serObj = new SerializedObject(m); + count += CountUnusedProperties(m, serObj, CleanPropertyType.Texture); + count += CountUnusedProperties(m, serObj, CleanPropertyType.Float); + count += CountUnusedProperties(m, serObj, CleanPropertyType.Color); + return count; + }); + } + private static int CountUnusedProperties(Material mat, SerializedObject serObj, CleanPropertyType type, List list = null) + { + var properties = serObj.FindProperty(GetPath(type)); + int count = 0; + if (properties != null && properties.isArray) + { + for (int i = 0; i < properties.arraySize; i++) + { + string propName = properties.GetArrayElementAtIndex(i).displayName; + if (!mat.HasProperty(propName)) + { + if (list != null) list.Add(propName); + count++; + } + } + } + return count; + } + public static int ListUnusedProperties(CleanPropertyType type, params Material[] materials) + { + List list = new List(); + int count = materials.Sum(m => CountUnusedProperties(m, new SerializedObject(m), type, list)); + if (count > 0) ShaderEditor.Out($"Unbound properties of type {type}", list.Distinct().Select(s => $"↳{s}")); + return count; + } + public static int CountUnusedProperties(CleanPropertyType type, params Material[] materials) + { + return materials.Sum(m => CountUnusedProperties(m, new SerializedObject(m), type)); + } + + private static int RemoveUnusedProperties(Material mat, SerializedObject serObj, CleanPropertyType type) + { + if (!mat.shader.isSupported) + { + Debug.LogWarning("Skipping \"" + mat.name + "\" cleanup because shader is unsupported!"); + return 0; + } + Undo.RecordObject(mat, "Material property cleanup"); + int removedprops = 0; + string path = PropPath_Tex; + if (type == CleanPropertyType.Float) path = PropPath_Float; + if (type == CleanPropertyType.Color) path = PropPath_Col; + var properties = serObj.FindProperty(path); + if (properties != null && properties.isArray) + { + int amount = properties.arraySize; + for (int i = amount - 1; i >= 0; i--) // reverse loop because array gets modified + { + string propName = properties.GetArrayElementAtIndex(i).displayName; + if (!mat.HasProperty(propName)) + { + properties.DeleteArrayElementAtIndex(i); + removedprops++; + } + } + if (removedprops > 0) + serObj.ApplyModifiedProperties(); + } + return removedprops; + } + public static int RemoveUnusedProperties(CleanPropertyType type, params Material[] materials) + { + return materials.Sum(m => RemoveUnusedProperties(m, new SerializedObject(m), type)); + } + private static int RemoveAllUnusedProperties(Material mat, SerializedObject serObj) + { + int removedprops = 0; + removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Texture); + removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Float); + removedprops += RemoveUnusedProperties(mat, serObj, CleanPropertyType.Color); + + Debug.Log("Removed " + removedprops + " unused properties from " + mat.name); + return removedprops; + } + public static int RemoveAllUnusedProperties(CleanPropertyType type, params Material[] materials) + { + return materials.Sum(m => RemoveAllUnusedProperties(m, new SerializedObject(m))); + } + private static void ClearKeywords(Material mat) + { + Undo.RecordObject(mat, "Material keyword clear"); + string[] keywords = mat.shaderKeywords; + mat.shaderKeywords = new string[0]; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs.meta new file mode 100644 index 00000000..962ff39d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialCleaner.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b3cf916d23be9a8478de44db4ca6a2bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs new file mode 100644 index 00000000..ee1d60eb --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class MaterialHelper + { + public static void ToggleKeyword(Material material, string keyword, bool turn_on) + { + bool is_on = material.IsKeywordEnabled(keyword); + if (is_on && !turn_on) + material.DisableKeyword(keyword); + else if (!is_on && turn_on) + material.EnableKeyword(keyword); + } + + public static void ToggleKeyword(Material[] materials, string keyword, bool on) + { + foreach (Material m in materials) + ToggleKeyword(m, keyword, on); + } + + public static void ToggleKeyword(MaterialProperty p, string keyword, bool on) + { + ToggleKeyword(p.targets as Material[], keyword, on); + } + + /// + /// Set Material Property value or Renderqueue of current Editor. + /// + /// Property Name or "render_queue" + /// + public static void SetMaterialValue(string key, string value) + { + Material[] materials = ShaderEditor.Active.Materials; + if (ShaderEditor.Active.PropertyDictionary.TryGetValue(key, out ShaderProperty p)) + { + MaterialHelper.SetMaterialPropertyValue(p.MaterialProperty, value); + p.UpdateKeywordFromValue(); + } + else if (key == "render_queue") + { + int q = 0; + if (int.TryParse(value, out q)) + { + foreach (Material m in materials) m.renderQueue = q; + } + } + else if (key == "render_type") + { + foreach (Material m in materials) m.SetOverrideTag("RenderType", value); + } + else if (key == "preview_type") + { + foreach (Material m in materials) m.SetOverrideTag("PreviewType", value); + } + else if (key == "ignore_projector") + { + foreach (Material m in materials) m.SetOverrideTag("IgnoreProjector", value); + } + } + + public static void SetMaterialPropertyValue(MaterialProperty p, string value) + { + object prev = null; + if (p.type == MaterialProperty.PropType.Texture) + { + prev = p.textureValue; + p.textureValue = AssetDatabase.LoadAssetAtPath(value); + } + else if (p.type == MaterialProperty.PropType.Float || p.type == MaterialProperty.PropType.Range) + { + prev = p.floatValue; + p.floatValue = Parser.ParseFloat(value, p.floatValue); + } +#if UNITY_2022_1_OR_NEWER + else if (p.type == MaterialProperty.PropType.Int) + { + prev = p.intValue; + p.intValue = (int)Parser.ParseFloat(value, p.intValue); + } +#endif + else if (p.type == MaterialProperty.PropType.Vector) + { + prev = p.vectorValue; + p.vectorValue = Converter.StringToVector(value); + } + else if (p.type == MaterialProperty.PropType.Color) + { + prev = p.colorValue; + p.colorValue = Converter.StringToColor(value); + } + if (p.applyPropertyCallback != null) + p.applyPropertyCallback.Invoke(p, 1, prev); + } + + public static void CopyPropertyValueFromMaterial(MaterialProperty p, Material source) + { + if (!source.HasProperty(p.name)) return; + object prev = null; + switch (p.type) + { + case MaterialProperty.PropType.Float: + case MaterialProperty.PropType.Range: + prev = p.floatValue; + p.floatValue = source.GetNumber(p); + break; +#if UNITY_2022_1_OR_NEWER + case MaterialProperty.PropType.Int: + prev = p.intValue; + p.intValue = source.GetInt(p.name); + break; +#endif + case MaterialProperty.PropType.Color: + prev = p.colorValue; + p.colorValue = source.GetColor(p.name); + break; + case MaterialProperty.PropType.Vector: + prev = p.vectorValue; + p.vectorValue = source.GetVector(p.name); + break; + case MaterialProperty.PropType.Texture: + prev = p.textureValue; + p.textureValue = source.GetTexture(p.name); + Vector2 offset = source.GetTextureOffset(p.name); + Vector2 scale = source.GetTextureScale(p.name); + p.textureScaleAndOffset = new Vector4(scale.x, scale.y, offset.x, offset.y); + break; + } + if (p.applyPropertyCallback != null) + p.applyPropertyCallback.Invoke(p, 1, prev); + } + + public static void CopyMaterialValueFromProperty(MaterialProperty target, MaterialProperty source) + { + object prev = null; + switch (target.type) + { + case MaterialProperty.PropType.Float: + case MaterialProperty.PropType.Range: + prev = target.floatValue; + target.floatValue = source.floatValue; + break; +#if UNITY_2022_1_OR_NEWER + case MaterialProperty.PropType.Int: + prev = target.intValue; + target.intValue = source.intValue; + break; +#endif + case MaterialProperty.PropType.Color: + prev = target.colorValue; + target.colorValue = source.colorValue; + break; + case MaterialProperty.PropType.Vector: + prev = target.vectorValue; + target.vectorValue = source.vectorValue; + break; + case MaterialProperty.PropType.Texture: + prev = target.textureValue; + target.textureValue = source.textureValue; + target.textureScaleAndOffset = source.textureScaleAndOffset; + break; + } + if (target.applyPropertyCallback != null) + target.applyPropertyCallback.Invoke(target, 1, prev); + } + + public static void CopyPropertyValueToMaterial(MaterialProperty source, Material target) + { + CopyMaterialValueFromProperty(MaterialEditor.GetMaterialProperty(new Material[] { target }, source.name), source); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs.meta new file mode 100644 index 00000000..78af19fb --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/MaterialHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 25862ceb58ee8ef48a6fb55844ff97a2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs new file mode 100644 index 00000000..ceda8e7d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class PersistentData + { + public static string Get(string key) + { + return FileHelper.LoadValueFromFile(key, PATH.PERSISTENT_DATA); + } + + public static void Set(string key, string value) + { + FileHelper.SaveValueToFile(key, value, PATH.PERSISTENT_DATA); + } + + public static T Get(string key, T defaultValue) + { + string s = FileHelper.LoadValueFromFile(key, PATH.PERSISTENT_DATA); + if (string.IsNullOrEmpty(s)) return defaultValue; + T obj = Parser.Deserialize(s); + if (obj == null) return defaultValue; + return obj; + } + + public static void Set(string key, object value) + { + FileHelper.SaveValueToFile(key, Parser.Serialize(value), PATH.PERSISTENT_DATA); + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs.meta new file mode 100644 index 00000000..d3e5f76b --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/PersistentData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3249a3571cfd2b247973fab7b2a545bf +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs new file mode 100644 index 00000000..35c9a695 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class ShaderHelper + { + + private static Dictionary> shader_property_drawers = new Dictionary>(); + public static string[] GetDrawer(MaterialProperty property) + { + Shader shader = ((Material)property.targets[0]).shader; + + if (!shader_property_drawers.ContainsKey(shader)) + LoadShaderPropertyDrawers(shader); + + Dictionary property_drawers = shader_property_drawers[shader]; + if (property_drawers.ContainsKey(property.name)) + return property_drawers[property.name]; + return null; + } + + public static void LoadShaderPropertyDrawers(Shader shader) + { + string path = AssetDatabase.GetAssetPath(shader); + string code = FileHelper.ReadFileIntoString(path); + code = Helper.GetStringBetweenBracketsAndAfterId(code, "Properties", new char[] { '{', '}' }); + MatchCollection matchCollection = Regex.Matches(code, @"\[.*\].*(?=\()"); + Dictionary property_drawers = new Dictionary(); + foreach (Match match in matchCollection) + { + string[] drawers_or_flag_code = GetDrawersFlagsCode(match.Value); + string drawer_code = GetNonFlagDrawer(drawers_or_flag_code); + if (drawer_code == null) + continue; + + string property_name = Regex.Match(match.Value, @"(?<=\])[^\[]*$").Value.Trim(); + + List drawer_and_parameters = new List(); + drawer_and_parameters.Add(Regex.Split(drawer_code, @"\(")[0]); + + GetDrawerParameters(drawer_code, drawer_and_parameters); + + property_drawers[property_name] = drawer_and_parameters.ToArray(); + } + shader_property_drawers[shader] = property_drawers; + } + + private static void GetDrawerParameters(string code, List list) + { + MatchCollection matchCollection = Regex.Matches(code, @"(?<=\(|,).*?(?=\)|,)"); + foreach (Match m in matchCollection) + list.Add(m.Value); + } + + private static string GetNonFlagDrawer(string[] codes) + { + foreach (string c in codes) + if (!DrawerIsFlag(c)) + return c; + return null; + } + + private static bool DrawerIsFlag(string code) + { + return (code == "HideInInspector" || code == "NoScaleOffset" || code == "Normal" || code == "HDR" || code == "Gamma" || code == "PerRendererData"); + } + + private static string[] GetDrawersFlagsCode(string line) + { + MatchCollection matchCollection = Regex.Matches(line, @"(?<=\[).*?(?=\])"); + string[] codes = new string[matchCollection.Count]; + int i = 0; + foreach (Match m in matchCollection) + codes[i++] = m.Value; + return codes; + } + //------------Track ShaderEditor shaders------------------- + + // [MenuItem("Thry/Shader Editor/Test")] + // public static void Test() + // { + // Shader shader = Shader.Find(".poiyomi/Poiyomi 8.1/Poiyomi Pro"); + // Debug.Log(IsShaderUsingThryEditor(shader)); + // } + + public static bool IsShaderUsingThryEditor(Shader shader) + { + return IsShaderUsingThryEditor(new Material(shader)); + } + public static bool IsShaderUsingThryEditor(Material material) + { + return IsShaderUsingThryEditor(MaterialEditor.CreateEditor(material) as MaterialEditor); + } + public static bool IsShaderUsingThryEditor(MaterialEditor materialEditor) + { + PropertyInfo shaderGUIProperty = typeof(MaterialEditor).GetProperty("customShaderGUI"); + var gui = shaderGUIProperty.GetValue(materialEditor); + // gui is null for some shaders. I think it has to do with packages maybe + return (gui != null) && gui.GetType() == typeof(ShaderEditor); + } + + internal static List<(string prop, List keywords)> GetPropertyKeywordsForShader(Shader s) + { + List<(string prop, List keywords)> list = new List<(string prop, List keywords)>(); + + for (int i = 0; i < s.GetPropertyCount(); i++) + { + if (s.GetPropertyType(i) == UnityEngine.Rendering.ShaderPropertyType.Float) + { + string prop = s.GetPropertyName(i); + List keywords = null; + keywords = GetKeywordsFromShaderProperty(s, prop); + + if (keywords.Count == 0) + continue; + else + list.Add((prop, keywords)); + } + } + + return list; + } + + // Logic Adapted from unity's reference implementation + /// Returns a list of keywords for a given shader property. + internal static List GetKeywordsFromShaderProperty(Shader shader, string propertyName) + { + List keywords = new List(); + if (string.IsNullOrEmpty(propertyName)) + return keywords; + + int propertyIndex = shader.FindPropertyIndex(propertyName); + if (propertyIndex < 0) + return keywords; + + string[] attributes = shader.GetPropertyAttributes(propertyIndex); + if (attributes.Length == 0 || attributes == null) + return keywords; + + foreach (string attribute in attributes) + { + string args = ""; + // Regex based on Unity's reference implementation: Match a string of the form Keyword(Argument) and capture its components + // (\w+) - Match a word (keyword name) + // \s*\(\s* - Match an opening parenthesis, allowing whitespace before and after + // ([^)]*) - Match any number of characters that are not a closing parenthesis, and capture them into a group + // \s*\) - Match a closing parenthesis, allowing whitespace before and after + const string propertyDrawerRegex = @"(\w+)\s*\(\s*([^)]*)\s*\)"; + + Match regexMatch = Regex.Match(attribute, propertyDrawerRegex); + if (regexMatch.Success) + { + string className = regexMatch.Groups[1].Value; + args = regexMatch.Groups[2].Value.Trim(); + + // Note that we don't handle ToggleOff as it would require extra logic to differentiate + if (className == "Toggle") // Unity Toggle drawer, toggles a keyword directly if provided as [Toggle(KEYWORD)] and toggles PropertyName + { + if (string.IsNullOrEmpty(args)) + keywords.Add(GetUnityKeywordName(propertyName, "ON")); + else + keywords.Add(args); + break; + } + else if (className == "ThryToggle") // Thry Toggle drawer, toggles a keyword directly if provided as [Toggle(KEYWORD)] + { + // We only care about the first argument, the second is for UI + if (args.Contains(",")) + args = args.Split(',')[0]; + + // Ignore ThryToggle's bools, since otherwise we get keywords that have the same name as HLSL language keywords + if (args != "false" && args != "true") + keywords.Add(args); + + break; + } + else if (className == "KeywordEnum") // Keyword enum, enables one keyword out of a list of keywords provided as [KeywordEnum(KEYWORD1,KEYWORD2,KEYWORD3)] + { + string[] enumArgs = args.Split(','); + foreach (var enumArg in enumArgs) + { + keywords.Add(GetUnityKeywordName(propertyName, enumArg.Trim())); + } + + break; + } + } + } + return keywords; + } + + // Logic from Unity defaults + /// Gets a formatted Keyword name from a shader property name and a keyword name. + private static string GetUnityKeywordName(string propertyName, string keywordName) => $"{propertyName}_{keywordName}".Replace(' ', '_').ToUpperInvariant(); + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs.meta new file mode 100644 index 00000000..781032a8 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/ShaderHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bc1084262fe755d4ea75d88da1afc727 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs new file mode 100644 index 00000000..e8f27ce1 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + static class StringExtensions + { + public static string ReplaceVariables(this string s, params object[] values) + { + for (int i = 0; i < values.Length; i++) + { + s = s.Replace("{" + i + "}", values[i].ToString()); + } + return s; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs.meta new file mode 100644 index 00000000..3a5a716b --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 15f8b8c86be45cc459664f9ae1215b84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs new file mode 100644 index 00000000..812c929f --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class StringHelper + { + public static string GetBetween(string value, string prefix, string postfix) + { + return GetBetween(value, prefix, postfix, value); + } + + public static string GetBetween(string value, string prefix, string postfix, string fallback) + { + string pattern = @"(?<=" + prefix + ").*?(?=" + postfix + ")"; + Match m = Regex.Match(value, pattern); + if (m.Success) + return m.Value; + return fallback; + } + + //returns data for name:{data} even if data containss brakets + public static string GetBracket(string data, string bracketName) + { + Match m = Regex.Match(data, bracketName + ":"); + if (m.Success) + { + int startIndex = m.Index + bracketName.Length + 2; + int i = startIndex; + int depth = 0; + while (++i < data.Length) + { + if (data[i] == '{') + depth++; + else if (data[i] == '}') + { + if (depth == 0) + break; + depth--; + } + } + return data.Substring(startIndex, i - startIndex); + } + return data; + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs.meta new file mode 100644 index 00000000..ea44ea49 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/StringHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 962bcfc0e759cda428185ea0f6827eec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs new file mode 100644 index 00000000..94f37b6d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class TextureHelper + { + public static Gradient GetGradient(Texture texture) + { + if (texture != null) + { + string path = AssetDatabase.GetAssetPath(texture); + string gradient_data_string = null; + if (path != null) gradient_data_string = FileHelper.LoadValueFromFile(AssetDatabase.AssetPathToGUID(path), PATH.GRADIENT_INFO_FILE); + //For Backwards compatibility check old id (name) if guid cant be found + if (gradient_data_string == null) gradient_data_string = FileHelper.LoadValueFromFile(texture.name, PATH.GRADIENT_INFO_FILE); + if (gradient_data_string != null) + { + Debug.Log(texture.name + " Gradient loaded from file."); + Gradient g = Parser.Deserialize(gradient_data_string); + return g; + } + Debug.Log(texture.name + " Converted into Gradient."); + return Converter.TextureToGradient(GetReadableTexture(texture)); + } + return new Gradient(); + } + + private static Texture2D s_BackgroundTexture; + + public static Texture2D GetBackgroundTexture() + { + if (s_BackgroundTexture == null) + s_BackgroundTexture = CreateCheckerTexture(32, 4, 4, Color.white, new Color(0.7f, 0.7f, 0.7f)); + return s_BackgroundTexture; + } + + public static Texture2D CreateCheckerTexture(int numCols, int numRows, int cellPixelWidth, Color col1, Color col2) + { + int height = numRows * cellPixelWidth; + int width = numCols * cellPixelWidth; + + Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false); + texture.hideFlags = HideFlags.HideAndDontSave; + Color[] pixels = new Color[width * height]; + + for (int i = 0; i < numRows; i++) + for (int j = 0; j < numCols; j++) + for (int ci = 0; ci < cellPixelWidth; ci++) + for (int cj = 0; cj < cellPixelWidth; cj++) + pixels[(i * cellPixelWidth + ci) * width + j * cellPixelWidth + cj] = ((i + j) % 2 == 0) ? col1 : col2; + + texture.SetPixels(pixels); + texture.Apply(); + return texture; + } + + public static Texture SaveTextureAsPNG(Texture2D texture, string path, TextureData settings = null) + { + if (!path.EndsWith(".png")) + path += ".png"; + byte[] encoding = texture.EncodeToPNG(); + Debug.Log("Texture saved at \"" + path + "\"."); + FileHelper.WriteBytesToFile(encoding, path); + + AssetDatabase.ImportAsset(path); + if (settings != null) + settings.ApplyModes(path); + Texture saved = AssetDatabase.LoadAssetAtPath(path); + return saved; + } + + public static void MakeTextureReadible(string path) + { + TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(path); + if (!importer.isReadable) + { + importer.isReadable = true; + importer.SaveAndReimport(); + } + } + + public static Texture2D GetReadableTexture(Texture texture) + { + RenderTexture temp = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear); + Graphics.Blit(texture, temp); + RenderTexture previous = RenderTexture.active; + RenderTexture.active = temp; + Texture2D ret = new Texture2D(texture.width, texture.height); + ret.ReadPixels(new Rect(0, 0, temp.width, temp.height), 0, 0); + ret.Apply(); + RenderTexture.active = previous; + RenderTexture.ReleaseTemporary(temp); + return ret; + } + + public static Texture2D Resize(Texture2D texture, int width, int height) + { + Texture2D ret = new Texture2D(width, height, texture.format, texture.mipmapCount > 0); + float scaleX = ((float)texture.width) / width; + float scaleY = ((float)texture.height) / height; + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + ret.SetPixel(x, y, texture.GetPixel((int)(scaleX * x), (int)(scaleY * y))); + } + } + ret.Apply(); + return ret; + } + + //===============TGA Loader by aaro4130 https://forum.unity.com/threads/tga-loader-for-unity3d.172291/============== + + public static Texture2D LoadTGA(string TGAFile, bool displayProgressbar = false) + { + using (BinaryReader r = new BinaryReader(File.Open(TGAFile, FileMode.Open))) + { + byte IDLength = r.ReadByte(); + byte ColorMapType = r.ReadByte(); + byte ImageType = r.ReadByte(); + Int16 CMapStart = r.ReadInt16(); + Int16 CMapLength = r.ReadInt16(); + byte CMapDepth = r.ReadByte(); + Int16 XOffset = r.ReadInt16(); + Int16 YOffset = r.ReadInt16(); + Int16 Width = r.ReadInt16(); + Int16 Height = r.ReadInt16(); + byte PixelDepth = r.ReadByte(); + byte ImageDescriptor = r.ReadByte(); + if (ImageType == 0) + { + EditorUtility.DisplayDialog("Error", "Unsupported TGA file! No image data", "OK"); + Debug.LogError("Unsupported TGA file! No image data"); + } + else if (ImageType == 3 | ImageType == 11) + { + EditorUtility.DisplayDialog("Error", "Unsupported TGA file! 8-bit grayscale images are not supported", "OK"); + Debug.LogError("Unsupported TGA file! Not truecolor"); + } + else if (ImageType == 9 | ImageType == 10) + { + EditorUtility.DisplayDialog("Error", "Unsupported TGA file! Run-length encoded images are not supported", "OK"); + Debug.LogError("Unsupported TGA file! Colormapped"); + + } + bool startsAtTop = (ImageDescriptor & 1 << 5) >> 5 == 1; + bool startsAtRight = (ImageDescriptor & 1 << 4) >> 4 == 1; + // MsgBox("Dimensions are " Width "," Height) + Texture2D b = new Texture2D(Width, Height, TextureFormat.ARGB32, false); + Color[] colors = new Color[Width * Height]; + int texX = 0; + int texY = 0; + int index = 0; + float red = 0, green = 0, blue = 0, alpha = 0; + Byte[] bytes = r.ReadBytes((PixelDepth == 32 ? 4 : 3) * Width * Height); + + int byteIndex = 0; + for (int y = 0; y < b.height; y++) + { + if (displayProgressbar && y % 50 == 0) EditorUtility.DisplayProgressBar("Loading Raw TGA", "Loading " + TGAFile, (float)y / b.height); + for (int x = 0; x < b.width; x++) + { + texX = x; + texY = y; + if (startsAtRight) texX = b.width - x - 1; + if (startsAtTop) texY = b.height - y - 1; + index = texX + texY * b.width; + + blue = Convert.ToSingle(bytes[byteIndex++]); + green = Convert.ToSingle(bytes[byteIndex++]); + red = Convert.ToSingle(bytes[byteIndex++]); + + blue = Mathf.Pow(blue / 255, 0.45454545454f); + green = Mathf.Pow(green / 255, 0.45454545454f); + red = Mathf.Pow(red / 255, 0.45454545454f); + + // blue /= 255; + // green /= 255; + // red /= 255; + + colors[index].r = red; + colors[index].g = green; + colors[index].b = blue; + + if (PixelDepth == 32) + { + alpha = Convert.ToSingle(bytes[byteIndex++]); + alpha /= 255; + colors[index].a = alpha; + } + else + { + colors[index].a = 1; + } + } + } + b.SetPixels(colors); + b.Apply(); + if (displayProgressbar) EditorUtility.ClearProgressBar(); + + return b; + } + } + + public class VRAM + { + static Dictionary BPP = new Dictionary() + { + { TextureImporterFormat.BC7 , 8 }, + { TextureImporterFormat.DXT5 , 8 }, + { TextureImporterFormat.DXT5Crunched , 8 }, + { TextureImporterFormat.RGBA32 , 32 }, + { TextureImporterFormat.RGBA16 , 16 }, + { TextureImporterFormat.DXT1 , 4 }, + { TextureImporterFormat.DXT1Crunched , 4 }, + { TextureImporterFormat.RGB24 , 32 }, + { TextureImporterFormat.RGB16 , 16 }, + { TextureImporterFormat.BC5 , 8 }, + { TextureImporterFormat.BC4 , 4 }, + { TextureImporterFormat.R8 , 8 }, + { TextureImporterFormat.R16 , 16 }, + { TextureImporterFormat.Alpha8 , 8 }, + { TextureImporterFormat.RGBAHalf , 64 }, + { TextureImporterFormat.BC6H , 8 }, + { TextureImporterFormat.RGB9E5 , 32 }, + { TextureImporterFormat.ETC2_RGBA8Crunched , 8 }, + { TextureImporterFormat.ETC2_RGB4 , 4 }, + { TextureImporterFormat.ETC2_RGBA8 , 8 }, + { TextureImporterFormat.ETC2_RGB4_PUNCHTHROUGH_ALPHA , 4 }, + { TextureImporterFormat.PVRTC_RGB2 , 2 }, + { TextureImporterFormat.PVRTC_RGB4 , 4 }, + { TextureImporterFormat.ARGB32 , 32 }, + { TextureImporterFormat.ARGB16 , 16 }, + #if (UNITY_2020_1_OR_NEWER || UNITY_2019_4_23 || UNITY_2019_4_24 || UNITY_2019_4_25 || UNITY_2019_4_26 || UNITY_2019_4_27 || UNITY_2019_4_28 || UNITY_2019_4_29 || UNITY_2019_4_30 || UNITY_2019_4_31 || UNITY_2019_4_32 || UNITY_2019_4_33 || UNITY_2019_4_34 || UNITY_2019_4_35 || UNITY_2019_4_36 || UNITY_2019_4_37 || UNITY_2019_4_38 || UNITY_2019_4_39 || UNITY_2019_4_40) + { TextureImporterFormat.RGBA64 , 64 }, + { TextureImporterFormat.RGB48 , 64 }, + { TextureImporterFormat.RG32 , 32 }, + #endif + }; + + static Dictionary RT_BPP = new Dictionary() + { + { RenderTextureFormat.ARGB32 , 32 }, + { RenderTextureFormat.Depth , 0 }, + { RenderTextureFormat.ARGBHalf , 64 }, + { RenderTextureFormat.Shadowmap , 8 }, //guessed bpp + { RenderTextureFormat.RGB565 , 32 }, //guessed bpp + { RenderTextureFormat.ARGB4444 , 16 }, + { RenderTextureFormat.ARGB1555 , 16 }, + { RenderTextureFormat.Default , 32 }, + { RenderTextureFormat.ARGB2101010 , 32 }, + { RenderTextureFormat.DefaultHDR , 128 }, + { RenderTextureFormat.ARGB64 , 64 }, + { RenderTextureFormat.ARGBFloat , 128 }, + { RenderTextureFormat.RGFloat , 64 }, + { RenderTextureFormat.RGHalf , 32 }, + { RenderTextureFormat.RFloat , 32 }, + { RenderTextureFormat.RHalf , 16 }, + { RenderTextureFormat.R8 , 8 }, + { RenderTextureFormat.ARGBInt , 128 }, + { RenderTextureFormat.RGInt , 64 }, + { RenderTextureFormat.RInt , 32 }, + { RenderTextureFormat.BGRA32 , 32 }, + { RenderTextureFormat.RGB111110Float , 32 }, + { RenderTextureFormat.RG32 , 32 }, + { RenderTextureFormat.RGBAUShort , 64 }, + { RenderTextureFormat.RG16 , 16 }, + { RenderTextureFormat.BGRA10101010_XR , 40 }, + { RenderTextureFormat.BGR101010_XR , 30 }, + { RenderTextureFormat.R16 , 16 } + }; + + public static string ToByteString(long l) + { + if (l < 1000) return l + " B"; + if (l < 1000000) return (l / 1000f).ToString("n2") + " KB"; + if (l < 1000000000) return (l / 1000000f).ToString("n2") + " MB"; + else return (l / 1000000000f).ToString("n2") + " GB"; + } + + public static (long size, string format) CalcSize(Texture t) + { + string add = ""; + long bytesCount = 0; + + string path = AssetDatabase.GetAssetPath(t); + if (t != null && path != null && t is RenderTexture == false && t.dimension == UnityEngine.Rendering.TextureDimension.Tex2D) + { + AssetImporter assetImporter = AssetImporter.GetAtPath(path); + if (assetImporter is TextureImporter) + { + TextureImporter textureImporter = (TextureImporter)assetImporter; + TextureImporterFormat textureFormat = textureImporter.GetPlatformTextureSettings("PC").format; +#pragma warning disable CS0618 + if (textureFormat == TextureImporterFormat.AutomaticCompressed) textureFormat = textureImporter.GetAutomaticFormat("PC"); +#pragma warning restore CS0618 + + if (BPP.ContainsKey(textureFormat)) + { + add = textureFormat.ToString(); + double mipmaps = 1; + for (int i = 0; i < t.mipmapCount; i++) mipmaps += Math.Pow(0.25, i + 1); + bytesCount = (long)(BPP[textureFormat] * t.width * t.height * (textureImporter.mipmapEnabled ? mipmaps : 1) / 8); + //Debug.Log(bytesCount); + } + else + { + Debug.LogWarning("[Thry][VRAM] Does not have BPP for " + textureFormat); + } + } + else + { + bytesCount = Profiler.GetRuntimeMemorySizeLong(t); + } + } + else if (t is RenderTexture) + { + RenderTexture rt = t as RenderTexture; + double mipmaps = 1; + for (int i = 0; i < rt.mipmapCount; i++) mipmaps += Math.Pow(0.25, i + 1); + bytesCount = (long)((RT_BPP[rt.format] + rt.depth) * rt.width * rt.height * (rt.useMipMap ? mipmaps : 1) / 8); + } + else + { + bytesCount = Profiler.GetRuntimeMemorySizeLong(t); + } + + return (bytesCount, add); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs.meta new file mode 100644 index 00000000..8a57d7d1 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TextureHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bff8952ca2bc03240bb2dbf1d8952f87 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs new file mode 100644 index 00000000..0d98c286 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class TrashHandler + { + public static void EmptyThryTrash() + { + if (Directory.Exists(PATH.DELETING_DIR)) + { + DeleteDirectory(PATH.DELETING_DIR); + } + } + + public static void MoveDirectoryToTrash(string path) + { + string name = Path.GetFileName(path); + if (!Directory.Exists(PATH.DELETING_DIR)) + Directory.CreateDirectory(PATH.DELETING_DIR); + int i = 0; + string newpath = PATH.DELETING_DIR + "/" + name + i; + while (Directory.Exists(newpath)) + newpath = PATH.DELETING_DIR + "/" + name + (++i); + Directory.Move(path, newpath); + } + + static void DeleteDirectory(string path) + { + foreach (string f in Directory.GetFiles(path)) + DeleteFile(f); + foreach (string d in Directory.GetDirectories(path)) + DeleteDirectory(d); + if (Directory.GetFiles(path).Length + Directory.GetDirectories(path).Length == 0) + Directory.Delete(path); + } + static void DeleteFile(string path) + { + try + { + File.Delete(path); + } + catch (Exception e) + { + e.GetType(); + } + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs.meta new file mode 100644 index 00000000..69669357 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/TrashHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 26974d12903ae7544aa19cb7444eae6d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs new file mode 100644 index 00000000..38a76f4c --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEngine; +using UnityEngine.Profiling; + +namespace Thry +{ + public class VRCInterface + { + private static VRCInterface _Instance; + public static VRCInterface Get() + { + if (_Instance == null) _Instance = new VRCInterface(); + return _Instance; + } + public static void Update() + { + _Instance = new VRCInterface(); + } + + public SDK_Information Sdk_information; + + public class SDK_Information + { + public VRC_SDK_Type type; + public string installed_version = "0"; + } + + public enum VRC_SDK_Type + { + NONE = 0, + SDK_2 = 1, + SDK_3_Avatar = 2, + SDK_3_World = 3 + } + + private VRCInterface() + { + Sdk_information = new SDK_Information(); + Sdk_information.type = GetInstalledSDKType(); + InitInstalledSDKVersionAndPaths(); + } + + private void InitInstalledSDKVersionAndPaths() + { + string[] guids = AssetDatabase.FindAssets("version"); + string path = null; + foreach (string guid in guids) + { + string p = AssetDatabase.GUIDToAssetPath(guid); + if (p.Contains("VRCSDK/version")) + path = p; + } + if (path == null || !File.Exists(path)) + return; + string persistent = PersistentData.Get("vrc_sdk_version"); + if (persistent != null) + Sdk_information.installed_version = persistent; + else + Sdk_information.installed_version = Regex.Replace(FileHelper.ReadFileIntoString(path), @"\n?\r", ""); + } + + public static VRC_SDK_Type GetInstalledSDKType() + { +#if VRC_SDK_VRCSDK3 && UDON + return VRC_SDK_Type.SDK_3_World; +#elif VRC_SDK_VRCSDK3 + return VRC_SDK_Type.SDK_3_Avatar; +#elif VRC_SDK_VRCSDK2 + return VRC_SDK_Type.SDK_2; +#else + return VRC_SDK_Type.NONE; +#endif + } + + public static bool IsVRCSDKInstalled() + { +#if VRC_SDK_VRCSDK3 + return true; +#elif VRC_SDK_VRCSDK2 + return true; +#else + return false; +#endif + } + } + +} \ No newline at end of file diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs.meta new file mode 100644 index 00000000..aee9dfea --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Helpers/VRCInterface.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bd3671c4d28beb148aec62f4afdb88ad +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Localization.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Localization.cs index aa5b49c7..40fc187e 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Localization.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Localization.cs @@ -63,15 +63,15 @@ public static Localization Create() return l; } - public void DrawDropdown() + public void DrawDropdown(Rect r) { if(_couldNotLoad) { - EditorGUILayout.HelpBox("Could not load localization file", MessageType.Warning); + EditorGUI.HelpBox(r, "Could not load localization file", MessageType.Warning); return; } EditorGUI.BeginChangeCheck(); - SelectedLanguage = EditorGUILayout.Popup(SelectedLanguage + 1, _allLanguages) - 1; + SelectedLanguage = EditorGUI.Popup(r, SelectedLanguage + 1, _allLanguages) - 1; if(EditorGUI.EndChangeCheck()) { ShaderEditor.Active.Reload(); diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/MaterialLinker.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/MaterialLinker.cs index 925815a8..26893393 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/MaterialLinker.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/MaterialLinker.cs @@ -201,7 +201,7 @@ void OnGUI() { GUILayout.Label("Linked Materials", EditorStyles.boldLabel); float listMaxHeight = this.position.height - 110; - GuiHelper.DrawListField(linked_materials, listMaxHeight, ref scrollPos); + GUILib.DrawListField(linked_materials, listMaxHeight, ref scrollPos); GUILayout.Box("Drag and Drop new Material", EditorStyles.helpBox, GUILayout.MinHeight(30)); //Rect drag_rect = GUILayoutUtility.GetLastRect(); Rect lastRect = GUILayoutUtility.GetLastRect(); diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Presets.cs b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Presets.cs index 701338ac..c7617ac8 100644 --- a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Presets.cs +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Presets.cs @@ -117,8 +117,7 @@ static void InitializeDataStructures() { string[] lines = File.ReadAllLines(FILE_NAME_CACHE); - string presetVersion = lines[0]; - if(presetVersion != PRESET_VERSION) + if(lines.Length == 0 || lines[0] != PRESET_VERSION) { CreatePresetCache(); return; @@ -300,7 +299,7 @@ static void AddPreset(Material material) if(!PresetCollections[collectionName].Guids.Contains(guid)) { - Debug.Log($"AddPreset: {name} ({guid})"); + //Debug.Log($"AddPreset: {name} ({guid})"); PresetCollections[collectionName].Names.Add(name); PresetCollections[collectionName].Guids.Add(guid); } @@ -312,7 +311,7 @@ static void AddPreset(Material material) string name = material.GetTag(TAG_PRESET_NAME, false, material.name).Replace(';', '_'); if(!PresetCollections["_full_"].Guids.Contains(guid)) { - Debug.Log($"AddPreset: {name} ({guid})"); + //Debug.Log($"AddPreset: {name} ({guid})"); PresetCollections["_full_"].Names.Add(name); PresetCollections["_full_"].Guids.Add(guid); } @@ -341,7 +340,7 @@ static void RemovePreset(string guid) // if guid matches, remove from collection if(collection.Value.Guids[i] == guid) { - Debug.Log($"RemovePreset: {collection.Value.Names[i]} ({guid})"); + //Debug.Log($"RemovePreset: {collection.Value.Names[i]} ({guid})"); collection.Value.Guids.RemoveAt(i); collection.Value.Names.RemoveAt(i); break; @@ -409,6 +408,8 @@ public static void PresetEditorGUI(ShaderEditor shaderEditor) { if (shaderEditor.IsPresetEditor) { + RectifiedLayout.Seperator(); + EditorGUILayout.LabelField(EditorLocale.editor.Get("preset_material_notify"), Styles.greenStyle); EditorGUI.BeginChangeCheck(); bool isSectionPreset = IsMaterialSectionedPreset(shaderEditor.Materials[0]); @@ -431,6 +432,9 @@ public static void PresetEditorGUI(ShaderEditor shaderEditor) Save(); } } + + RectifiedLayout.Seperator(); + GUILayout.Space(10); } if (s_appliedPresets.ContainsKey(shaderEditor.Materials[0])) { @@ -542,6 +546,27 @@ public static bool IsPreset(Material m) { return m.GetTag(TAG_IS_PRESET, false, "false") == "true"; } + + public static void SetPreset(IEnumerable mats, bool set) + { + if (set) + { + foreach (Material m in mats) + { + m.SetOverrideTag(TAG_IS_PRESET, "true"); + if (m.GetTag("presetName", false, "") == "") m.SetOverrideTag("presetName", m.name); + Presets.AddPreset(m); + } + } + else + { + foreach (Material m in mats) + { + m.SetOverrideTag(TAG_IS_PRESET, ""); + Presets.RemovePreset(m); + } + } + } public static bool IsMaterialSectionedPreset(Material m) { @@ -551,6 +576,8 @@ public static bool IsMaterialSectionedPreset(Material m) public static void SetMaterialSectionedPreset(Material m, bool value) { m.SetOverrideTag(TAG_IS_SECTION_PRESET, value ? "true" : ""); + RemovePreset(m); + AddPreset(m); } public static bool IsSectionPreset(Material m, string headerPropName) @@ -601,7 +628,7 @@ public static void SetSectionPreset(Material m, string headerPropName, string na public static bool DoesSectionHavePresets(string headerPropName) { - return PresetCollections.ContainsKey(headerPropName); + return PresetCollections.ContainsKey(headerPropName) && PresetCollections[headerPropName].Guids.Count > 0; } #region Preset Validation @@ -656,46 +683,6 @@ static void CheckPresetCache() #endregion #region Unity Menu Hooks - - [MenuItem("Assets/Thry/Materials/Mark as Preset",false,500)] - static void MarkAsPreset() - { - IEnumerable mats = Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)). - Where(p => AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(Material)).Select(p => AssetDatabase.LoadAssetAtPath(p)); - foreach (Material m in mats) - { - m.SetOverrideTag(TAG_IS_PRESET, "true"); - if (m.GetTag("presetName", false, "") == "") m.SetOverrideTag("presetName", m.name); - Presets.AddPreset(m); - } - } - - [MenuItem("Assets/Thry/Materials/Mark as Preset", true,500)] - static bool MarkAsPresetValid() - { - return Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)). - All(p => AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(Material)); - } - - [MenuItem("Assets/Thry/Materials/Remove as preset",false,500)] - static void RemoveAsPreset() - { - IEnumerable mats = Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)). - Where(p => AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(Material)).Select(p => AssetDatabase.LoadAssetAtPath(p)); - foreach (Material m in mats) - { - m.SetOverrideTag(TAG_IS_PRESET, ""); - Presets.RemovePreset(m); - } - } - - [MenuItem("Assets/Thry/Materials/Remove as preset", true,500)] - static bool RemoveAsPresetValid() - { - return Selection.assetGUIDs.Select(g => AssetDatabase.GUIDToAssetPath(g)). - All(p => AssetDatabase.GetMainAssetTypeAtPath(p) == typeof(Material)); - } - [MenuItem("Thry/Presets/Rebuild Cache", priority = 100)] static void RebuildCache() { diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Resources.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources.meta similarity index 100% rename from _PoiyomiShaders/Scripts/ThryEditor/Resources.meta rename to _PoiyomiShaders/Scripts/ThryEditor/Editor/Resources.meta diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator.meta b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator.meta new file mode 100644 index 00000000..b72f8e3d --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb59d6efd9063ad46b285b6c088c43c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator/AvatarMaterialTranslator.uxml b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator/AvatarMaterialTranslator.uxml new file mode 100644 index 00000000..ac61b883 --- /dev/null +++ b/_PoiyomiShaders/Scripts/ThryEditor/Editor/Resources/Shader Translator/AvatarMaterialTranslator.uxml @@ -0,0 +1,21 @@ + +