/// <summary> /// Destroys loose preset objects that live in memory and not in assets /// </summary> public static void CleanupPresetsOfType <T>() where T : PumkinPreset { var tools = PumkinsAvatarTools.Instance; string typeName = typeof(T).Name; var presets = GameObject.FindObjectsOfType <T>(); Type t = typeof(T); Type tP = typeof(PumkinPreset); foreach (var preset in presets) { if (preset && !Helpers.IsAssetInAssets(preset)) { PumkinsAvatarTools.LogVerbose($"Destroying orphanned {typeName}"); Helpers.DestroyAppropriate(preset); } } if (typeof(T) == typeof(PumkinsCameraPreset) || t == tP) { CameraPresets.RemoveAll(o => o == default(PumkinsCameraPreset) || !Helpers.IsAssetInAssets(o)); } if (typeof(T) == typeof(PumkinsPosePreset) || t == tP) { PosePresets.RemoveAll(o => o == default(PumkinsPosePreset) || !Helpers.IsAssetInAssets(o)); } if (typeof(T) == typeof(PumkinsBlendshapePreset) || t == tP) { BlendshapePresets.RemoveAll(o => o == default(PumkinsBlendshapePreset) || !Helpers.IsAssetInAssets(o)); } PumkinsAvatarTools.RefreshPresetIndex <T>(); }
/// <summary> /// TODO: Replace with one that reads only the needed lines /// </summary> static bool ReplacePresetGUIDTemp(string filePath, string newGUID) { filePath = Helpers.AbsolutePathToLocalAssetsPath(filePath); if (Helpers.StringIsNullOrWhiteSpace(filePath) || Helpers.StringIsNullOrWhiteSpace(newGUID)) { PumkinsAvatarTools.LogVerbose($"Filepath ({filePath}) or GUID ({newGUID}) is empty", LogType.Warning); return(false); } else if (!File.Exists(filePath)) { PumkinsAvatarTools.Log($"File {filePath} doesn't exist. Can't fix preset references", LogType.Warning); return(false); } var lines = File.ReadAllLines(filePath); for (int i = 0; i < lines.Length; i++) { var line = lines[i]; if (!line.Contains("m_Script")) { continue; } lines[i] = Helpers.ReplaceGUIDInLine(line, newGUID, out bool replaced); if (replaced) { File.WriteAllLines(filePath, lines); return(true); } break; } return(false); }
/// <summary> /// Destroys ParticleSystem in object /// </summary> /// <param name="destroyInChildrenToo">Whether to destroy particle systems in children as well</param> internal static void DestroyParticleSystems(GameObject from, bool destroyInChildrenToo = true) { var sysList = new List <ParticleSystem>(); if (destroyInChildrenToo) { sysList.AddRange(from.GetComponentsInChildren <ParticleSystem>(true)); } else { sysList.AddRange(from.GetComponents <ParticleSystem>()); } foreach (var p in sysList) { var rend = p.GetComponent <ParticleSystemRenderer>(); if (rend != null) { GameObject.DestroyImmediate(rend); } PumkinsAvatarTools.Log(Strings.Log.removeAttempt + " - " + Strings.Log.success, LogType.Log, p.ToString(), from.name); GameObject.DestroyImmediate(p); } }
/// <summary> /// Sets all materials on the renderers to copies using fallback shaders /// </summary> /// <param name="renders"></param> internal void SetFallbacks(Renderer[] renders) { foreach (var r in renders) { var serial = new SerializedObject(r); var materials = serial.FindProperty("m_Materials"); for (int i = 0; i < r.sharedMaterials.Length; i++) { var oldMat = r.sharedMaterials[i]; if (AssetDatabaseHelpers.IsBuiltInAsset(oldMat)) { continue; } var newMat = cache.GetCachedCopy(oldMat, out bool _); var fallback = MaterialManager.CreateFallbackMaterial(newMat, Color.white); var mat = materials.GetArrayElementAtIndex(i); mat.objectReferenceValue = newMat; } serial.ApplyModifiedProperties(); AssetDatabase.SaveAssets(); PumkinsAvatarTools.Log($"Set fallback materials for <b>{r.gameObject.name}</b>"); } }
private static void LoadTranslationPresets() { var presets = Resources.LoadAll <Preset>(resourceTranslationPath); var translations = Resources.LoadAll <PumkinsTranslation>(resourceTranslationPath); foreach (var p in presets) { var mods = p.PropertyModifications; string langName = mods.FirstOrDefault(m => m.propertyPath == "languageName").value; string author = mods.FirstOrDefault(m => m.propertyPath == "author").value; if (Helpers.StringIsNullOrWhiteSpace(langName) || Helpers.StringIsNullOrWhiteSpace(author)) { PumkinsAvatarTools.Log(Strings.Log.invalidTranslation, LogType.Error, p.name); continue; } var tr = translations.FirstOrDefault(t => t.author == author && t.languageName == langName); if (tr == default) { tr = ScriptableObjectUtility.CreateAndSaveAsset <PumkinsTranslation>("language_" + langName, translationPath); } if (p.CanBeAppliedTo(tr)) { p.ApplyTo(tr); } else { PumkinsAvatarTools.Log(Strings.Log.cantApplyPreset, LogType.Error); } } }
/// <summary> /// Destroys loose preset objects that live in memory and not in assets /// </summary> public static void CleanupPresetsOfType <T>() where T : PumkinPreset { var tools = PumkinsAvatarTools.Instance; foreach (var p in GameObject.FindObjectsOfType <T>()) { if (p && string.IsNullOrEmpty(AssetDatabase.GetAssetPath(p))) { Debug.Log("Destroying orphanned " + typeof(T).Name); GameObject.DestroyImmediate(p); } } if (typeof(T) == typeof(PumkinsCameraPreset)) { CameraPresets.RemoveAll(o => o == default(PumkinsCameraPreset) || string.IsNullOrEmpty(AssetDatabase.GetAssetPath(o)) || string.IsNullOrEmpty(o.name)); } else if (typeof(T) == typeof(PumkinsPosePreset)) { PosePresets.RemoveAll(o => o == default(PumkinsPosePreset) || string.IsNullOrEmpty(AssetDatabase.GetAssetOrScenePath(o)) || string.IsNullOrEmpty(o.name)); } else if (typeof(T) == typeof(PumkinsBlendshapePreset)) { BlendshapePresets.RemoveAll(o => o == default(PumkinsBlendshapePreset) || string.IsNullOrEmpty(AssetDatabase.GetAssetOrScenePath(o)) || string.IsNullOrEmpty(o.name)); } PumkinsAvatarTools.RefreshPresetIndex <T>(); }
private void OnDestroy() { PumkinsAvatarTools.RestoreCameraRT(PumkinsAvatarTools.SelectedCamera); if (editingExistingPreset) { GetNewOffsetsAndApplyToPreset(); } }
public static void LoadTranslations() { var guids = AssetDatabase.FindAssets(typeof(PumkinsTranslation).Name); translationScriptGUID = guids[0]; var def = PumkinsTranslation.GetOrCreateDefaultTranslation(); for (int i = Languages.Count - 1; i >= 0; i--) { var lang = Languages[i]; if (i == 0 && def.Equals(lang)) { break; } if (!Helpers.IsAssetInAssets(lang)) { Helpers.DestroyAppropriate(lang, true); //careful with allow destroying assets here Languages.RemoveAt(i); } } //LoadTranslationPresets(); FixTranslationAssets(); if (Languages.Count == 0 || !def.Equals(Languages[0])) { Languages.Insert(0, PumkinsTranslation.Default); } var loaded = Resources.LoadAll <PumkinsTranslation>(resourceTranslationPath); foreach (var l in loaded) { int i = Languages.IndexOf(l); if (i != -1) { Languages[i] = l; } else { Languages.Add(l); } } string langs = "Loaded languages: {"; for (int i = 0; i < Languages.Count; i++) { langs += (" " + Languages[i].languageName); langs += (i != Languages.Count - 1) ? "," : ""; } langs += " }"; PumkinsAvatarTools.LogVerbose(langs); }
private void OnGUI() { PumkinsBlendshapePreset preset = (PumkinsBlendshapePreset)CreatePresetPopupBase.preset; if (!preset) { AssignOrCreatePreset <PumkinsBlendshapePreset>(preset); return; } try { scroll = EditorGUILayout.BeginScrollView(scroll); { EditorGUILayout.Space(); preset.name = EditorGUILayout.TextField(Strings.Presets.presetName, preset.name); Helpers.DrawGUILine(); PumkinsAvatarTools.DrawAvatarSelectionWithButtonGUI(false, false); Helpers.DrawGUILine(); DrawBlendshapePresetControls(); Helpers.DrawGUILine(); EditorGUI.BeginDisabledGroup(string.IsNullOrEmpty(preset.name) || !PumkinsAvatarTools.SelectedAvatar); { if (!editingExistingPreset) { _overwriteFile = GUILayout.Toggle(_overwriteFile, Strings.Presets.overwriteFile); if (GUILayout.Button(Strings.Buttons.savePreset, Styles.BigButton)) { EditorApplication.delayCall += () => { preset.SavePreset(_overwriteFile); Close(); }; } } } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndScrollView(); CreatePresetPopupBase.preset = preset; } catch { if (this) { Close(); } } }
public static void ResetPrefs() { EditorPrefs.DeleteKey("PumkinToolsWindow"); ToolsWindow = null; _DependecyChecker.Status = _DependecyChecker.CheckerStatus.DEFAULT; if (_window) { _window.Repaint(); } }
/// <summary> /// Destroy all components of type in object and it's children /// </summary> internal static void DestroyAllComponentsOfType(GameObject obj, Type type, bool ignoreRoot, bool useIgnoreList) { Transform oldParent = obj.transform.parent; obj.transform.parent = null; try { string log = ""; Component[] comps = obj.transform.GetComponentsInChildren(type, true); if (comps != null && comps.Length > 0) { for (int i = 0; i < comps.Length; i++) { if ((ignoreRoot && comps[i].transform.parent == null) || (useIgnoreList && Helpers.ShouldIgnoreObject(comps[i].transform, PumkinsAvatarTools.Settings._copierIgnoreArray, PumkinsAvatarTools.Settings.bCopier_ignoreArray_includeChildren))) { continue; } log = Strings.Log.removeAttempt + " - "; string name = comps[i].name; if (!PrefabUtility.IsPartOfPrefabInstance(comps[i])) { try { Helpers.DestroyAppropriate(comps[i]); log += Strings.Log.success; PumkinsAvatarTools.Log(log, LogType.Log, type.Name, name); } catch (Exception e) { log += Strings.Log.failed + " - " + e.Message; PumkinsAvatarTools.Log(log, LogType.Exception, type.Name, name); } } else { PumkinsAvatarTools.Log(Strings.Log.cantBeDestroyedPartOfPrefab, LogType.Warning, name, type.Name); } } } } finally { obj.transform.parent = oldParent; } }
void ApplyHumanPose(GameObject avatar, PumkinsPosePreset hp) { Undo.RegisterFullObjectHierarchyUndo(avatar, "Load Human Pose"); Vector3 pos = avatar.transform.position; Quaternion rot = avatar.transform.rotation; avatar.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); hp.ApplyPreset(avatar); PumkinsAvatarTools.OnPoseWasChanged(PumkinsAvatarTools.PoseChangeType.Normal); avatar.transform.SetPositionAndRotation(pos, rot); }
public override bool ApplyPreset(GameObject avatar) { if (!avatar || renderers == null) { PumkinsAvatarTools.Log(Strings.Warning.invalidPreset, LogType.Warning, name); return(false); } for (int i = 0; i < renderers.Count; i++) { if (renderers[i] == null) { continue; } var t = avatar.transform.Find(renderers[i].rendererPath); if (t) { var render = t.GetComponent <SkinnedMeshRenderer>(); if (render) { for (int j = 0; j < renderers[i].blendshapes.Count; j++) { int index = render.sharedMesh.GetBlendShapeIndex(renderers[i].blendshapes[j].name); if (index == -1) { foreach (string name in renderers[i].blendshapes[j].otherNames) { index = render.sharedMesh.GetBlendShapeIndex(name); if (index != -1) { break; } } } if (index == -1) { continue; } float weight = renderers[i].blendshapes[j].weight; render.SetBlendShapeWeight(index, weight); } } } } return(true); }
public static void SetDefaultPoseByName(GameObject avatar, string poseName) { PumkinsPosePreset pose = DefaultPoses.Find(o => o.name.ToLower() == poseName.ToLower()); if (poseName.ToLower() == "tpose") { PumkinsAvatarTools.OnPoseWasChanged(PumkinsAvatarTools.PoseChangeType.Reset); } else { PumkinsAvatarTools.OnPoseWasChanged(PumkinsAvatarTools.PoseChangeType.Normal); } pose.ApplyPreset(avatar); }
public static void OnPoseWasChanged(PoseChangeType changeType) { //bool toggle = false; //var bonesToKeepDisabled = new List<DynamicBone>(); //ToggleDynamicBonesEnabledState(SelectedAvatar, ref toggle, ref bonesToKeepDisabled); if (PoseChanged != null) { PoseChanged.Invoke(changeType); } //EditorApplication.delayCall += () => ToggleDynamicBonesEnabledState(SelectedAvatar, ref toggle, ref bonesToKeepDisabled); //PumkinsAvatarTools.RefreshDynamicBoneTransforms(SelectedAvatar); PumkinsAvatarTools.LogVerbose("Pose was changed and OnPoseWasChanged() was called with changeType as " + changeType.ToString()); }
public void OnGUI() { //deltaTime = Time.time - lastTime; //lastTime = Time.time; EditorGUILayout.BeginHorizontal(); { EditorGUILayout.LabelField(Strings.PoseEditor.title, Styles.Label_mainTitle); if (GUILayout.Button(Icons.Settings, Styles.IconButton)) { _openedSettings = !_openedSettings; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.LabelField(Strings.PoseEditor.version); EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); { PumkinsAvatarTools.DrawAvatarSelectionWithButtonGUI(); } //if(GUILayout.Button("Dump muscle names")) //{ // string s = ""; // foreach(string m in HumanTrait.MuscleName) // { // s += "\"" + m + "\",\n"; // } // Debug.Log(s); //} Helpers.DrawGUILine(); if (_openedSettings) { DrawSettingsGUI(); } else { DrawMainGUI(); } }
/// <summary> /// Destroys all Missing Script components on avatar /// </summary> internal static void DestroyMissingScripts(GameObject avatar) { #if UNITY_2018 if (EditorApplication.isPlaying) { PumkinsAvatarTools.Log("Can't remove missing scripts in play mode, it causes crashes", LogType.Warning); return; } #endif var ts = avatar.GetComponentsInChildren <Transform>(true); foreach (var t in ts) { if (Helpers.DestroyMissingScriptsInGameObject(t.gameObject)) { PumkinsAvatarTools.Log(Strings.Log.hasMissingScriptDestroying, LogType.Log, Helpers.GetTransformPath(t, avatar.transform)); } } }
/// <summary> /// Destroys GameObjects in object and all children, if it has no children and if it's not a bone /// </summary> internal static void DestroyEmptyGameObjects(GameObject from) { var obj = from.GetComponentsInChildren <Transform>(true); var renders = from.GetComponentsInChildren <SkinnedMeshRenderer>(true); var bones = new HashSet <Transform>(); foreach (var r in renders) { foreach (var b in r.bones) { bones.Add(b); } } foreach (var t in obj.OrderBy(o => o.childCount)) { if (t != null && t != t.root && t.GetComponents <Component>().Length == 1 && !bones.Contains(t)) { int c = t.childCount; for (int i = 0; i < t.childCount; i++) { var n = t.GetChild(i); if (!bones.Contains(n)) { c--; } } if (c <= 0 && (t.name.ToLower() != (t.parent.name.ToLower() + "_end"))) { if (PrefabUtility.GetPrefabInstanceStatus(t) == PrefabInstanceStatus.NotAPrefab || PrefabUtility.GetPrefabInstanceStatus(t) == PrefabInstanceStatus.Disconnected) { PumkinsAvatarTools.Log(Strings.Log.hasNoComponentsOrChildrenDestroying, LogType.Log, t.name); GameObject.DestroyImmediate(t.gameObject); } else { PumkinsAvatarTools.Log(Strings.Log.cantBeDestroyedPartOfPrefab, LogType.Warning, t.name, "GameObject"); } } } } }
static void SetupGUID <T>() where T : PumkinPreset { if (typeof(T) == typeof(PumkinPreset)) { SetupAllGUIDs(); // bad redirect to setup all return; } string typeName = typeof(T).Name; var guids = AssetDatabase.FindAssets(typeName); string guid = null; string path = null; foreach (var g in guids) { path = AssetDatabase.GUIDToAssetPath(g); if (!path.EndsWith($"{typeName}.cs")) { continue; } guid = g; break; } if (typeof(T) == typeof(PumkinsBlendshapePreset)) { blendshapePresetScriptGUID = guid; } else if (typeof(T) == typeof(PumkinsCameraPreset)) { cameraPresetScriptGUID = guid; } else if (typeof(T) == typeof(PumkinsPosePreset)) { posePresetScriptGUID = guid; } else { return; } PumkinsAvatarTools.LogVerbose($"Set GUID of {typeof(T).Name} script at {path} to {guid}"); }
public static void FixScriptReferences <T>() where T : PumkinPreset { SetupGUID <T>(); Type t = typeof(T); Type pT = typeof(PumkinPreset); var pathsGuids = new Dictionary <string, string>(); if (t == typeof(PumkinsBlendshapePreset) || t == pT) { pathsGuids.Add(Helpers.LocalAssetsPathToAbsolutePath(localBlendshapesPath), blendshapePresetScriptGUID); } if (t == typeof(PumkinsCameraPreset) || t == pT) { pathsGuids.Add(Helpers.LocalAssetsPathToAbsolutePath(localCamerasPath), cameraPresetScriptGUID); } if (t == typeof(PumkinsPosePreset) || t == pT) { pathsGuids.Add(Helpers.LocalAssetsPathToAbsolutePath(localPosesPath), posePresetScriptGUID); } foreach (var kv in pathsGuids) { var path = kv.Key; var guid = kv.Value; if (!Directory.Exists(path)) { PumkinsAvatarTools.LogVerbose($"Directory {path} doesn't exist. Can't fix references"); continue; } var files = Directory.GetFiles($"{path}", "*.asset", SearchOption.AllDirectories); foreach (var file in files) { if (ReplacePresetGUIDTemp(file, guid)) { AssetDatabase.ImportAsset(Helpers.AbsolutePathToLocalAssetsPath(file), ImportAssetOptions.ForceUpdate); } } PumkinsAvatarTools.LogVerbose($"Fixed references for type {typeof(T).Name}"); } }
/// <summary> /// Assigns back the original materials to the renderers /// </summary> /// <param name="renders"></param> internal void RevertFallbacks(Renderer[] renders) { foreach (var r in renders) { var serial = new SerializedObject(r); var materials = serial.FindProperty("m_Materials"); for (int i = 0; i < r.sharedMaterials.Length; i++) { var newMat = cache.GetOriginalMaterialFromCached(r.sharedMaterials[i]); if (!newMat) { PumkinsAvatarTools.Log($"Can't find original material for material <b>slot {i}</b> on <b>{r.gameObject.name}</b>", LogType.Warning); continue; } var mat = materials.GetArrayElementAtIndex(i); mat.objectReferenceValue = newMat; } PumkinsAvatarTools.Log($"Restored materials for <b>{r.gameObject.name}</b>"); serial.ApplyModifiedProperties(); } }
public override bool ApplyPreset(GameObject avatar) { if (!avatar) { return(false); } Undo.RegisterFullObjectHierarchyUndo(avatar, "Apply Pose"); PumkinsAvatarTools.ResetPose(avatar); if (presetMode == PosePresetMode.HumanPose) { Animator anim = avatar.GetComponent <Animator>(); if (anim && anim.avatar && anim.avatar.isHuman) { Vector3 pos = avatar.transform.position; Quaternion rot = avatar.transform.rotation; avatar.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); var humanPoseHandler = new HumanPoseHandler(anim.avatar, avatar.transform); var humanPose = new HumanPose(); humanPoseHandler.GetHumanPose(ref humanPose); humanPose.muscles = muscles; if (PumkinsAvatarTools.Settings.posePresetTryFixSinking) { if (humanPose.bodyPosition.y < 1 && !Mathf.Approximately(humanPose.bodyPosition.y, 0)) { PumkinsAvatarTools.Log(Strings.PoseEditor.bodyPositionYTooSmall, LogType.Warning, humanPose.bodyPosition.y.ToString()); humanPose.bodyPosition.y = 1; } } if (PumkinsAvatarTools.Settings.posePresetApplyBodyPosition) { humanPose.bodyPosition = bodyPosition; } if (PumkinsAvatarTools.Settings.posePresetApplyBodyRotation) { humanPose.bodyRotation = bodyRotation; } humanPoseHandler.SetHumanPose(ref humanPose); avatar.transform.SetPositionAndRotation(pos, rot); PumkinsPoseEditor.OnPoseWasChanged(PumkinsPoseEditor.PoseChangeType.Reset); return(true); } else { PumkinsAvatarTools.Log(Strings.Log.cantSetPoseNonHumanoid, LogType.Error, name); return(false); } } else { if (!avatar) { return(false); } for (int i = 0; i < transformPaths.Count; i++) { var t = avatar.transform.Find(transformPaths[i]); if (t != null) { t.localEulerAngles = transformRotations[i]; } } return(true); } }
private void DrawMainGUI() { if (!PumkinsAvatarTools.SelectedAvatar || !PumkinsAvatarTools.SelectedAvatarIsHuman) { EditorGUILayout.LabelField(Strings.PoseEditor.selectHumanoidAvatar, Styles.HelpBox_OneLine); Helpers.DrawGUILine(); return; } DrawPoseFromAnimationGUI(); //Draw the toolbar then get the muscle ranges based on it's selection toolbarSelection = GUILayout.Toolbar(toolbarSelection, new string[] { "Body", "Head", "Arms", "Legs", "Fingers" }); EditorGUILayout.Space(); scroll = GUILayout.BeginScrollView(scroll); { List <Vector2Int> muscleRanges = new List <Vector2Int>(); switch (toolbarSelection) { case 0: muscleRanges.Add(PumkinsMuscleDefinitions.bodyRange); break; case 1: muscleRanges.Add(PumkinsMuscleDefinitions.headRange); break; case 2: muscleRanges.Add(PumkinsMuscleDefinitions.leftArmRange); muscleRanges.Add(PumkinsMuscleDefinitions.rightArmRange); break; case 3: muscleRanges.Add(PumkinsMuscleDefinitions.leftLegRange); muscleRanges.Add(PumkinsMuscleDefinitions.rightLegRange); break; case 4: muscleRanges.Add(PumkinsMuscleDefinitions.leftFingersRange); muscleRanges.Add(PumkinsMuscleDefinitions.rightFingersRange); break; default: muscleRanges.Add(new Vector2Int(0, HumanTrait.MuscleCount)); break; } //Draw sliders for the muscle ranges and apply the changes if they've changed EditorGUI.BeginChangeCheck(); { for (int i = 0; i < muscleRanges.Count; i++) { Vector2Int range = muscleRanges[i]; for (int j = range.x; j < range.y; j++) { avatarPose.muscles[j] = EditorGUILayout.Slider(new GUIContent(HumanTrait.MuscleName[j]), avatarPose.muscles[j], -sliderRange, sliderRange); } if (i != muscleRanges.Count - 1) { EditorGUILayout.Space(); } } } if (EditorGUI.EndChangeCheck()) { if (PumkinsAvatarTools.SelectedAvatar) { if (PumkinsAvatarTools.Instance.posePresetTryFixSinking && avatarPose.bodyPosition.y > 0 && avatarPose.bodyPosition.y <= 0.01f) { PumkinsAvatarTools.Log(Strings.PoseEditor.bodyPositionYTooSmall, LogType.Warning, avatarPose.bodyPosition.y.ToString()); avatarPose.bodyPosition.y = 1; } Undo.RegisterCompleteObjectUndo(PumkinsAvatarTools.SelectedAvatar, "Pose Editor: Set pose from sliders"); avatarPoseHandler.SetHumanPose(ref avatarPose); } } Helpers.DrawGUILine(); PumkinsAvatarTools.Instance.posePresetApplyBodyPosition = GUILayout.Toggle(PumkinsAvatarTools.Instance.posePresetApplyBodyPosition, Strings.Thumbnails.applyBodyPosition); PumkinsAvatarTools.Instance.posePresetApplyBodyRotation = GUILayout.Toggle(PumkinsAvatarTools.Instance.posePresetApplyBodyRotation, Strings.Thumbnails.applyBodyRotation); EditorGUILayout.Space(); PumkinsAvatarTools.Instance.posePresetTryFixSinking = GUILayout.Toggle(PumkinsAvatarTools.Instance.posePresetTryFixSinking, Strings.Thumbnails.tryFixPoseSinking); PumkinsAvatarTools.Instance.DrawPresetGUI <PumkinsPosePreset>(); } GUILayout.EndScrollView(); }
protected override void RefreshSelectedPresetIndex() { PumkinsAvatarTools.RefreshPresetIndexByString <PumkinsPosePreset>(preset.name); }
/// <summary> /// Sets hardcoded TPose. /// </summary> public static void SetTPoseHardcoded(GameObject avatar) { Undo.RegisterFullObjectHierarchyUndo(avatar, "Set TPose"); var anim = avatar.GetComponent <Animator>(); if (anim && anim.avatar && anim.avatar.isHuman) { Vector3 pos = avatar.transform.position; Quaternion rot = avatar.transform.rotation; avatar.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity); var humanPoseHandler = new HumanPoseHandler(anim.avatar, avatar.transform); var humanPose = new HumanPose(); humanPoseHandler.GetHumanPose(ref humanPose); //A long time ago CATS used to export avatars with a Armature scale of 100. This caused issues applying poses. //For now we'll just hardcode search for "Armature". //TODO: Find a better way to get the armature and check if it's scale could cause issues when tposing Transform armature = avatar.transform.Find("Armature"); if (!(armature && armature.localScale == Vector3.one)) { if (humanPose.bodyPosition.y < 1 && !Mathf.Approximately(humanPose.bodyPosition.y, 1)) { humanPose.bodyPosition.y = 1; PumkinsAvatarTools.LogVerbose(Strings.PoseEditor.bodyPositionYTooSmall, LogType.Warning, humanPose.bodyPosition.y.ToString()); } } #region Hardcoded TPose Values humanPose.muscles[0] = -6.830189E-07f; humanPose.muscles[1] = 4.268869E-08f; humanPose.muscles[2] = 4.268868E-08f; humanPose.muscles[3] = -8.537737E-08f; humanPose.muscles[4] = 0f; humanPose.muscles[5] = 0f; humanPose.muscles[6] = 0f; humanPose.muscles[7] = 0f; humanPose.muscles[8] = 0f; humanPose.muscles[9] = 4.268868E-08f; humanPose.muscles[10] = -8.537737E-08f; humanPose.muscles[11] = 4.268868E-08f; humanPose.muscles[12] = 3.415095E-07f; humanPose.muscles[13] = 0f; humanPose.muscles[14] = 0f; humanPose.muscles[15] = 0f; humanPose.muscles[16] = 0f; humanPose.muscles[17] = 0f; humanPose.muscles[18] = 0f; humanPose.muscles[19] = 0f; humanPose.muscles[20] = 0f; humanPose.muscles[21] = 0.5994893f; humanPose.muscles[22] = 0.004985309f; humanPose.muscles[23] = 0.00297395f; humanPose.muscles[24] = 0.9989594f; humanPose.muscles[25] = -0.02284526f; humanPose.muscles[26] = -3.449878E-05f; humanPose.muscles[27] = -0.0015229f; humanPose.muscles[28] = -4.781132E-07f; humanPose.muscles[29] = 0.599489f; humanPose.muscles[30] = 0.004985378f; humanPose.muscles[31] = 0.002974245f; humanPose.muscles[32] = 0.9989589f; humanPose.muscles[33] = -0.02284535f; humanPose.muscles[34] = -3.548912E-05f; humanPose.muscles[35] = -0.001522672f; humanPose.muscles[36] = -1.024528E-07f; humanPose.muscles[37] = -2.429621E-07f; humanPose.muscles[38] = 1.549688E-07f; humanPose.muscles[39] = 0.3847253f; humanPose.muscles[40] = 0.310061f; humanPose.muscles[41] = -0.103543f; humanPose.muscles[42] = 0.9925866f; humanPose.muscles[43] = 0.159403f; humanPose.muscles[44] = -0.01539368f; humanPose.muscles[45] = 0.01405432f; humanPose.muscles[46] = 5.680533E-08f; humanPose.muscles[47] = 2.701393E-07f; humanPose.muscles[48] = 0.3847259f; humanPose.muscles[49] = 0.3100605f; humanPose.muscles[50] = -0.1035404f; humanPose.muscles[51] = 0.9925874f; humanPose.muscles[52] = 0.1593992f; humanPose.muscles[53] = -0.01539393f; humanPose.muscles[54] = 0.01405326f; humanPose.muscles[55] = -0.7706841f; humanPose.muscles[56] = 0.423209f; humanPose.muscles[57] = 0.6456643f; humanPose.muscles[58] = 0.6362566f; humanPose.muscles[59] = 0.6677276f; humanPose.muscles[60] = -0.4597229f; humanPose.muscles[61] = 0.811684f; humanPose.muscles[62] = 0.8116837f; humanPose.muscles[63] = 0.6683907f; humanPose.muscles[64] = -0.5737826f; humanPose.muscles[65] = 0.8116839f; humanPose.muscles[66] = 0.8116843f; humanPose.muscles[67] = 0.6670681f; humanPose.muscles[68] = -0.6459302f; humanPose.muscles[69] = 0.8116837f; humanPose.muscles[70] = 0.8116839f; humanPose.muscles[71] = 0.666789f; humanPose.muscles[72] = -0.4676594f; humanPose.muscles[73] = 0.811684f; humanPose.muscles[74] = 0.8116839f; humanPose.muscles[75] = -0.7706831f; humanPose.muscles[76] = 0.4232127f; humanPose.muscles[77] = 0.6456538f; humanPose.muscles[78] = 0.6362569f; humanPose.muscles[79] = 0.6678051f; humanPose.muscles[80] = -0.4589976f; humanPose.muscles[81] = 0.8116843f; humanPose.muscles[82] = 0.8116842f; humanPose.muscles[83] = 0.668391f; humanPose.muscles[84] = -0.5737844f; humanPose.muscles[85] = 0.811684f; humanPose.muscles[86] = 0.8116837f; humanPose.muscles[87] = 0.6669571f; humanPose.muscles[88] = -0.6492739f; humanPose.muscles[89] = 0.8116841f; humanPose.muscles[90] = 0.8116843f; humanPose.muscles[91] = 0.6667888f; humanPose.muscles[92] = -0.4676568f; humanPose.muscles[93] = 0.8116842f; humanPose.muscles[94] = 0.8116836f; #endregion humanPoseHandler.SetHumanPose(ref humanPose); avatar.transform.SetPositionAndRotation(pos, rot); PumkinsAvatarTools.OnPoseWasChanged(PumkinsAvatarTools.PoseChangeType.Reset); } else { PumkinsAvatarTools.Log(Strings.Log.cantSetPoseNonHumanoid, LogType.Warning, "TPose"); } }
public static void DrawBlendshapeSlidersWithLabels(ref List <PumkinsRendererBlendshapesHolder> rendererHolders, GameObject avatar, int indentLevel = 0, float labelWidthOverride = 0) { if (rendererHolders == null || avatar == null) { return; } EditorGUI.indentLevel += indentLevel; bool[] rendererShapeChanged = new bool[rendererHolders.Count]; //record changes in holder to apply to renderer later for (int i = 0; i < rendererHolders.Count; i++) { Transform renderTransform = avatar.transform.Find(rendererHolders[i].rendererPath); if (!renderTransform) { continue; } SkinnedMeshRenderer renderer = renderTransform.GetComponent <SkinnedMeshRenderer>(); if (!renderer) { continue; } EditorGUILayout.Space(); //Draw renderer dropdown toggle EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true)); { float oldLabelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 0; rendererHolders[i].expandedInUI = EditorGUILayout.Toggle(rendererHolders[i].expandedInUI, Styles.Foldout, GUILayout.MaxWidth(10)); EditorGUIUtility.labelWidth = oldLabelWidth; EditorGUILayout.LabelField(rendererHolders[i].rendererPath); } EditorGUILayout.EndHorizontal(); //Draw renderer dropdown if (rendererHolders[i].expandedInUI) { EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); { EditorGUILayout.BeginVertical(); for (int j = 0; j < rendererHolders[i].blendshapes.Count; j++) { EditorGUI.BeginChangeCheck(); { rendererHolders[i].blendshapes[j].weight = EditorGUILayout.Slider(new GUIContent(rendererHolders[i].blendshapes[j].name), rendererHolders[i].blendshapes[j].weight, 0, 100); } if (EditorGUI.EndChangeCheck()) { rendererShapeChanged[i] = true; } } EditorGUILayout.EndVertical(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); EditorGUILayout.BeginHorizontal(); { if (!EditorApplication.isPlaying && GUILayout.Button(Strings.Buttons.revertRenderer) && renderer) { bool expanded = rendererHolders[i].expandedInUI; PumkinsAvatarTools.ResetRendererBlendshapes(renderer, true); rendererHolders[i] = (PumkinsRendererBlendshapesHolder)renderer; rendererHolders[i].expandedInUI = expanded; } if (GUILayout.Button(Strings.Buttons.resetRenderer)) { bool expanded = rendererHolders[i].expandedInUI; PumkinsAvatarTools.ResetRendererBlendshapes(renderer, false); rendererHolders[i] = (PumkinsRendererBlendshapesHolder)renderer; rendererHolders[i].expandedInUI = expanded; } } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); } } //Apply changes from holder to actual skinned mesh renderer for (int i = 0; i < rendererShapeChanged.Length; i++) { if (!rendererShapeChanged[i]) { continue; } SkinnedMeshRenderer ren; Transform tRen = avatar.transform.Find(rendererHolders[i].rendererPath); if (!tRen) { continue; } ren = tRen.GetComponent <SkinnedMeshRenderer>(); if (!ren) { continue; } foreach (PumkinsBlendshape blendshape in rendererHolders[i].blendshapes) { string name = blendshape.name; int index = ren.sharedMesh.GetBlendShapeIndex(name); if (index == -1 && blendshape.otherNames.Count > 0) { for (int z = 0; z < blendshape.otherNames.Count; z++) { index = ren.sharedMesh.GetBlendShapeIndex(blendshape.otherNames[z]); if (index != -1) { break; } } } if (index != -1) { ren.SetBlendShapeWeight(index, blendshape.weight); } } } if (rendererHolders.Count > 0) { Helpers.DrawGUILine(); } EditorGUI.indentLevel -= indentLevel; }
void OnGUI() { try { PumkinsCameraPreset newPreset = (PumkinsCameraPreset)preset; if (!newPreset) //Not sure I like this part { newPreset = (PumkinsCameraPreset)AssignOrCreatePreset <PumkinsCameraPreset>(null); preset = newPreset; } Rect r = GUILayoutUtility.GetAspectRect(1.3f); EditorGUI.DrawTextureTransparent(r, PumkinsAvatarTools.SelectedCamRT, ScaleMode.ScaleToFit); scroll = EditorGUILayout.BeginScrollView(scroll); { if (newPreset) { newPreset.name = EditorGUILayout.TextField(Strings.Presets.presetName, newPreset.name); EditorGUILayout.Space(); PumkinsAvatarTools.DrawAvatarSelectionWithButtonGUI(false, false); Helpers.DrawGUILine(); PumkinsAvatarTools.SelectedCamera = (Camera)EditorGUILayout.ObjectField(Strings.Presets.camera, PumkinsAvatarTools.SelectedCamera, typeof(Camera), true); EditorGUILayout.Space(); newPreset.offsetMode = (PumkinsCameraPreset.CameraOffsetMode)EditorGUILayout.EnumPopup(Strings.Presets.offsetMode, newPreset.offsetMode); if (newPreset.offsetMode == PumkinsCameraPreset.CameraOffsetMode.Transform) { EditorGUI.BeginDisabledGroup(!PumkinsAvatarTools.SelectedAvatar); { referenceTransform = EditorGUILayout.ObjectField(Strings.Presets.transform, referenceTransform, typeof(Transform), true) as Transform; if (referenceTransform && !referenceTransform.IsChildOf(PumkinsAvatarTools.SelectedAvatar.transform)) { PumkinsAvatarTools.Log(Strings.Presets.transformDoesntBelongToAvatar, LogType.Warning, referenceTransform.name, PumkinsAvatarTools.SelectedAvatar.name); referenceTransform = null; } } } EditorGUILayout.Space(); Helpers.DrawGUILine(); PumkinsAvatarTools.Instance.DrawOverlayGUI(); Helpers.DrawGUILine(); PumkinsAvatarTools.Instance.DrawBackgroundGUI(); Helpers.DrawGUILine(); PumkinsAvatarTools.Instance.DrawCameraControlButtons(); } EditorGUILayout.EndScrollView(); Helpers.DrawGUILine(); if (!editingExistingPreset) { EditorGUI.BeginDisabledGroup(!PumkinsAvatarTools.SelectedCamera || string.IsNullOrEmpty(newPreset.name) || !PumkinsAvatarTools.SelectedAvatar); { _overwriteFile = GUILayout.Toggle(_overwriteFile, Strings.Presets.overwriteFile); EditorGUI.BeginDisabledGroup(newPreset.offsetMode == PumkinsCameraPreset.CameraOffsetMode.Transform && referenceTransform == null); { if (GUILayout.Button(Strings.Buttons.savePreset, Styles.BigButton)) { #if (VRC_SDK_VRCSDK3 || VRC_SDK_VRCSDK2) && !UDON if (newPreset.offsetMode == PumkinsCameraPreset.CameraOffsetMode.Viewpoint && (Avatar.GetComponent <VRC_AvatarDescriptor>() == null)) { PumkinsAvatarTools.Log(Strings.Log.descriptorIsMissingCantGetViewpoint, LogType.Warning); } else #endif if (newPreset.offsetMode == PumkinsCameraPreset.CameraOffsetMode.Transform) { EditorApplication.delayCall += () => { newPreset.SavePreset(referenceTransform.gameObject, PumkinsAvatarTools.SelectedCamera, _overwriteFile); Close(); }; } else { EditorApplication.delayCall += () => { newPreset.SavePreset(PumkinsAvatarTools.SelectedAvatar, PumkinsAvatarTools.SelectedCamera, _overwriteFile); Close(); }; } } EditorGUILayout.Space(); } EditorGUI.EndDisabledGroup(); } EditorGUI.EndDisabledGroup(); } } } catch { if (this) { Close(); } } }
/// <summary> /// Applies preset to selected camera /// </summary> public override bool ApplyPreset(GameObject avatar) { Camera cam = PumkinsAvatarTools.SelectedCamera; if (!cam || !avatar) { return(false); } Undo.RegisterFullObjectHierarchyUndo(cam.gameObject, "Apply Camera Preset"); Transform dummy = null; try { if (offsetMode == CameraOffsetMode.Viewpoint) { dummy = new GameObject("Dummy").transform; var desc = avatar.GetComponent <VRC_AvatarDescriptor>(); if (desc) { dummy.localPosition = desc.transform.position + desc.ViewPosition; cam.transform.localPosition = positionOffset + dummy.transform.localPosition; cam.transform.localEulerAngles = rotationAnglesOffset + dummy.transform.localEulerAngles; } else { PumkinsAvatarTools.Log(Strings.Log.descriptorIsMissingCantGetViewpoint); } } else { Transform t = avatar.transform.Find(transformPath); dummy = new GameObject("Dummy").transform; if (t) { Transform oldCamParent = cam.transform.parent; cam.transform.parent = dummy; cam.transform.localPosition = positionOffset; cam.transform.localEulerAngles = rotationAnglesOffset; dummy.SetPositionAndRotation(t.position, t.rotation); cam.transform.parent = oldCamParent; } } } catch (Exception e) { Debug.LogError(e.Message); if (dummy) { Helpers.DestroyAppropriate(dummy.gameObject); } return(false); } finally { if (dummy) { Helpers.DestroyAppropriate(dummy.gameObject); } } PumkinsAvatarTools.Instance.bThumbnails_use_camera_overlay = useOverlay; if (useOverlay) { PumkinsAvatarTools.Instance.SetOverlayToImageFromPath(overlayImagePath); } PumkinsAvatarTools.Instance.bThumbnails_use_camera_background = useBackground; if (useBackground) { PumkinsAvatarTools.Instance.cameraBackgroundType = backgroundType; switch (backgroundType) { case PumkinsAvatarTools.CameraBackgroundOverrideType.Color: PumkinsAvatarTools.Instance.SetCameraBackgroundToColor(backgroundColor); break; case PumkinsAvatarTools.CameraBackgroundOverrideType.Image: PumkinsAvatarTools.Instance.cameraBackgroundImageTint = backgroundImageTint; PumkinsAvatarTools.Instance.SetBackgroundToImageFromPath(backgroundImagePath); break; case PumkinsAvatarTools.CameraBackgroundOverrideType.Skybox: PumkinsAvatarTools.Instance.SetCameraBackgroundToSkybox(backgroundMaterial); break; default: break; } } PumkinsAvatarTools.Instance.RefreshBackgroundOverrideType(); return(true); }
private void OnGUI() { PumkinsPosePreset preset = (PumkinsPosePreset)CreatePresetPopupBase.preset; if (!preset) { AssignOrCreatePreset <PumkinsPosePreset>(null); return; } try { scroll = EditorGUILayout.BeginScrollView(scroll); { EditorGUILayout.Space(); preset.name = EditorGUILayout.TextField(Strings.Presets.presetName, preset.name); Helpers.DrawGUILine(); PumkinsAvatarTools.DrawAvatarSelectionWithButton(false, false); Helpers.DrawGUILine(); preset.presetMode = (PumkinsPosePreset.PosePresetMode)EditorGUILayout.EnumPopup(Strings.Presets.poseMode, preset.presetMode); Helpers.DrawGUILine(); if (GUILayout.Button(Strings.Buttons.openPoseEditor, Styles.BigButton)) { PumkinsMuscleEditor.ShowWindow(); } Helpers.DrawGUILine(); EditorGUI.BeginDisabledGroup(!PumkinsAvatarTools.SelectedAvatar || !preset || string.IsNullOrEmpty(preset.name)); { if (!editingExistingPreset) { _overwriteFile = GUILayout.Toggle(_overwriteFile, Strings.Presets.overwriteFile); if (GUILayout.Button(Strings.Buttons.savePreset, Styles.BigButton)) { preset.SetupPreset(preset.name, PumkinsAvatarTools.SelectedAvatar, preset.presetMode); if (preset) { EditorApplication.delayCall += () => { preset.SavePreset(_overwriteFile); Close(); }; } } } } EditorGUI.EndDisabledGroup(); } EditorGUILayout.EndScrollView(); CreatePresetPopupBase.preset = preset; } catch { if (this) { Close(); } } }
private void OnDestroy() { PumkinsAvatarTools.DestroyDummies(); }