diff options
author | Freya Murphy <freya@freyacat.org> | 2024-12-27 00:56:58 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-12-27 00:58:02 -0500 |
commit | 799e6680d40119dc9c2a9e0b320054a40324bebe (patch) | |
tree | dbcd308d59eb6e4f937a5547dd77d9f91d4fec20 /VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor | |
parent | move to self host (diff) | |
download | unityprojects-799e6680d40119dc9c2a9e0b320054a40324bebe.tar.gz unityprojects-799e6680d40119dc9c2a9e0b320054a40324bebe.tar.bz2 unityprojects-799e6680d40119dc9c2a9e0b320054a40324bebe.zip |
VRCSDK3Avatars found!
Diffstat (limited to 'VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor')
2 files changed, 445 insertions, 0 deletions
diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs new file mode 100644 index 00000000..fd5f8600 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs @@ -0,0 +1,434 @@ +#if UNITY_EDITOR +using System.Collections; +using System.Collections.Generic; +using UnityEditor; +using UnityEngine; +using System.IO; +using UnityEngine.UI; +using System; +using System.Text; +using UnityEngine.Assertions; +using System.Linq; +using System.Text.RegularExpressions; +using Poiyomi.ModularShaderSystem; + +//using Poiyomi.ModularShaderSystem; + +// PoiyomiPatreon.Scripts.poi_tools.Editor + +namespace Poiyomi.AngryLabs +{ + [ExecuteInEditMode] + public class ModuleInstaller : EditorWindow + { + [MenuItem("Poi/Module Installer")] + static void Init() + { + //var window = GetWindowWithRect<BlendshapeToTextures>(new Rect(0, 0, 200, 500)); + var window = GetWindow(typeof(ModuleInstaller)); + window.minSize = new Vector2(250, 300); + window.Show(); + } + + private static void ShowWindow() + { + var window = GetWindow<ModuleInstaller>(); + window.titleContent = new GUIContent("Module Installer"); + window.Show(); + + RefreshShaderList(); + } + + string CopyName { get; set; } + string NewID { get; set; } = ".poiyomi/User Modules/"; + + string OutputPath; + + static List<ModularShader> _shaders; + static List<Shader> _compiledShaders; + + static IEnumerable<T> FindAssetsByType<T>(string searchFolder = null) + { + AssetDatabase.Refresh(); + string[] guids; + if(searchFolder != null) + { + guids = AssetDatabase.FindAssets($"t:{typeof(T).ToString().Replace("UnityEngine.", "")}", new string[] { searchFolder }); + } + else + { + guids = AssetDatabase.FindAssets($"t:{typeof(T).ToString().Replace("UnityEngine.", "")}"); + } + + var paths = guids.Select(x => AssetDatabase.GUIDToAssetPath(x)).ToList(); + + var oassets = paths + .Select(path => AssetDatabase.LoadMainAssetAtPath(path)) + .Where(x => x != null) + .ToList() + ; + + List<T> assets = new List<T>(oassets.Cast<T>()); + return assets; + } + + ModularShader _activeShader; + ModularShader ActiveShader + { + get + { + return _activeShader; + } + set + { + if(ActiveShader == value) + { + return; + } + + _activeShader = value; + } + } + + /// <summary> + /// List of modules to install + /// </summary> + List<ShaderModule> ToInstall = new List<ShaderModule>(); + + bool AlreadyInstalled + { + get + { + if (ToInstall == null) return false; + + var modules = ActiveShader.BaseModules; + + var hash = new HashSet<string>(ToInstall.Select(x=>x?.Name).Where(x=>x!=null)); + + return modules.Any(x => hash.Contains(x?.Name)); + } + } + + bool ValidCopyName + { + get + { + if (_shaders == null) RefreshShaderList(); + return !_shaders.Any(x => x.Name == CopyName) && ! string.IsNullOrEmpty(CopyName); + } + } + + bool ValidNewID + { + get + { + if (_compiledShaders == null) RefreshShaderList(); + + if (NewID.EndsWith("/")) + { + return false; + } + + Regex alreadyExists = new Regex($@".*{NewID}$"); + return !_compiledShaders.Any(x => alreadyExists.IsMatch(x.name)) && ! string.IsNullOrEmpty(NewID) ; + } + } + + Vector2 ScrollPosition { get; set; } + + bool _refreshing; + private void OnFocus() + { + RefreshShaderList(); + } + + void OnGUI() + { + GUILayout.ExpandWidth(true); + + using (new GUILayout.HorizontalScope()) + { + GUILayout.FlexibleSpace(); + EditorGUILayout.LabelField($"By: AngriestSCV"); + + + var sty = new GUIStyle(GUI.skin.button) + { + padding = new RectOffset() + { + bottom = 8, + top = 8, + left = 25, + right = 25, + }, + + }; + + if (GUILayout.Button("angriestscv.gumroad.com", sty)) + { + Application.OpenURL("https://angriestscv.gumroad.com"); + } + } + + using(var sv = new GUILayout.ScrollViewScope(ScrollPosition)) + using (new GUILayout.VerticalScope()) + { + ScrollPosition = sv.scrollPosition; + + if (_shaders == null || _compiledShaders == null) + { + RefreshShaderList(); + } + + EditorGUILayout.LabelField($""); // provides the perfect amount of vertical space + ActiveShader = (ModularShader) EditorGUILayout.ObjectField("Shader to install to", ActiveShader, typeof(ModularShader), true); + + if (ActiveShader == null) + { + this.ShowNotification(new GUIContent("A Modular Shader target is required")); + return; + } + else + { + RemoveNotification(); + } + + GUILayout.Space(20); + + CopyName = EditorGUILayout.TextField("Modular Shader Name", CopyName); + NewID = EditorGUILayout.TextField("Output Shader Name", NewID); + + OutputPath = EditorGUILayout.TextField("Output Path", OutputPath); + //EditorGUILayout.LabelField("Output Path", OutputPath); + if (GUILayout.Button("Set Output Path")) + { + string startPath = OutputPath; + if (!Directory.Exists(startPath??"")) + { + startPath = "Assets"; + } + OutputPath = EditorUtility.OpenFolderPanel("Output Path Picker", startPath, ""); + if (OutputPath.StartsWith(Application.dataPath)) + { + OutputPath = "Assets" + OutputPath.Substring(Application.dataPath.Length); + } + else + { + OutputPath = "Assets/"; + } + + if(!Directory.Exists(OutputPath)) + { + OutputPath = "Assets/"; + } + + } + + GUILayout.Space(20); + using (new GUILayout.HorizontalScope()) + { + EditorGUILayout.LabelField("Modules to install"); + + if (GUILayout.Button("+")) + { + ToInstall.Add(null); + } + else if(GUILayout.Button("-")) + { + if(ToInstall.Count != 0) + { + ToInstall.RemoveAt(ToInstall.Count - 1); + } + else + { + Debug.Log("You are module-less."); + } + } + } + + for(int i=0; i<ToInstall.Count; i++) + { + ToInstall[i] = (ShaderModule) EditorGUILayout.ObjectField("", ToInstall[i], typeof(ShaderModule), true); + } + + GUILayout.Space(20); + if (!ValidCopyName || !ValidNewID) + { + if (string.IsNullOrEmpty(CopyName)) + { + GUILayout.Label("The output Modular Shader name is required."); + } + else if (!ValidCopyName) + { + GUILayout.Label("The Modular Shader asset already exists."); + if (GUILayout.Button("Delete it/them")) + { + DeleteModularShaderByName(CopyName); + RefreshShaderList(); + } + } + + if (string.IsNullOrEmpty(NewID)) + { + GUILayout.Label("A new shader name is required"); + } + else if (NewID.EndsWith("/")) + { + GUILayout.Label("'/' is not a valid final character"); + } + else if (!ValidNewID) + { + GUILayout.Label("The shader name is already used."); + + if (GUILayout.Button("Delete it")) + { + DeleteShaderByName(NewID); + RefreshShaderList(); + } + } + else + { + GUILayout.Label("Valid NewID"); + } + } + else if(ToInstall.All(x=>x==null)) + { + GUILayout.Label("There are no modules to install"); + } + else if(string.IsNullOrEmpty(OutputPath)) + { + GUILayout.Label("An output path is required"); + } + else if (!Directory.Exists(OutputPath)) + { + GUILayout.Label("The given output directory does not exist"); + } + else + { + + if (AlreadyInstalled) + { + GUILayout.Label("At least one of the modules to install is already in the active shader. Duplicates will not be reinstalled"); + } + + if (GUILayout.Button("Install Modules")) + { + Install(); + } + } + } + } + + private void DeleteModularShaderByName(string name) + { + AssetDatabase.Refresh(); + string[] guids; + guids = AssetDatabase.FindAssets($"t:{typeof(ModularShader).ToString().Replace("UnityEngine.", "")}"); + + IEnumerable<string> paths = guids.Select(x => AssetDatabase.GUIDToAssetPath(x)).ToList(); + var assets = paths + .Select(path => new { Asset = AssetDatabase.LoadMainAssetAtPath(path) as ModularShader, Path = path }) + .Where(x => x.Asset != null) + .Where(x => x.Asset.Name == name) + .ToList(); + + var toDel = assets + .Select(x => x.Path) + .ToList() + ; + + foreach(string path in toDel) + { + AssetDatabase.DeleteAsset(path); + } + } + + private void DeleteShaderByName(string name) + { + AssetDatabase.Refresh(); + string[] guids; + guids = AssetDatabase.FindAssets($"t:{typeof(Shader).ToString().Replace("UnityEngine.", "")}"); + + IEnumerable<string> paths = guids.Select(x => AssetDatabase.GUIDToAssetPath(x)).ToList(); + var assets = paths + .Select(path => new { Asset = AssetDatabase.LoadMainAssetAtPath(path) as Shader, Path = path }) + .Where(x => x.Asset != null) + .ToList(); + + Regex re = new Regex($@".*{name}$"); + + string delAsset = assets + .Where(x => re.IsMatch(x.Asset.name)) + .Select(x => x.Path) + .FirstOrDefault() + ; + + AssetDatabase.DeleteAsset(delAsset); + } + + private void Install() + { + RefreshShaderList(); + if(!ValidCopyName || !ValidNewID) + { + return; + } + + ModularShader shader = new ModularShader() + { + AdditionalModules = ActiveShader.AdditionalModules.ToList(), + AdditionalSerializedData = ActiveShader.AdditionalSerializedData, + Author = ActiveShader.Author, + BaseModules = ActiveShader.BaseModules.Where(x=>x!=null).ToList(), + CustomEditor = ActiveShader.CustomEditor, + Description = ActiveShader.Description, + hideFlags = ActiveShader.hideFlags, + Name = CopyName, + Properties = ActiveShader.Properties.ToList(), + ShaderTemplate = ActiveShader.ShaderTemplate, + ShaderPropertiesTemplate = ActiveShader.ShaderPropertiesTemplate, + UseTemplatesForProperties = ActiveShader.UseTemplatesForProperties, + Version = ActiveShader.Version, + Id = ActiveShader.Id + "AudioBump", + ShaderPath = NewID, + LockBaseModules = ActiveShader.LockBaseModules, + LastGeneratedShaders = new List<Shader>(), + }; + + string savePath = $"{OutputPath}/{CopyName}.asset"; + Debug.Log($"Creating new asset at [{savePath}]"); + AssetDatabase.CreateAsset(shader, savePath); + + var installedNames = new HashSet<string>(shader.BaseModules.Select(x => x.Name).Where(x => x != null)); + + foreach(ShaderModule mod in ToInstall) + { + if (mod == null) continue; + if (installedNames.Contains(mod.Name)) continue; + + installedNames.Add(mod.Name); + shader.BaseModules.Add(mod); + } + + AssetDatabase.SaveAssets(); + + RefreshShaderList(); + } + + ShaderModule FindModuleById(string name, string searchPath) + { + var modules = FindAssetsByType<ShaderModule>(searchPath); + + return modules.FirstOrDefault(x => x?.Id == name); + } + + + private static void RefreshShaderList() + { + _shaders = FindAssetsByType<ModularShader>().ToList(); + _compiledShaders = FindAssetsByType<Shader>().ToList(); + } + + } +} +#endif diff --git a/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs.meta b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs.meta new file mode 100644 index 00000000..16c83df2 --- /dev/null +++ b/VRCSDK3Avatars/Assets/_PoiyomiShaders/Scripts/ModuleInstaller/Editor/ModuleInstaller.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a469b044218f0834c8eb752e6bfffdb6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |