MaidFaceSliderPane.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using Newtonsoft.Json;
  6. using UnityEngine;
  7. using static MeidoPhotoStudio.Plugin.Meido;
  8. namespace MeidoPhotoStudio.Plugin;
  9. public class MaidFaceSliderPane : BasePane
  10. {
  11. private static readonly Dictionary<string, float> SliderLimits = new()
  12. {
  13. ["eyeclose"] = 1f, // Eye Shut
  14. ["eyeclose2"] = 1f, // Eye Smile
  15. ["eyeclose3"] = 1f, // Glare
  16. ["eyebig"] = 1f, // Wide Eyes
  17. ["eyeclose6"] = 1f, // Wink 1
  18. ["eyeclose5"] = 1f, // Wink 2
  19. ["hitomih"] = 2f, // Highlight
  20. ["hitomis"] = 3f, // Pupil Size
  21. ["mayuha"] = 1f, // Brow 1
  22. ["mayuw"] = 1f, // Brow 2
  23. ["mayuup"] = 1f, // Brow Up
  24. ["mayuv"] = 1f, // Brow Down 1
  25. ["mayuvhalf"] = 1f, // Brow Down 2
  26. ["moutha"] = 1f, // Mouth Open 1
  27. ["mouths"] = 1f, // Mouth Open 2
  28. ["mouthc"] = 1f, // Mouth Narrow
  29. ["mouthi"] = 1f, // Mouth Widen
  30. ["mouthup"] = 1.4f, // Smile
  31. ["mouthdw"] = 1f, // Frown
  32. ["mouthhe"] = 1f, // Mouth Pucker
  33. ["mouthuphalf"] = 2f, // Grin
  34. ["tangout"] = 1f, // Tongue Out
  35. ["tangup"] = 1f, // Tongue Up
  36. ["tangopen"] = 1f, // Tongue Base
  37. };
  38. private readonly MeidoManager meidoManager;
  39. private readonly Dictionary<string, BaseControl> faceControls;
  40. private bool hasTangOpen;
  41. public MaidFaceSliderPane(MeidoManager meidoManager)
  42. {
  43. this.meidoManager = meidoManager;
  44. faceControls = new();
  45. foreach (var key in FaceKeys)
  46. {
  47. var uiName = Translation.Get("faceBlendValues", key);
  48. var slider = new Slider(uiName, 0f, SliderLimits[key]);
  49. var sliderKey = key;
  50. slider.ControlEvent += (_, _) =>
  51. SetFaceValue(sliderKey, slider.Value);
  52. faceControls[key] = slider;
  53. }
  54. foreach (var key in FaceToggleKeys)
  55. {
  56. var uiName = Translation.Get("faceBlendValues", key);
  57. var toggle = new Toggle(uiName);
  58. var sliderKey = key;
  59. toggle.ControlEvent += (_, _) =>
  60. SetFaceValue(sliderKey, toggle.Value);
  61. faceControls[key] = toggle;
  62. }
  63. InitializeSliderLimits(faceControls);
  64. }
  65. public override void UpdatePane()
  66. {
  67. updating = true;
  68. var meido = meidoManager.ActiveMeido;
  69. for (var i = 0; i < FaceKeys.Length; i++)
  70. {
  71. var slider = (Slider)faceControls[FaceKeys[i]];
  72. try
  73. {
  74. slider.Value = meido.GetFaceBlendValue(FaceKeys[i]);
  75. }
  76. catch
  77. {
  78. // Ignored
  79. }
  80. }
  81. for (var i = 0; i < FaceToggleKeys.Length; i++)
  82. {
  83. var hash = FaceToggleKeys[i];
  84. var toggle = (Toggle)faceControls[hash];
  85. toggle.Value = meido.GetFaceBlendValue(hash) > 0f;
  86. if (hash is "toothoff")
  87. toggle.Value = !toggle.Value;
  88. }
  89. hasTangOpen = meido.Body.Face.morph.Contains("tangopen");
  90. updating = false;
  91. }
  92. public override void Draw()
  93. {
  94. GUI.enabled = meidoManager.HasActiveMeido;
  95. DrawSliders("eyeclose", "eyeclose2");
  96. DrawSliders("eyeclose3", "eyebig");
  97. DrawSliders("eyeclose6", "eyeclose5");
  98. DrawSliders("hitomih", "hitomis");
  99. DrawSliders("mayuha", "mayuw");
  100. DrawSliders("mayuup", "mayuv");
  101. DrawSliders("mayuvhalf");
  102. DrawSliders("moutha", "mouths");
  103. DrawSliders("mouthc", "mouthi");
  104. DrawSliders("mouthup", "mouthdw");
  105. DrawSliders("mouthhe", "mouthuphalf");
  106. DrawSliders("tangout", "tangup");
  107. if (hasTangOpen)
  108. DrawSliders("tangopen");
  109. MpsGui.WhiteLine();
  110. DrawToggles("hoho2", "shock", "nosefook");
  111. DrawToggles("namida", "yodare", "toothoff");
  112. DrawToggles("tear1", "tear2", "tear3");
  113. DrawToggles("hohos", "hoho", "hohol");
  114. GUI.enabled = true;
  115. }
  116. protected override void ReloadTranslation()
  117. {
  118. for (var i = 0; i < FaceKeys.Length; i++)
  119. {
  120. var slider = (Slider)faceControls[FaceKeys[i]];
  121. slider.Label = Translation.Get("faceBlendValues", FaceKeys[i]);
  122. }
  123. for (var i = 0; i < FaceToggleKeys.Length; i++)
  124. {
  125. var toggle = (Toggle)faceControls[FaceToggleKeys[i]];
  126. toggle.Label = Translation.Get("faceBlendValues", FaceToggleKeys[i]);
  127. }
  128. }
  129. private static void InitializeSliderLimits(Dictionary<string, BaseControl> controls)
  130. {
  131. try
  132. {
  133. var sliderLimitsPath = Path.Combine(Constants.DatabasePath, "face_slider_limits.json");
  134. var sliderLimitsJson = File.ReadAllText(sliderLimitsPath);
  135. foreach (var kvp in JsonConvert.DeserializeObject<Dictionary<string, float>>(sliderLimitsJson))
  136. {
  137. var key = kvp.Key;
  138. if (FaceKeys.Contains(key) && controls.ContainsKey(key))
  139. {
  140. var limit = kvp.Value;
  141. limit = kvp.Value >= 1f ? limit : SliderLimits[key];
  142. var slider = (Slider)controls[kvp.Key];
  143. slider.SetBounds(slider.Left, limit);
  144. }
  145. else
  146. {
  147. Utility.LogWarning($"'{key}' is not a valid face key");
  148. }
  149. }
  150. }
  151. catch (IOException e)
  152. {
  153. Utility.LogWarning($"Could not open face slider limit database because {e.Message}");
  154. }
  155. catch (Exception e)
  156. {
  157. Utility.LogError($"Could not apply face slider limit database because {e.Message}");
  158. }
  159. }
  160. private void DrawSliders(params string[] keys)
  161. {
  162. GUILayout.BeginHorizontal();
  163. foreach (var key in keys)
  164. faceControls[key].Draw(MpsGui.HalfSlider);
  165. GUILayout.EndHorizontal();
  166. }
  167. private void DrawToggles(params string[] keys)
  168. {
  169. GUILayout.BeginHorizontal();
  170. foreach (var key in keys)
  171. faceControls[key].Draw();
  172. GUILayout.EndHorizontal();
  173. }
  174. private void SetFaceValue(string key, float value)
  175. {
  176. if (updating)
  177. return;
  178. meidoManager.ActiveMeido.SetFaceBlendValue(key, value);
  179. }
  180. private void SetFaceValue(string key, bool value)
  181. {
  182. if (key is "toothoff")
  183. value = !value;
  184. SetFaceValue(key, value ? 1f : 0f);
  185. }
  186. }