diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor.meta b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor.meta new file mode 100644 index 0000000..8341b8c --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: dcd2dae79e135544e8f59bbfd335d224 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs new file mode 100644 index 0000000..99d69ec --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs @@ -0,0 +1,140 @@ +// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, +// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. +// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// Eden.AutoMorpher.AutoMorpherLogCollector +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Eden.AutoMorpher; +using UnityEditor; +using UnityEngine; + +public class AutoMorpherLogCollector +{ + private struct LogEntry + { + public DateTime utcTime; + + public LogType type; + + public string condition; + + public string stackTrace; + } + + private bool _isCapturing; + + private DateTime _captureStartUtc; + + private readonly List _entries = new List(2048); + + private int entriesCapacity = 5000; + + private const string logSavePath = "Assets/@Eden_Tools/Eden_AutoMorpher/Logs"; + + public void BeginCapture() + { + if (!_isCapturing) + { + _isCapturing = true; + _entries.Clear(); + _captureStartUtc = DateTime.UtcNow; + Application.logMessageReceived += OnLogMessageReceived; + } + } + + public void EndCapture() + { + if (_isCapturing) + { + _isCapturing = false; + Application.logMessageReceived -= OnLogMessageReceived; + } + } + + public string SaveToTextFile(string defaultFileName, bool includeWarningsAndInfo) + { + EnsureLogDirectoryExists(); + string text = defaultFileName; + if (string.IsNullOrEmpty(text)) + { + text = "EdenAutoMorpher_Report.txt"; + } + if (!text.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) + { + text += ".txt"; + } + string text2 = Path.Combine("Assets/@Eden_Tools/Eden_AutoMorpher/Logs", text); + string contents = BuildReportText(includeWarningsAndInfo); + File.WriteAllText(text2, contents, Encoding.UTF8); + AssetDatabase.Refresh(); + Debug.Log("[AutoMorpher] Log report saved: " + text2); + return text2; + } + + private void EnsureLogDirectoryExists() + { + if (AssetDatabase.IsValidFolder("Assets/@Eden_Tools/Eden_AutoMorpher/Logs")) + { + return; + } + string[] array = "Assets/@Eden_Tools/Eden_AutoMorpher/Logs".Split('/', StringSplitOptions.None); + string text = array[0]; + for (int i = 1; i < array.Length; i++) + { + string text2 = text + "/" + array[i]; + if (!AssetDatabase.IsValidFolder(text2)) + { + AssetDatabase.CreateFolder(text, array[i]); + } + text = text2; + } + } + + public string BuildReportText(bool includeWarningsAndInfo) + { + StringBuilder stringBuilder = new StringBuilder(65536); + stringBuilder.AppendLine("==== EDEN AUTO MORPHER LOG REPORT ===="); + stringBuilder.AppendLine($"Captured (UTC) : {_captureStartUtc:yyyy-MM-dd HH:mm:ss} ~ {DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}"); + stringBuilder.AppendLine("Unity Version : " + Application.unityVersion); + stringBuilder.AppendLine($"Platform : {Application.platform}"); + stringBuilder.AppendLine("Project : " + Application.productName); + stringBuilder.AppendLine(); + stringBuilder.AppendLine("---- Logs ----"); + for (int i = 0; i < _entries.Count; i++) + { + LogEntry logEntry = _entries[i]; + if (includeWarningsAndInfo || logEntry.type == LogType.Error || logEntry.type == LogType.Assert || logEntry.type == LogType.Exception) + { + stringBuilder.AppendLine($"[{i:0000}] - [{logEntry.type}] | {logEntry.utcTime:HH:mm:ss.fff} UTC"); + stringBuilder.AppendLine(logEntry.condition ?? string.Empty); + if (!string.IsNullOrEmpty(logEntry.stackTrace)) + { + stringBuilder.AppendLine("Details:"); + stringBuilder.AppendLine(logEntry.stackTrace); + } + stringBuilder.AppendLine(); + } + } + return stringBuilder.ToString(); + } + + private void OnLogMessageReceived(string condition, string stackTrace, LogType type) + { + if (_isCapturing) + { + _entries.Add(new LogEntry + { + utcTime = DateTime.UtcNow, + type = type, + condition = condition, + stackTrace = stackTrace + }); + if (_entries.Count > entriesCapacity) + { + _entries.RemoveRange(0, 1000); + } + } + } +} diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs.meta b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs.meta new file mode 100644 index 0000000..ddf3403 --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherLogCollector.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 48dbd59641bef954eb938512667a41d1 \ No newline at end of file diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs new file mode 100644 index 0000000..1e39286 --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs @@ -0,0 +1,304 @@ +// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, +// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. +// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// Eden.AutoMorpher.AutoMorpherValidator +using System.Text; +using Eden.AutoMorpher; +using UnityEngine; + +public class AutoMorpherValidator +{ + public bool ValidateAutoModeObjects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + return ValidateAutoModeObjects_Internal(sourceAvatar, sourceClothes, targetAvatar, out errorMessage); + } + + public bool ValidateManualMode_AutoSetup_Objects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + return ValidateManualMode_AutoSetup_Objects_Internal(sourceAvatar, sourceClothes, targetAvatar, out errorMessage); + } + + public bool ValidateManualModeObjects(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, GameObject targetClothes, out string errorMessage) + { + return ValidateManualModeObjects_Internal(sourceAvatar, sourceClothes, targetAvatar, targetClothes, out errorMessage); + } + + public bool ValidateProfileModeObjects(GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + return ValidateProfileModeObjects_Internal(sourceClothes, targetAvatar, out errorMessage); + } + + public bool ValidateAutoModeObjects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + StringBuilder stringBuilder = new StringBuilder(); + ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object")); + if (sourceClothes != null) + { + ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck")); + HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer"); + HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck")); + } + if (sourceAvatar != null) + { + IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck")); + } + if (targetAvatar != null) + { + IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck")); + } + if (stringBuilder.Length == 0) + { + errorMessage = null; + return true; + } + errorMessage = "Auto Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString(); + return false; + } + + public bool ValidateProfileModeObjects_Internal(GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + StringBuilder stringBuilder = new StringBuilder(); + ObjectNullCheck(stringBuilder, (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object")); + if (sourceClothes != null) + { + HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer"); + HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck")); + } + if (targetAvatar != null) + { + IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck")); + } + if (stringBuilder.Length == 0) + { + errorMessage = null; + return true; + } + errorMessage = "Profile Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString(); + return false; + } + + public bool ValidateManualMode_AutoSetup_Objects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, out string errorMessage) + { + StringBuilder stringBuilder = new StringBuilder(); + ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object")); + if (sourceClothes != null) + { + ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck")); + HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer"); + HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck")); + } + if (sourceAvatar != null) + { + IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck")); + } + if (targetAvatar != null) + { + IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck")); + } + if (stringBuilder.Length == 0) + { + errorMessage = null; + return true; + } + errorMessage = "Manual Mode - Auto Setup: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString(); + return false; + } + + private bool ValidateManualModeObjects_Internal(GameObject sourceAvatar, GameObject sourceClothes, GameObject targetAvatar, GameObject targetClothes, out string errorMessage) + { + StringBuilder stringBuilder = new StringBuilder(); + ObjectNullCheck(stringBuilder, (sourceAvatar, "- Source Avatar Object"), (sourceClothes, "- Source Clothes Object"), (targetAvatar, "- Target Avatar Object"), (targetClothes, "- Target Clothes Object")); + if (sourceClothes != null) + { + ClothesChildCheck(stringBuilder, sourceAvatar, sourceClothes, LanguageManager.Get("UI.Validator.SourceClothesChildCheck")); + HasSMRInClothes(stringBuilder, sourceClothes, "ClothesObject - There is No SkinnedMeshRenderer"); + HasLocalArmature(stringBuilder, sourceClothes, "Source " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck")); + } + if (targetClothes != null) + { + ClothesChildCheck(stringBuilder, targetAvatar, targetClothes, LanguageManager.Get("UI.Validator.TargetClothesChildCheck")); + HasSMRInClothes(stringBuilder, targetClothes, "ClothesObject - There is No SkinnedMeshRenderer"); + HasLocalArmature(stringBuilder, targetClothes, "Target " + LanguageManager.Get("UI.Validator.ClothesArmatureCheck")); + } + if (sourceAvatar != null) + { + IsHumanoid(stringBuilder, sourceAvatar, LanguageManager.Get("UI.Validator.SourceAvatarAnimatorCheck")); + } + if (targetAvatar != null) + { + IsHumanoid(stringBuilder, targetAvatar, LanguageManager.Get("UI.Validator.TargetAvatarAnimatorCheck")); + } + if (sourceClothes != null && targetClothes != null) + { + AppendSmrAndVertexCheck(stringBuilder, sourceClothes, targetClothes); + } + if (stringBuilder.Length == 0) + { + errorMessage = null; + return true; + } + errorMessage = "Manual Mode: " + LanguageManager.Get("UI.Validator.Can'tFitting") + stringBuilder.ToString(); + return false; + } + + private void ObjectNullCheck(StringBuilder sb, params (GameObject obj, string label)[] refs) + { + bool flag = false; + for (int i = 0; i < refs.Length; i++) + { + if (refs[i].obj == null) + { + flag = true; + break; + } + } + if (!flag) + { + return; + } + sb.AppendLine(LanguageManager.Get("UI.Validator.ReferenceCheck")); + for (int j = 0; j < refs.Length; j++) + { + if (refs[j].obj == null) + { + sb.AppendLine(refs[j].label); + } + } + } + + private void ClothesChildCheck(StringBuilder sb, GameObject parentObject, GameObject childObject, string messageOnInvalid) + { + if (!(childObject == null) && (parentObject == null || !childObject.transform.IsChildOf(parentObject.transform))) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + sb.AppendLine(messageOnInvalid); + } + } + + private void HasSMRInClothes(StringBuilder sb, GameObject clothesRoot, string messageOnInvalid) + { + if (clothesRoot == null) + { + return; + } + SkinnedMeshRenderer[] componentsInChildren = clothesRoot.GetComponentsInChildren(includeInactive: true); + if (componentsInChildren == null || componentsInChildren.Length == 0) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + sb.AppendLine(messageOnInvalid); + } + } + + private void HasLocalArmature(StringBuilder sb, GameObject clothesRoot, string messageOnInvalid) + { + if (clothesRoot == null) + { + return; + } + SkinnedMeshRenderer[] componentsInChildren = clothesRoot.GetComponentsInChildren(includeInactive: true); + if (componentsInChildren == null || componentsInChildren.Length == 0) + { + return; + } + Transform transform = clothesRoot.transform; + bool flag = true; + SkinnedMeshRenderer[] array = componentsInChildren; + for (int i = 0; i < array.Length; i++) + { + Transform[] bones = array[i].bones; + if (bones == null || bones.Length == 0) + { + continue; + } + Transform[] array2 = bones; + foreach (Transform transform2 in array2) + { + if (!(transform2 == null) && !transform2.transform.IsChildOf(transform)) + { + flag = false; + } + } + } + if (!flag) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + sb.AppendLine(messageOnInvalid); + } + } + + private bool IsHumanoid(StringBuilder sb, GameObject avatarObject, string messageOnInvalid) + { + if (avatarObject == null) + { + return false; + } + Animator component = avatarObject.GetComponent(); + if (component == null) + { + return false; + } + if (component.avatar == null) + { + return false; + } + if (!component.avatar.isHuman) + { + return false; + } + return true; + } + + private void AppendSmrAndVertexCheck(StringBuilder sb, GameObject sourceClothes, GameObject targetClothes) + { + if (sourceClothes == null || targetClothes == null) + { + return; + } + SkinnedMeshRenderer[] componentsInChildren = sourceClothes.GetComponentsInChildren(includeInactive: true); + SkinnedMeshRenderer[] componentsInChildren2 = targetClothes.GetComponentsInChildren(includeInactive: true); + int num = ((componentsInChildren != null) ? componentsInChildren.Length : 0); + int num2 = ((componentsInChildren2 != null) ? componentsInChildren2.Length : 0); + if (num != num2) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + sb.AppendLine(LanguageManager.Get("UI.Validator.CheckRendererCountCheck")); + sb.AppendLine($"- Source Clothes SMR : {num}"); + sb.AppendLine($"- Target Clothes SMR : {num2}"); + return; + } + for (int i = 0; i < num; i++) + { + SkinnedMeshRenderer skinnedMeshRenderer = componentsInChildren[i]; + SkinnedMeshRenderer skinnedMeshRenderer2 = componentsInChildren2[i]; + if (skinnedMeshRenderer == null || skinnedMeshRenderer2 == null) + { + continue; + } + Mesh sharedMesh = skinnedMeshRenderer.sharedMesh; + Mesh sharedMesh2 = skinnedMeshRenderer2.sharedMesh; + if (!(sharedMesh == null) && !(sharedMesh2 == null) && sharedMesh.vertexCount != sharedMesh2.vertexCount) + { + if (sb.Length > 0) + { + sb.AppendLine(); + } + sb.AppendLine(LanguageManager.Get("UI.Validator.VertexCountCheck")); + sb.AppendLine($"- Source: {skinnedMeshRenderer.name} (vertices: {sharedMesh.vertexCount})"); + sb.AppendLine($"- Target: {skinnedMeshRenderer2.name} (vertices: {sharedMesh2.vertexCount})"); + break; + } + } + } +} diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs.meta b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs.meta new file mode 100644 index 0000000..e9b4908 --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/AutoMorpherValidator.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 367e223b416de1d4d92bdcaee21b1df7 \ No newline at end of file diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs new file mode 100644 index 0000000..c0bd1ee --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs @@ -0,0 +1,1008 @@ +// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, +// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. +// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// Eden.AutoMorpher.EdenAutoMorpherEditor +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using Eden.AutoMorpher; +using Eden.AutoMorpher.profile; +using UnityEditor; +using UnityEditorInternal; +using UnityEngine; + +[CustomEditor(typeof(EdenAutoMorpher))] +public class EdenAutoMorpherEditor : Editor +{ + private const string _version = "2.2.2"; + + private const string documentationUrl = "https://0xseoul.notion.site/How-to-Use-2bd1bca8582e8054a642efa8b35f4a9d"; + + private const string questionUrl = "https://0xseoul.notion.site/Q-A-2bd1bca8582e80bc8122cb0cace28d25?source=copy_link"; + + private const string discordUrl = "https://discord.gg/DgquvzGHC8"; + + private MorpherMode _currentMode; + + private ResultInfo _resultInfo = new ResultInfo(); + + private Stopwatch _stopwatch = new Stopwatch(); + + private bool _showStepByStepProgress; + + private bool _showAdvanced; + + private bool _showMeshDetails; + + private List _profileNames = new List(); + + private int _profileIndex; + + private Vector2 _errorMessageScroll = Vector2.zero; + + private const string PREF_KEY_MODE = "EdenAutoMorpher_Mode"; + + private const string PREF_KEY_Profile = "EdenAutoMorpher_LastProfile"; + + private IEnumerator _morphingEnumerator; + + private EdenAutoMorpher _edenAutoMorpher; + + private string _selectedProfileName = ""; + + private bool _isProgressing; + + private bool _isUpdateWorking; + + private AutoMorpherValidator _validator; + + private AutoMorpherLogCollector _logCollector; + + private SerializedProperty _sourceAvatarObject; + + private SerializedProperty _sourceClothesObject; + + private SerializedProperty _sourceBodyMeshes; + + private SerializedProperty _profileName; + + private SerializedProperty _targetAvatarObject; + + private SerializedProperty _targetClothesObjectOriginal; + + private SerializedProperty _targetBodyMeshes; + + private SerializedProperty _minMargin; + + private SerializedProperty _worldRadius; + + private SerializedProperty _sigma; + + private SerializedProperty _smoothingIteration; + + private SerializedProperty _fittingExpandIteration; + + private SerializedProperty _fittingShrinkIteration; + + private SerializedProperty _isBodyAutoSetup; + + private SerializedProperty _isReparentAccessoryBonesToTargetAvatar; + + private SerializedProperty _skipFootFitting; + + private SerializedProperty _transferWeightToAvatar; + + private SerializedProperty _addAnchorBone; + + private SerializedProperty _armatureBoneScaleCopy; + + private SerializedProperty _isRemoveAutoMorphedClothes; + + private void OnEnable() + { + _validator = new AutoMorpherValidator(); + _logCollector = new AutoMorpherLogCollector(); + _currentMode = (MorpherMode)EditorPrefs.GetInt("EdenAutoMorpher_Mode", 0); + _selectedProfileName = EditorPrefs.GetString("EdenAutoMorpher_LastProfile", ""); + _sourceAvatarObject = base.serializedObject.FindProperty("sourceAvatarObject"); + _sourceClothesObject = base.serializedObject.FindProperty("sourceClothesObject"); + _sourceBodyMeshes = base.serializedObject.FindProperty("sourceBodyMeshes"); + _profileName = base.serializedObject.FindProperty("profileName"); + _targetAvatarObject = base.serializedObject.FindProperty("targetAvatarObject"); + _targetClothesObjectOriginal = base.serializedObject.FindProperty("targetClothesObjectOriginal"); + _targetBodyMeshes = base.serializedObject.FindProperty("targetBodyMeshes"); + _minMargin = base.serializedObject.FindProperty("minMargin"); + _worldRadius = base.serializedObject.FindProperty("worldRadius"); + _sigma = base.serializedObject.FindProperty("sigma"); + _smoothingIteration = base.serializedObject.FindProperty("smoothingIteration"); + _fittingExpandIteration = base.serializedObject.FindProperty("fittingExpandIteration"); + _fittingShrinkIteration = base.serializedObject.FindProperty("fittingShrinkIteration"); + _isBodyAutoSetup = base.serializedObject.FindProperty("isBodyAutoSetup"); + _isReparentAccessoryBonesToTargetAvatar = base.serializedObject.FindProperty("isReparentAccessoryBonesToTargetAvatar"); + _skipFootFitting = base.serializedObject.FindProperty("skipFootFitting"); + _transferWeightToAvatar = base.serializedObject.FindProperty("transferWeightToAvatar"); + _addAnchorBone = base.serializedObject.FindProperty("addAnchorBone"); + _armatureBoneScaleCopy = base.serializedObject.FindProperty("armatureBoneScaleCopy"); + _isRemoveAutoMorphedClothes = base.serializedObject.FindProperty("isRemoveAutoMorphedClothes"); + RefreshProfiles(); + } + + private void OnDestroy() + { + StopProcess(); + } + + public override void OnInspectorGUI() + { + //IL_002e: Unknown result type (might be due to invalid IL or missing references) + //IL_0033: Unknown result type (might be due to invalid IL or missing references) + //IL_0034: Unknown result type (might be due to invalid IL or missing references) + //IL_0035: Unknown result type (might be due to invalid IL or missing references) + //IL_0043: Unknown result type (might be due to invalid IL or missing references) + //IL_0061: Unknown result type (might be due to invalid IL or missing references) + //IL_0066: Unknown result type (might be due to invalid IL or missing references) + //IL_0075: Unknown result type (might be due to invalid IL or missing references) + //IL_0076: Unknown result type (might be due to invalid IL or missing references) + //IL_0079: Unknown result type (might be due to invalid IL or missing references) + EditorGUILayout.Space(4f); + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField("EDEN Auto Morpher", EditorStyles.boldLabel); + GUILayout.FlexibleSpace(); + Language currentLanguage = LanguageManager.CurrentLanguage; + Language val = currentLanguage; + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + val = (Language)(object)EditorGUILayout.EnumPopup((Enum)(object)currentLanguage, GUILayout.Width(80f)); + } + if (val != currentLanguage) + { + LanguageManager.SetLanguage(val); + GUI.FocusControl(null); + } + EditorGUILayout.EndHorizontal(); + EditorGUILayout.LabelField(" - Version : 2.2.2", EditorStyles.boldLabel); + EditorGUILayout.Space(6f); + base.serializedObject.Update(); + _edenAutoMorpher = (EdenAutoMorpher)base.target; + _isProgressing = _morphingEnumerator != null; + if (!_isProgressing && _isUpdateWorking) + { + StopProcess(); + } + InfoBox(); + EditorGUILayout.Space(); + string text = LanguageManager.Get("UI.Mode.AutoFitting"); + string text2 = LanguageManager.Get("UI.Mode.ManualFitting"); + string text3 = LanguageManager.Get("UI.Mode.ProfileFitting"); + string[] texts = new string[3] { text, text2, text3 }; + int num = (int)_currentMode; + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + num = GUILayout.Toolbar(num, texts); + } + if (num != (int)_currentMode) + { + _showAdvanced = false; + _showMeshDetails = false; + _currentMode = (MorpherMode)num; + EditorPrefs.SetInt("EdenAutoMorpher_Mode", num); + _edenAutoMorpher.ChangeMode(_currentMode); + } + switch (_currentMode) + { + case MorpherMode.AutoMorpher: + DrawAutoFittingMode(_edenAutoMorpher, _currentMode); + break; + case MorpherMode.ManualMorpher: + DrawManualFittingMode(_edenAutoMorpher, _currentMode); + break; + case MorpherMode.ProfileMorpher: + DrawProfileFittingMode(_edenAutoMorpher, _currentMode); + break; + } + EditorGUILayout.Space(); + EditorGUILayout.Space(); + if (!_isProgressing) + { + ApplyVariableConstraints(); + base.serializedObject.ApplyModifiedProperties(); + } + } + + private void InfoBox() + { + EditorGUILayout.BeginVertical(EditorStyles.helpBox); + DrawLabelWithShortLink(" - How To Use:", "Open Documentation", "https://0xseoul.notion.site/How-to-Use-2bd1bca8582e8054a642efa8b35f4a9d"); + DrawLabelWithShortLink(" - Q&A:", "Open Q&A Page", "https://0xseoul.notion.site/Q-A-2bd1bca8582e80bc8122cb0cace28d25?source=copy_link"); + DrawLabelWithShortLink(" - Discord:", "Open Discord", "https://discord.gg/DgquvzGHC8"); + EditorGUILayout.EndVertical(); + } + + private void DrawLabelWithShortLink(string label, string linkText, string url) + { + EditorGUILayout.BeginHorizontal(); + EditorGUILayout.LabelField(label, GUILayout.Width(90f)); + GUIStyle style = new GUIStyle(EditorStyles.linkLabel); + Rect rect = GUILayoutUtility.GetRect(new GUIContent(linkText), style); + EditorGUIUtility.AddCursorRect(rect, MouseCursor.Link); + if (GUI.Button(rect, linkText, style)) + { + Application.OpenURL(url); + } + EditorGUILayout.EndHorizontal(); + } + + private void ApplyVariableConstraints() + { + if (_minMargin != null) + { + _minMargin.floatValue = Mathf.Max(0f, _minMargin.floatValue); + } + if (_sigma != null) + { + _sigma.floatValue = Mathf.Max(0f, _sigma.floatValue); + } + if (_fittingExpandIteration != null) + { + _fittingExpandIteration.intValue = Mathf.Max(0, _fittingExpandIteration.intValue); + } + if (_fittingShrinkIteration != null) + { + _fittingShrinkIteration.intValue = Mathf.Max(0, _fittingShrinkIteration.intValue); + } + } + + private void DrawAutoFittingMode(EdenAutoMorpher _edenAutoMorpher, MorpherMode morpherMode) + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Basic Avatar Settings", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.LabelField("Source Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_sourceAvatarObject); + EditorGUILayout.PropertyField(_sourceClothesObject); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Target Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_targetAvatarObject); + EditorGUI.indentLevel--; + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + DrawBasicProperties(morpherMode); + EditorGUILayout.Space(); + DrawAdvanceProperties(); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + Rect controlRect = EditorGUILayout.GetControlRect(false, 1f); + controlRect.height = 3f; + EditorGUI.DrawRect(controlRect, new Color(0f, 0f, 0f, 0.25f)); + EditorGUILayout.Space(); + GUIStyle gUIStyle = new GUIStyle(EditorStyles.boldLabel); + gUIStyle.fontSize = 20; + gUIStyle.wordWrap = true; + EditorGUILayout.LabelField("Auto Morphing", gUIStyle); + EditorGUILayout.Space(); + ShowInspectorProgress(); + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + GUIStyle gUIStyle2 = new GUIStyle(GUI.skin.button); + gUIStyle2.fontSize = 18; + gUIStyle2.fixedHeight = 40f; + gUIStyle2.alignment = TextAnchor.MiddleCenter; + bool flag = true; + GameObject sourceAvatar = _sourceAvatarObject.objectReferenceValue as GameObject; + GameObject sourceClothes = _sourceClothesObject.objectReferenceValue as GameObject; + GameObject targetAvatar = _targetAvatarObject.objectReferenceValue as GameObject; + flag = _validator.ValidateAutoModeObjects(sourceAvatar, sourceClothes, targetAvatar, out var errorMessage); + if (!flag) + { + EditorGUILayout.HelpBox(errorMessage, MessageType.Error); + } + EditorGUILayout.Space(); + using (new EditorGUI.DisabledScope(!flag)) + { + EditorGUILayout.Space(); + if (GUILayout.Button("Run All", gUIStyle2)) + { + StartAutoMorphing(_edenAutoMorpher, morpherMode); + } + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + _showStepByStepProgress = EditorGUILayout.Foldout(_showStepByStepProgress, "Step-by-step progress", toggleOnLabelClick: true); + EditorGUI.indentLevel--; + if (!_showStepByStepProgress) + { + return; + } + EditorGUILayout.Space(); + using (new EditorGUILayout.HorizontalScope()) + { + if (GUILayout.Button("1.Run Fitting", gUIStyle2)) + { + StartFitting(_edenAutoMorpher, morpherMode); + } + bool flag2 = _edenAutoMorpher != null && _edenAutoMorpher.IsWeightingReady(isAutoMode: true); + using (new EditorGUI.DisabledScope(!flag2)) + { + if (GUILayout.Button("2.Run Weighting", gUIStyle2)) + { + StartWeighting(_edenAutoMorpher); + } + } + } + } + } + } + + private void DrawManualFittingMode(EdenAutoMorpher _edenAutoMorpher, MorpherMode morpherMode) + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Basic Avatar Settings", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.LabelField("Source Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_sourceAvatarObject); + EditorGUILayout.PropertyField(_sourceClothesObject); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Target Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_targetAvatarObject); + EditorGUILayout.PropertyField(_targetClothesObjectOriginal, new GUIContent("Target Clothes Object")); + EditorGUI.indentLevel--; + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + DrawBasicProperties(morpherMode); + EditorGUILayout.Space(); + DrawAdvanceProperties(); + } + EditorGUILayout.Space(); + Rect controlRect = EditorGUILayout.GetControlRect(false, 1f); + controlRect.height = 3f; + EditorGUI.DrawRect(controlRect, new Color(0f, 0f, 0f, 0.25f)); + EditorGUILayout.Space(); + GUIStyle gUIStyle = new GUIStyle(EditorStyles.boldLabel); + gUIStyle.fontSize = 20; + gUIStyle.wordWrap = true; + EditorGUILayout.LabelField("Auto Morphing", gUIStyle); + EditorGUILayout.Space(); + ShowInspectorProgress(); + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + GUIStyle gUIStyle2 = new GUIStyle(GUI.skin.button); + gUIStyle2.fontSize = 18; + gUIStyle2.fixedHeight = 40f; + gUIStyle2.alignment = TextAnchor.MiddleCenter; + bool flag = true; + bool flag2 = true; + GameObject sourceAvatar = _sourceAvatarObject.objectReferenceValue as GameObject; + GameObject sourceClothes = _sourceClothesObject.objectReferenceValue as GameObject; + GameObject targetAvatar = _targetAvatarObject.objectReferenceValue as GameObject; + GameObject targetClothes = _targetClothesObjectOriginal.objectReferenceValue as GameObject; + flag = _validator.ValidateManualMode_AutoSetup_Objects(sourceAvatar, sourceClothes, targetAvatar, out var errorMessage); + if (!flag) + { + EditorGUILayout.HelpBox(errorMessage, MessageType.Error); + } + EditorGUILayout.Space(); + using (new EditorGUI.DisabledScope(!flag)) + { + if (GUILayout.Button("0. Auto Setup", gUIStyle2)) + { + try + { + _edenAutoMorpher.AutoPoseSetup(morpherMode); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Auto Setup Success"; + } + catch (AutoMorpherException ex) + { + UnityEngine.Debug.LogException(ex); + string text = ex.title ?? "Eden AutoMorpher Error"; + string text2 = ex.Message + "\n\nIf you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately."; + EditorUtility.DisplayDialog(text, text2, "OK"); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text + "\n\n" + text2; + } + catch (Exception ex2) + { + UnityEngine.Debug.LogException(ex2); + string text3 = "Unexpected Error"; + string text4 = "If you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately.\n\nError Details:\n" + ex2.ToString(); + EditorUtility.DisplayDialog(text3, text4, "OK"); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text3 + "\n\n" + text4; + } + } + } + EditorGUILayout.Space(); + flag2 = _validator.ValidateManualModeObjects(sourceAvatar, sourceClothes, targetAvatar, targetClothes, out errorMessage); + if (!flag2) + { + EditorGUILayout.HelpBox(errorMessage, MessageType.Error); + } + EditorGUILayout.Space(); + using (new EditorGUI.DisabledScope(!flag2)) + { + if (GUILayout.Button("Run All", gUIStyle2)) + { + StartAutoMorphing(_edenAutoMorpher, morpherMode); + } + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + _showStepByStepProgress = EditorGUILayout.Foldout(_showStepByStepProgress, "Step-by-step progress", toggleOnLabelClick: true); + EditorGUI.indentLevel--; + if (!_showStepByStepProgress) + { + return; + } + EditorGUILayout.Space(); + using (new EditorGUILayout.HorizontalScope()) + { + if (GUILayout.Button("1. Run Fitting", gUIStyle2)) + { + StartFitting(_edenAutoMorpher, morpherMode); + } + bool flag3 = flag2 && _edenAutoMorpher != null && _edenAutoMorpher.IsWeightingReady(isAutoMode: false); + using (new EditorGUI.DisabledScope(!flag3)) + { + if (GUILayout.Button("2. Run Weighting", gUIStyle2)) + { + StartWeighting(_edenAutoMorpher); + } + } + } + } + } + } + + private void DrawProfileFittingMode(EdenAutoMorpher _edenAutoMorpher, MorpherMode morpherMode) + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Basic Avatar Settings", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.LabelField("Source Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + if (_profileNames == null || _profileNames.Count == 0) + { + RefreshProfiles(); + } + using (new EditorGUILayout.HorizontalScope()) + { + float labelWidth = EditorGUIUtility.labelWidth; + EditorGUIUtility.labelWidth = labelWidth - 14f; + EditorGUILayout.PrefixLabel("Profile"); + base.serializedObject.Update(); + if (_profileNames != null && _profileNames.Count > 0) + { + int num = EditorGUILayout.Popup(_profileIndex, _profileNames.ToArray()); + if (num != _profileIndex) + { + _profileIndex = num; + _selectedProfileName = _profileNames[_profileIndex]; + EditorPrefs.SetString("EdenAutoMorpher_LastProfile", _selectedProfileName); + if (_profileName != null) + { + _profileName.stringValue = _selectedProfileName; + } + } + } + else + { + EditorGUILayout.LabelField("No profiles found"); + } + GUILayout.Space(8f); + if (GUILayout.Button("Refresh", GUILayout.Width(70f))) + { + RefreshProfiles(); + } + EditorGUIUtility.labelWidth = labelWidth; + } + EditorGUILayout.PropertyField(_sourceClothesObject); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Target Avatar", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_targetAvatarObject); + EditorGUI.indentLevel--; + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + DrawBasicProperties(morpherMode); + EditorGUILayout.Space(); + DrawAdvanceProperties(); + EditorGUILayout.Space(); + } + EditorGUILayout.Space(); + Rect controlRect = EditorGUILayout.GetControlRect(false, 1f); + controlRect.height = 3f; + EditorGUI.DrawRect(controlRect, new Color(0f, 0f, 0f, 0.25f)); + EditorGUILayout.Space(); + GUIStyle gUIStyle = new GUIStyle(EditorStyles.boldLabel); + gUIStyle.fontSize = 20; + gUIStyle.wordWrap = true; + EditorGUILayout.LabelField("Auto Morphing", gUIStyle); + EditorGUILayout.Space(); + ShowInspectorProgress(); + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + GUIStyle gUIStyle2 = new GUIStyle(GUI.skin.button); + gUIStyle2.fontSize = 18; + gUIStyle2.fixedHeight = 40f; + gUIStyle2.alignment = TextAnchor.MiddleCenter; + if (AutoMorpherDev.isDeveloperMode) + { + using (new EditorGUI.DisabledScope(_isProgressing)) + { + if (GUILayout.Button("0. Auto Setup", gUIStyle2)) + { + try + { + _edenAutoMorpher.ProfileSetup(morpherMode); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Auto Setup Success"; + } + catch (AutoMorpherException ex) + { + UnityEngine.Debug.LogException(ex); + string text = ex.title ?? "Eden AutoMorpher Error"; + string text2 = ex.Message + "\n\nIf you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately."; + EditorUtility.DisplayDialog(text, text2, "OK"); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text + "\n\n" + text2; + } + catch (Exception ex2) + { + UnityEngine.Debug.LogException(ex2); + string text3 = "Unexpected Error"; + string text4 = "If you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately.\n\nError Details:\n" + ex2.ToString(); + EditorUtility.DisplayDialog(text3, text4, "OK"); + _resultInfo.isComplicated = true; + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text3 + "\n\n" + text4; + } + } + } + } + GameObject sourceClothes = _sourceClothesObject.objectReferenceValue as GameObject; + GameObject targetAvatar = _targetAvatarObject.objectReferenceValue as GameObject; + string errorMessage; + bool flag = _validator.ValidateProfileModeObjects(sourceClothes, targetAvatar, out errorMessage); + if (!flag) + { + EditorGUILayout.HelpBox(errorMessage, MessageType.Error); + } + EditorGUILayout.Space(); + using (new EditorGUI.DisabledScope(!flag)) + { + if (GUILayout.Button("Run All", gUIStyle2)) + { + StartAutoMorphing(_edenAutoMorpher, morpherMode); + } + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + _showStepByStepProgress = EditorGUILayout.Foldout(_showStepByStepProgress, "Step-by-step progress", toggleOnLabelClick: true); + EditorGUI.indentLevel--; + if (!_showStepByStepProgress) + { + return; + } + EditorGUILayout.Space(); + using (new EditorGUILayout.HorizontalScope()) + { + if (GUILayout.Button("1.Run Fitting", gUIStyle2)) + { + StartFitting(_edenAutoMorpher, morpherMode); + } + bool flag2 = _edenAutoMorpher != null && _edenAutoMorpher.IsWeightingReady(isAutoMode: true); + using (new EditorGUI.DisabledScope(!flag2)) + { + if (GUILayout.Button("2.Run Weighting", gUIStyle2)) + { + StartWeighting(_edenAutoMorpher); + } + } + } + } + } + } + + private void RefreshProfiles() + { + ProfileLoader profileLoader = new ProfileLoader(); + _profileNames = profileLoader.GetProfileList(); + if (_profileNames == null || _profileNames.Count == 0) + { + _profileIndex = 0; + _selectedProfileName = ""; + if (_profileName != null) + { + base.serializedObject.Update(); + _profileName.stringValue = ""; + base.serializedObject.ApplyModifiedProperties(); + } + return; + } + int num = _profileNames.IndexOf(_selectedProfileName); + if (num >= 0) + { + _profileIndex = num; + } + else + { + _profileIndex = Mathf.Clamp(_profileIndex, 0, _profileNames.Count - 1); + } + _selectedProfileName = _profileNames[_profileIndex]; + if (_profileName != null) + { + base.serializedObject.Update(); + _profileName.stringValue = _selectedProfileName; + base.serializedObject.ApplyModifiedProperties(); + } + } + + private void ShowInspectorProgress() + { + if (_isProgressing) + { + using (new EditorGUI.DisabledGroupScope(disabled: false)) + { + ProcessInfo processInfo = _edenAutoMorpher.GetProcessInfo(); + EditorGUILayout.HelpBox("ProgressInfo\n\n" + processInfo.title + "\n" + processInfo.text, MessageType.Info); + EditorGUILayout.Space(); + EditorGUI.ProgressBar(GUILayoutUtility.GetRect(18f, 18f, "TextField"), processInfo.progress, $"{processInfo.progress * 100f:0}%"); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + if (GUILayout.Button("Stop")) + { + StopProcess(); + _edenAutoMorpher.StopProcess(); + _resultInfo.processEndState = "Stopped"; + } + } + } + else if (_resultInfo.isComplicated) + { + EditorGUILayout.HelpBox(_resultInfo.processTyep + " is " + _resultInfo.processEndState + "\n - Progressing time : " + _resultInfo.processTime, MessageType.Info); + if (_resultInfo.processEndState == "Failed") + { + EditorGUILayout.Space(6f); + using (new EditorGUILayout.VerticalScope(new GUIStyle(EditorStyles.helpBox) + { + padding = new RectOffset(10, 10, 8, 8) + })) + { + GUIStyle style = new GUIStyle(EditorStyles.boldLabel) + { + normal = + { + textColor = Color.red + } + }; + EditorGUILayout.LabelField("Error Occurred", style); + EditorGUILayout.Space(4f); + float height = 160f; + _errorMessageScroll = EditorGUILayout.BeginScrollView(_errorMessageScroll, GUILayout.Height(height)); + EditorGUILayout.TextArea(_resultInfo.errorMessage ?? string.Empty, GUILayout.ExpandHeight(expand: true)); + EditorGUILayout.EndScrollView(); + } + } + } + EditorGUILayout.Space(); + } + + private void DrawMeshProperties() + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + _showMeshDetails = EditorGUILayout.Foldout(_showMeshDetails, "Mesh Info", toggleOnLabelClick: true); + } + if (_showMeshDetails) + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + EditorGUI.indentLevel++; + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Mesh Lists", EditorStyles.boldLabel); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Source Avatar Meshes", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(_sourceBodyMeshes, new GUIContent("Source Body Meshes"), true); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Target Avatar Meshes", EditorStyles.boldLabel); + EditorGUILayout.PropertyField(_targetBodyMeshes, new GUIContent("Target Body Meshes"), true); + EditorGUI.indentLevel--; + } + } + } + + private void DrawBasicProperties(MorpherMode morpherMode) + { + EditorGUILayout.LabelField("Body Mesh", EditorStyles.boldLabel); + using (new EditorGUI.DisabledScope(disabled: true)) + { + GUIStyle gUIStyle = new GUIStyle(EditorStyles.miniLabel); + gUIStyle.wordWrap = true; + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.BodyMeshInfo"), gUIStyle, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 40f)); + } + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_isBodyAutoSetup, new GUIContent(LanguageManager.Get("UI.Property.BodyMeshTitle")), true); + if (!_edenAutoMorpher.isBodyAutoSetup) + { + if (morpherMode != MorpherMode.ProfileMorpher) + { + EditorGUILayout.LabelField("Source Avatar Meshes", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_sourceBodyMeshes, new GUIContent("Source Body Meshes"), true); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + } + EditorGUILayout.LabelField("Target Avatar Meshes", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_targetBodyMeshes, new GUIContent("Target Body Meshes"), true); + EditorGUI.indentLevel--; + } + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Min Margin", EditorStyles.boldLabel); + using (new EditorGUI.DisabledScope(disabled: true)) + { + GUIStyle gUIStyle2 = new GUIStyle(EditorStyles.miniLabel); + gUIStyle2.wordWrap = true; + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.MinMarginInfo"), gUIStyle2, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 40f)); + } + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_minMargin); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Skip Foot Fitting", EditorStyles.boldLabel); + using (new EditorGUI.DisabledScope(disabled: true)) + { + GUIStyle style = new GUIStyle(EditorStyles.miniLabel) + { + wordWrap = true + }; + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.SkipFootFittingInfo"), style, GUILayout.MaxWidth(EditorGUIUtility.currentViewWidth - 40f)); + } + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_skipFootFitting); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Remove AutoMorphed Other Clothes", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_isRemoveAutoMorphedClothes, new GUIContent("Remove AutoMorphed Other Clothes")); + EditorGUI.indentLevel--; + EditorGUILayout.Space(); + } + + private void DrawAdvanceProperties() + { + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + _showAdvanced = EditorGUILayout.Foldout(_showAdvanced, "Advanced Option", toggleOnLabelClick: true); + } + if (!_showAdvanced) + { + return; + } + using (new EditorGUI.DisabledGroupScope(_isProgressing)) + { + GUIStyle style = new GUIStyle(GUI.skin.box) + { + padding = new RectOffset(12, 12, 10, 12), + margin = new RectOffset(0, 0, 8, 8) + }; + GUIStyle style2 = new GUIStyle(EditorStyles.boldLabel) + { + fontSize = 13 + }; + EditorGUI.indentLevel++; + EditorGUILayout.LabelField("- Fitting Settings", style2); + using (new EditorGUILayout.VerticalScope(style)) + { + using (new EditorGUI.DisabledScope(disabled: true)) + { + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.SigmaInfo"), EditorStyles.miniLabel); + } + EditorGUILayout.PropertyField(_sigma); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + using (new EditorGUI.DisabledScope(disabled: true)) + { + GUIStyle style3 = new GUIStyle(EditorStyles.miniLabel) + { + wordWrap = true + }; + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.SmoothingInfo"), style3); + } + EditorGUILayout.PropertyField(_smoothingIteration); + EditorGUILayout.Space(); + EditorGUILayout.Space(); + EditorGUILayout.LabelField("Fitting Iterations", EditorStyles.boldLabel); + using (new EditorGUI.DisabledScope(disabled: true)) + { + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.IterationInfo"), EditorStyles.miniLabel); + } + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_fittingExpandIteration, new GUIContent("Expand Iteration")); + EditorGUILayout.PropertyField(_fittingShrinkIteration, new GUIContent("Shrink Iteration")); + EditorGUI.indentLevel--; + } + EditorGUILayout.Space(); + EditorGUILayout.LabelField("- Weighting Settings", style2); + using (new EditorGUILayout.VerticalScope(style)) + { + EditorGUILayout.PropertyField(_transferWeightToAvatar, new GUIContent("Transfer Weight To Avatar")); + bool boolValue = _transferWeightToAvatar.boolValue; + if (boolValue) + { + using (new EditorGUI.DisabledScope(!boolValue)) + { + using (new EditorGUI.DisabledScope(disabled: true)) + { + EditorGUILayout.LabelField(LanguageManager.Get("UI.Property.ReparentAccessoryBones"), EditorStyles.miniLabel); + } + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_isReparentAccessoryBonesToTargetAvatar, new GUIContent("Reparent Accessory Bones")); + EditorGUI.indentLevel--; + } + } + else + { + if (_isReparentAccessoryBonesToTargetAvatar.boolValue) + { + _isReparentAccessoryBonesToTargetAvatar.boolValue = false; + } + EditorGUILayout.Space(); + EditorGUI.indentLevel++; + EditorGUILayout.LabelField("Adds an anchor bone to preserve clothes bone rotation.", EditorStyles.boldLabel); + EditorGUI.indentLevel++; + EditorGUILayout.PropertyField(_addAnchorBone, new GUIContent("Add Anchor Bone")); + EditorGUI.indentLevel--; + EditorGUI.indentLevel--; + } + } + EditorGUI.indentLevel--; + } + } + + private void StartAutoMorphing(EdenAutoMorpher _edenAutoMorpher, MorpherMode _modeIndex) + { + StartProcess(_edenAutoMorpher, _edenAutoMorpher.AutoMorphingEnumerator(_modeIndex), "Auto Morphing"); + } + + private void StartFitting(EdenAutoMorpher _edenAutoMorpher, MorpherMode morpherMode) + { + StartProcess(_edenAutoMorpher, _edenAutoMorpher.FittingEnumerator(morpherMode), "Fitting"); + } + + private void StartWeighting(EdenAutoMorpher _edenAutoMorpher) + { + StartProcess(_edenAutoMorpher, _edenAutoMorpher.WeightingEnumerator(), "Weighting"); + } + + private void StartProcess(EdenAutoMorpher _edenAutoMorpher, IEnumerator enumerator, string processType) + { + if (_morphingEnumerator != null) + { + UnityEngine.Debug.LogWarning("[EdenAutoMorpherEditor] Already AutoMorpher is Working"); + return; + } + this._edenAutoMorpher = _edenAutoMorpher; + _morphingEnumerator = enumerator; + _resultInfo.processTyep = processType; + _resultInfo.processTime = string.Empty; + _resultInfo.processEndState = "Unknown"; + _resultInfo.isComplicated = false; + _stopwatch.Reset(); + _stopwatch.Start(); + _logCollector.BeginCapture(); + EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, new EditorApplication.CallbackFunction(OnEditorUpdate)); + EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Combine(EditorApplication.update, new EditorApplication.CallbackFunction(OnEditorUpdate)); + UnityEngine.Debug.Log("[EdenAutoMorpherEditor] Start " + processType + " Process"); + } + + private void StopProcess() + { + if (_isUpdateWorking) + { + EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, new EditorApplication.CallbackFunction(OnEditorUpdate)); + if (_stopwatch.IsRunning) + { + _stopwatch.Stop(); + double totalSeconds = _stopwatch.Elapsed.TotalSeconds; + _resultInfo.processTime = $"{totalSeconds:F2} sec"; + _resultInfo.isComplicated = true; + } + EditorUtility.ClearProgressBar(); + SceneView.RepaintAll(); + EditorApplication.QueuePlayerLoopUpdate(); + InternalEditorUtility.RepaintAllViews(); + _logCollector.SaveToTextFile("EdenAutoMorpher_Report.txt", includeWarningsAndInfo: true); + _logCollector.EndCapture(); + _morphingEnumerator = null; + _isProgressing = false; + _isUpdateWorking = false; + UnityEngine.Debug.Log("[EdenAutoMorpherEditor] AutoMorphing Process Ended"); + } + } + + private void OnEditorUpdate() + { + if (_morphingEnumerator == null || _edenAutoMorpher == null) + { + StopProcess(); + return; + } + _isUpdateWorking = true; + try + { + bool flag = _morphingEnumerator.MoveNext(); + ProcessInfo processInfo = _edenAutoMorpher.GetProcessInfo(); + try + { + processInfo = _edenAutoMorpher.GetProcessInfo(); + } + catch + { + processInfo.title = "Eden AutoMorpher"; + processInfo.text = "Processing..."; + processInfo.progress = 0f; + } + if (EditorUtility.DisplayCancelableProgressBar(processInfo.title, processInfo.text, processInfo.progress)) + { + UnityEngine.Debug.Log("[EdenAutoMorpherEditor] User Canceled Process"); + _edenAutoMorpher.StopProcess(); + StopProcess(); + _resultInfo.processEndState = "Stopped"; + } + else if (!flag) + { + StopProcess(); + _resultInfo.processEndState = "Ended"; + } + else + { + Repaint(); + } + } + catch (AutoMorpherException ex) + { + EditorUtility.ClearProgressBar(); + UnityEngine.Debug.LogException(ex); + StopProcess(); + string text = ex.title ?? "Eden AutoMorpher Error"; + string text2 = ex.Message + "\n\nIf you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately."; + EditorUtility.DisplayDialog(text, text2, "OK"); + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text + "\n\n" + text2; + } + catch (Exception ex2) + { + EditorUtility.ClearProgressBar(); + UnityEngine.Debug.LogException(ex2); + StopProcess(); + string text3 = "Unexpected Error"; + string text4 = "If you need assistance resolving this issue,\nplease contact us on Discord and include the following information:\n\n1. A screenshot of the Console window showing the error message.\n2. A screenshot of the current Hierarchy window.\n3. This error dialog, including the avatar and clothing information used.\n4. The log file saved at:\n Assets/@Eden_Tools/Eden_AutoMorpher/Logs/EdenAutoMorpher_Report.txt\n\nProviding these details will help us identify the issue more accurately.\n\nError Details:\n" + ex2.ToString(); + EditorUtility.DisplayDialog(text3, text4, "OK"); + _resultInfo.processEndState = "Failed"; + _resultInfo.errorMessage = text3 + "\n\n" + text4; + } + } +} diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs.meta b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs.meta new file mode 100644 index 0000000..54bac03 --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/EdenAutoMorpherEditor.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2a5cebf384008fb4fa1e1141a4845238 \ No newline at end of file diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs new file mode 100644 index 0000000..94e9613 --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs @@ -0,0 +1,16 @@ +// Warning: Some assembly references could not be resolved automatically. This might lead to incorrect decompilation of some parts, +// for ex. property getter/setter access. To get optimal decompilation results, please manually add the missing references to the list of loaded assemblies. +// EdenAutoMorpherEditor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null +// Eden.AutoMorpher.ResultInfo +public class ResultInfo +{ + public bool isComplicated; + + public string processTyep = ""; + + public string processEndState = ""; + + public string processTime = ""; + + public string errorMessage = ""; +} diff --git a/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs.meta b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs.meta new file mode 100644 index 0000000..204ab5a --- /dev/null +++ b/Assets/@Eden_Tools/Eden_AutoMorpher/Editor/ResultInfo.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 45a0e5ffc6837dc48b871f340e85e7a4 \ No newline at end of file