DragPointManager.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace COM3D2.MeidoPhotoStudio.Plugin
  6. {
  7. using ModKey = Utility.ModKey;
  8. internal class DragPointManager
  9. {
  10. enum IKMode
  11. {
  12. None, UpperLock, Mune, RotLocal, BodyTransform, FingerRotLocalY, FingerRotLocalXZ, BodySelect,
  13. UpperRot
  14. }
  15. enum Bone
  16. {
  17. Head, HeadNub, ClavicleL, ClavicleR,
  18. UpperArmL, UpperArmR, ForearmL, ForearmR,
  19. HandL, HandR, IKHandL, IKHandR,
  20. MuneL, MuneSubL, MuneR, MuneSubR,
  21. Neck, Spine, Spine0a, Spine1, Spine1a, ThighL, ThighR,
  22. Pelvis, Hip,
  23. CalfL, CalfR, FootL, FootR,
  24. // Dragpoint specific
  25. Cube, Body, Torso,
  26. // Fingers
  27. Finger0L, Finger01L, Finger02L, Finger0NubL,
  28. Finger1L, Finger11L, Finger12L, Finger1NubL,
  29. Finger2L, Finger21L, Finger22L, Finger2NubL,
  30. Finger3L, Finger31L, Finger32L, Finger3NubL,
  31. Finger4L, Finger41L, Finger42L, Finger4NubL,
  32. Finger0R, Finger01R, Finger02R, Finger0NubR,
  33. Finger1R, Finger11R, Finger12R, Finger1NubR,
  34. Finger2R, Finger21R, Finger22R, Finger2NubR,
  35. Finger3R, Finger31R, Finger32R, Finger3NubR,
  36. Finger4R, Finger41R, Finger42R, Finger4NubR,
  37. // Toes
  38. Toe0L, Toe01L, Toe0NubL,
  39. Toe1L, Toe11L, Toe1NubL,
  40. Toe2L, Toe21L, Toe2NubL,
  41. Toe0R, Toe01R, Toe0NubR,
  42. Toe1R, Toe11R, Toe1NubR,
  43. Toe2R, Toe21R, Toe2NubR
  44. }
  45. private static readonly Dictionary<IKMode, Bone[]> IKGroup = new Dictionary<IKMode, Bone[]>()
  46. {
  47. [IKMode.None] = new[]
  48. {
  49. Bone.UpperArmL, Bone.ForearmL, Bone.HandL, Bone.UpperArmR,
  50. Bone.ForearmR, Bone.HandR, Bone.CalfL, Bone.FootL, Bone.CalfR, Bone.FootR
  51. },
  52. [IKMode.UpperLock] = new[] { Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR },
  53. [IKMode.Mune] = new[] { Bone.Head, Bone.MuneL, Bone.MuneR },
  54. [IKMode.RotLocal] = new[]
  55. {
  56. Bone.Head, Bone.CalfL, Bone.CalfR, Bone.Torso,
  57. Bone.Pelvis, Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR
  58. },
  59. [IKMode.BodyTransform] = new[] { Bone.Body, Bone.Cube },
  60. [IKMode.BodySelect] = new[] { Bone.Head, Bone.Body },
  61. [IKMode.FingerRotLocalXZ] = new[]
  62. {
  63. Bone.Finger01L, Bone.Finger02L, Bone.Finger0NubL,
  64. Bone.Finger11L, Bone.Finger12L, Bone.Finger1NubL,
  65. Bone.Finger21L, Bone.Finger22L, Bone.Finger2NubL,
  66. Bone.Finger31L, Bone.Finger32L, Bone.Finger3NubL,
  67. Bone.Finger41L, Bone.Finger42L, Bone.Finger4NubL,
  68. Bone.Finger01R, Bone.Finger02R, Bone.Finger0NubR,
  69. Bone.Finger11R, Bone.Finger12R, Bone.Finger1NubR,
  70. Bone.Finger21R, Bone.Finger22R, Bone.Finger2NubR,
  71. Bone.Finger31R, Bone.Finger32R, Bone.Finger3NubR,
  72. Bone.Finger41R, Bone.Finger42R, Bone.Finger4NubR,
  73. Bone.Toe01L, Bone.Toe0NubL, Bone.Toe11L, Bone.Toe1NubL,
  74. Bone.Toe21L, Bone.Toe2NubL, Bone.Toe01R, Bone.Toe0NubR,
  75. Bone.Toe11R, Bone.Toe1NubR, Bone.Toe21R, Bone.Toe2NubR
  76. },
  77. [IKMode.FingerRotLocalY] = new[] {
  78. Bone.Finger01L, Bone.Finger11L, Bone.Finger21L, Bone.Finger31L, Bone.Finger41L,
  79. Bone.Finger01R, Bone.Finger11R, Bone.Finger21R, Bone.Finger31R, Bone.Finger41R,
  80. Bone.Toe01L, Bone.Toe11L, Bone.Toe21L, Bone.Toe01R, Bone.Toe11R, Bone.Toe21R
  81. }
  82. };
  83. private static readonly Dictionary<IKMode, DragInfo[]> IKGroupBone = new Dictionary<IKMode, DragInfo[]>()
  84. {
  85. [IKMode.None] = new[] {
  86. DragInfo.DragBone(Bone.UpperArmL), DragInfo.DragBone(Bone.ForearmL), DragInfo.DragBone(Bone.HandL),
  87. DragInfo.DragBone(Bone.UpperArmR), DragInfo.DragBone(Bone.ForearmR), DragInfo.DragBone(Bone.HandR),
  88. DragInfo.DragBone(Bone.CalfL), DragInfo.DragBone(Bone.FootL), DragInfo.DragBone(Bone.CalfR),
  89. DragInfo.DragBone(Bone.FootR), DragInfo.DragBone(Bone.Neck), DragInfo.DragBone(Bone.Spine1a),
  90. DragInfo.DragBone(Bone.Spine1), DragInfo.DragBone(Bone.Spine0a), DragInfo.DragBone(Bone.Spine),
  91. DragInfo.DragBone(Bone.Hip)
  92. },
  93. [IKMode.UpperLock] = new[] {
  94. DragInfo.Gizmo(Bone.Neck), DragInfo.Gizmo(Bone.Spine1a), DragInfo.Gizmo(Bone.Spine1),
  95. DragInfo.Gizmo(Bone.Spine0a), DragInfo.Gizmo(Bone.Spine), DragInfo.DragBone(Bone.Hip),
  96. DragInfo.DragBone(Bone.HandR), DragInfo.DragBone(Bone.HandL), DragInfo.DragBone(Bone.FootL),
  97. DragInfo.DragBone(Bone.FootR)
  98. },
  99. [IKMode.RotLocal] = new[] {
  100. DragInfo.Gizmo(Bone.HandL), DragInfo.Gizmo(Bone.HandR), DragInfo.Gizmo(Bone.FootL),
  101. DragInfo.Gizmo(Bone.FootR), DragInfo.Gizmo(Bone.Hip)
  102. },
  103. [IKMode.Mune] = new[] {
  104. DragInfo.Gizmo(Bone.ForearmL), DragInfo.Gizmo(Bone.ForearmR), DragInfo.Gizmo(Bone.CalfL),
  105. DragInfo.Gizmo(Bone.CalfR), DragInfo.Drag(Bone.MuneL), DragInfo.Drag(Bone.MuneR),
  106. DragInfo.Drag(Bone.Head)
  107. },
  108. [IKMode.UpperRot] = new[] {
  109. DragInfo.Gizmo(Bone.UpperArmL), DragInfo.Gizmo(Bone.UpperArmR), DragInfo.Gizmo(Bone.ThighL),
  110. DragInfo.Gizmo(Bone.ThighR)
  111. },
  112. [IKMode.BodyTransform] = new[] { DragInfo.Drag(Bone.Body), DragInfo.DragAll(Bone.Cube) },
  113. [IKMode.BodySelect] = new[] { DragInfo.Drag(Bone.Head), DragInfo.Drag(Bone.Body) },
  114. [IKMode.FingerRotLocalXZ] = IKGroup[IKMode.FingerRotLocalXZ]
  115. .Select(bone => DragInfo.DragBone(bone)).ToArray(),
  116. [IKMode.FingerRotLocalY] = IKGroup[IKMode.FingerRotLocalY]
  117. .Select(bone => DragInfo.DragBone(bone)).ToArray()
  118. };
  119. private static bool cubeActive = false;
  120. public static bool CubeActive
  121. {
  122. get => cubeActive;
  123. set
  124. {
  125. if (value != cubeActive)
  126. {
  127. cubeActive = value;
  128. CubeActiveChange?.Invoke(null, EventArgs.Empty);
  129. }
  130. }
  131. }
  132. private static bool cubeSmall = false;
  133. public static bool CubeSmall
  134. {
  135. get => cubeSmall;
  136. set
  137. {
  138. if (value != cubeSmall)
  139. {
  140. cubeSmall = value;
  141. CubeSmallChange?.Invoke(null, EventArgs.Empty);
  142. }
  143. }
  144. }
  145. private static event EventHandler CubeActiveChange;
  146. private static event EventHandler CubeSmallChange;
  147. private Meido meido;
  148. private Maid maid;
  149. private Dictionary<Bone, BaseDrag> DragPoint;
  150. private Dictionary<Bone, Transform> BoneTransform;
  151. private IKMode ikMode;
  152. private IKMode ikModeOld = IKMode.None;
  153. public event EventHandler<MeidoUpdateEventArgs> SelectMaid;
  154. private bool active = false;
  155. public bool Active
  156. {
  157. get => active;
  158. set
  159. {
  160. if (this.active == value) return;
  161. this.active = value;
  162. this.SetActive(this.active);
  163. }
  164. }
  165. private bool isBone = false;
  166. public bool IsBone
  167. {
  168. get => isBone;
  169. set
  170. {
  171. if (this.isBone == value) return;
  172. this.isBone = value;
  173. this.SetBoneMode(this.isBone);
  174. }
  175. }
  176. public DragPointManager(Meido meido)
  177. {
  178. this.meido = meido;
  179. this.maid = meido.Maid;
  180. this.meido.BodyLoad += Initialize;
  181. }
  182. public void Destroy()
  183. {
  184. foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
  185. {
  186. GameObject.Destroy(dragPoint.Value.gameObject);
  187. }
  188. BoneTransform.Clear();
  189. DragPoint.Clear();
  190. CubeSmallChange -= OnCubeSmall;
  191. }
  192. public void Update()
  193. {
  194. if (Input.GetKey(KeyCode.Z) || Input.GetKey(KeyCode.X) || Input.GetKey(KeyCode.C))
  195. {
  196. ikMode = IKMode.BodyTransform;
  197. }
  198. else if (Input.GetKey(KeyCode.A))
  199. {
  200. ikMode = IKMode.BodySelect;
  201. }
  202. else if (Utility.GetModKey(ModKey.Control) && Utility.GetModKey(ModKey.Alt))
  203. {
  204. ikMode = IKMode.Mune;
  205. }
  206. else if (Utility.GetModKey(ModKey.Shift) && Input.GetKey(KeyCode.Space))
  207. {
  208. ikMode = IKMode.FingerRotLocalY;
  209. }
  210. else if (Utility.GetModKey(ModKey.Alt))
  211. {
  212. bool shift = IsBone && Utility.GetModKey(ModKey.Shift);
  213. ikMode = shift ? IKMode.UpperRot : IKMode.RotLocal;
  214. }
  215. else if (Input.GetKey(KeyCode.Space))
  216. {
  217. ikMode = IKMode.FingerRotLocalXZ;
  218. }
  219. else if (Utility.GetModKey(ModKey.Control))
  220. {
  221. ikMode = IKMode.UpperLock;
  222. }
  223. else
  224. {
  225. ikMode = IKMode.None;
  226. }
  227. if (ikMode != ikModeOld) UpdateIK();
  228. ikModeOld = ikMode;
  229. }
  230. private void Initialize(object sender, EventArgs args)
  231. {
  232. meido.BodyLoad -= Initialize;
  233. InitializeBones();
  234. InitializeDragPoints();
  235. this.Active = true;
  236. this.SetBoneMode(false);
  237. CubeSmallChange += OnCubeSmall;
  238. }
  239. private void SetBoneMode(bool active)
  240. {
  241. foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
  242. {
  243. dragPoint.Value.IsBone = this.IsBone;
  244. if (!this.IsBone)
  245. {
  246. dragPoint.Value.SetDragProp(false, true, dragPoint.Key >= Bone.Finger0L);
  247. }
  248. }
  249. UpdateIK();
  250. }
  251. private void SetActive(bool active)
  252. {
  253. if (active)
  254. {
  255. ikMode = ikModeOld = IKMode.None;
  256. ((DragHead)DragPoint[Bone.Head]).IsIK = true;
  257. UpdateIK();
  258. }
  259. else
  260. {
  261. foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
  262. {
  263. dragPoint.Value.gameObject.SetActive(false);
  264. }
  265. ((DragHead)DragPoint[Bone.Head]).IsIK = false;
  266. DragPoint[Bone.Head].SetDragProp(false, true, false);
  267. DragPoint[Bone.Body].SetDragProp(false, true, false);
  268. DragPoint[Bone.Cube].SetDragProp(false, true, true);
  269. }
  270. }
  271. private void UpdateIK()
  272. {
  273. if (this.Active)
  274. {
  275. if (this.IsBone) UpdateBoneIK();
  276. else
  277. {
  278. foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
  279. {
  280. dragPoint.Value.gameObject.SetActive(false);
  281. }
  282. foreach (Bone bone in IKGroup[ikMode])
  283. {
  284. DragPoint[bone].gameObject.SetActive(true);
  285. }
  286. }
  287. bool cubeVisible = CubeActive && (ikMode == IKMode.BodyTransform);
  288. DragPoint[Bone.Cube].SetDragProp(cubeVisible, cubeVisible, cubeVisible);
  289. DragPoint[Bone.Cube].gameObject.SetActive(cubeVisible);
  290. }
  291. else
  292. {
  293. if (ikMode == IKMode.BodySelect)
  294. {
  295. DragPoint[Bone.Body].gameObject.SetActive(true);
  296. DragPoint[Bone.Head].gameObject.SetActive(true);
  297. }
  298. else if (ikMode == IKMode.BodyTransform)
  299. {
  300. DragPoint[Bone.Body].gameObject.SetActive(true);
  301. DragPoint[Bone.Cube].gameObject.SetActive(CubeActive);
  302. }
  303. else if (ikMode == IKMode.UpperRot || ikMode == IKMode.RotLocal)
  304. {
  305. DragPoint[Bone.Head].gameObject.SetActive(true);
  306. }
  307. else
  308. {
  309. DragPoint[Bone.Body].gameObject.SetActive(false);
  310. DragPoint[Bone.Head].gameObject.SetActive(false);
  311. DragPoint[Bone.Cube].gameObject.SetActive(false);
  312. }
  313. }
  314. }
  315. private void UpdateBoneIK()
  316. {
  317. foreach (KeyValuePair<Bone, BaseDrag> dragPoint in DragPoint)
  318. {
  319. dragPoint.Value.gameObject.SetActive(false);
  320. dragPoint.Value.SetDragProp(false, false, dragPoint.Key >= Bone.Finger0L);
  321. }
  322. foreach (DragInfo info in IKGroupBone[ikMode])
  323. {
  324. BaseDrag drag = DragPoint[info.Bone];
  325. drag.gameObject.SetActive(true);
  326. drag.SetDragProp(info.GizmoActive, info.DragPointActive, info.DragPointVisible);
  327. }
  328. }
  329. private void OnCubeSmall(object sender, EventArgs args)
  330. {
  331. DragBody dragPoint = (DragBody)DragPoint[Bone.Cube];
  332. dragPoint.DragPointScale = dragPoint.BaseScale * (CubeSmall ? 0.4f : 1f);
  333. }
  334. private void OnSelectFace(object sender, EventArgs args)
  335. {
  336. OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, false));
  337. }
  338. private void OnSelectBody(object sender, EventArgs args)
  339. {
  340. OnMeidoSelect(new MeidoUpdateEventArgs(meido.ActiveSlot, true, true));
  341. }
  342. private void OnSetDragPointScale(object sender, EventArgs args)
  343. {
  344. this.SetDragPointScale(maid.transform.localScale.x);
  345. }
  346. private void OnMeidoSelect(MeidoUpdateEventArgs args)
  347. {
  348. SelectMaid?.Invoke(this, args);
  349. }
  350. private void SetDragPointScale(float scale)
  351. {
  352. foreach (KeyValuePair<Bone, BaseDrag> kvp in DragPoint)
  353. {
  354. if (kvp.Key == Bone.Cube) continue;
  355. BaseDrag dragPoint = kvp.Value;
  356. dragPoint.DragPointScale = dragPoint.BaseScale * scale;
  357. }
  358. }
  359. // TODO: Rework this a little to reduce number of needed BaseDrag derived components
  360. private void InitializeDragPoints()
  361. {
  362. DragPoint = new Dictionary<Bone, BaseDrag>();
  363. Vector3 limbDragPointSize = Vector3.one * 0.12f;
  364. Vector3 limbDragPointSizeBone = Vector3.one * 0.07f;
  365. Vector3 fingerDragPointSize = Vector3.one * 0.015f;
  366. Func<Transform[], Transform[], Transform[], bool, BaseDrag[]> MakeIKChainDragPoint =
  367. (upper, middle, lower, leg) =>
  368. {
  369. GameObject[] dragPoints = new GameObject[3];
  370. for (int i = 0; i < dragPoints.Length; i++)
  371. {
  372. dragPoints[i] =
  373. BaseDrag.MakeDragPoint(PrimitiveType.Sphere, limbDragPointSize, BaseDrag.LightBlue);
  374. }
  375. return new BaseDrag[3] {
  376. dragPoints[0].AddComponent<DragJointForearm>()
  377. .Initialize(upper, false, meido, () => upper[2].position, () => Vector3.zero),
  378. dragPoints[1].AddComponent<DragJointForearm>()
  379. .Initialize(middle, leg, meido, () => middle[2].position, () => Vector3.zero),
  380. dragPoints[2].AddComponent<DragJointHand>()
  381. .Initialize(lower, leg, meido, () => lower[2].position, () => Vector3.zero)
  382. };
  383. };
  384. // TODO: Modify dragpoint sizes for each joint
  385. Action<Bone, Bone, int> MakeFingerDragPoint = (start, end, joints) =>
  386. {
  387. for (Bone it = start; it <= end; it += joints)
  388. {
  389. for (int i = 0; i < joints - 1; i++)
  390. {
  391. Bone bone = it + 1 + i;
  392. DragPoint[bone] = BaseDrag.MakeDragPoint(PrimitiveType.Sphere, fingerDragPointSize, BaseDrag.Blue)
  393. .AddComponent<DragJointFinger>()
  394. .Initialize(new Transform[3] {
  395. BoneTransform[bone - 1],
  396. BoneTransform[bone - 1],
  397. BoneTransform[bone]
  398. }, i == 0, meido, () => BoneTransform[bone].position, () => Vector3.zero
  399. );
  400. DragPoint[bone].gameObject.layer = 0;
  401. DragPoint[bone].DragPointVisible = true;
  402. }
  403. }
  404. };
  405. // Cube Dragpoint
  406. DragPoint[Bone.Cube] =
  407. BaseDrag.MakeDragPoint(PrimitiveType.Cube, Vector3.one * 0.12f, BaseDrag.Blue)
  408. .AddComponent<DragBody>()
  409. .Initialize(meido,
  410. () => maid.transform.position,
  411. () => maid.transform.eulerAngles
  412. );
  413. DragBody dragCube = (DragBody)DragPoint[Bone.Cube];
  414. dragCube.Scale += OnSetDragPointScale;
  415. dragCube.DragPointVisible = true;
  416. // TODO: Make gizmos work on cube
  417. // Body Dragpoint
  418. DragPoint[Bone.Body] =
  419. BaseDrag.MakeDragPoint(PrimitiveType.Capsule, new Vector3(0.2f, 0.3f, 0.24f), BaseDrag.LightBlue)
  420. .AddComponent<DragBody>()
  421. .Initialize(meido,
  422. () => new Vector3(
  423. (BoneTransform[Bone.Hip].position.x + BoneTransform[Bone.Spine0a].position.x) / 2f,
  424. (BoneTransform[Bone.Spine1].position.y + BoneTransform[Bone.Spine0a].position.y) / 2f,
  425. (BoneTransform[Bone.Spine0a].position.z + BoneTransform[Bone.Hip].position.z) / 2f
  426. ),
  427. () => new Vector3(
  428. BoneTransform[Bone.Spine0a].transform.eulerAngles.x,
  429. BoneTransform[Bone.Spine0a].transform.eulerAngles.y,
  430. BoneTransform[Bone.Spine0a].transform.eulerAngles.z + 90f
  431. )
  432. );
  433. DragBody dragBody = (DragBody)DragPoint[Bone.Body];
  434. dragBody.Select += OnSelectBody;
  435. dragBody.Scale += OnSetDragPointScale;
  436. // Head Dragpoint
  437. DragPoint[Bone.Head] =
  438. BaseDrag.MakeDragPoint(PrimitiveType.Sphere, new Vector3(0.2f, 0.24f, 0.2f), BaseDrag.LightBlue)
  439. .AddComponent<DragHead>()
  440. .Initialize(BoneTransform[Bone.Neck], meido,
  441. () => new Vector3(
  442. BoneTransform[Bone.Head].position.x,
  443. (BoneTransform[Bone.Head].position.y * 1.2f + BoneTransform[Bone.HeadNub].position.y * 0.8f) / 2f,
  444. BoneTransform[Bone.Head].position.z
  445. ),
  446. () => new Vector3(
  447. BoneTransform[Bone.Head].eulerAngles.x,
  448. BoneTransform[Bone.Head].eulerAngles.y,
  449. BoneTransform[Bone.Head].eulerAngles.z + 90f
  450. )
  451. );
  452. DragHead dragHead = (DragHead)DragPoint[Bone.Head];
  453. dragHead.Select += OnSelectFace;
  454. // Torso Dragpoint
  455. DragPoint[Bone.Torso] =
  456. BaseDrag.MakeDragPoint(PrimitiveType.Capsule, new Vector3(0.2f, 0.19f, 0.24f), BaseDrag.LightBlue)
  457. .AddComponent<DragTorso>();
  458. Transform spineTrans1 = BoneTransform[Bone.Spine1];
  459. Transform spineTrans2 = BoneTransform[Bone.Spine1a];
  460. Transform[] spineParts = new Transform[4] {
  461. BoneTransform[Bone.Spine1a],
  462. BoneTransform[Bone.Spine1],
  463. BoneTransform[Bone.Spine0a],
  464. BoneTransform[Bone.Spine]
  465. };
  466. DragTorso dragTorso = (DragTorso)DragPoint[Bone.Torso];
  467. dragTorso.Initialize(spineParts, meido,
  468. () => new Vector3(
  469. spineTrans1.position.x,
  470. (spineTrans2.position.y * 2f) / 2f,
  471. spineTrans1.position.z
  472. ),
  473. () => new Vector3(
  474. spineTrans1.eulerAngles.x,
  475. spineTrans1.eulerAngles.y,
  476. spineTrans1.eulerAngles.z + 90f
  477. )
  478. );
  479. // Pelvis Dragpoint
  480. DragPoint[Bone.Pelvis] =
  481. BaseDrag.MakeDragPoint(PrimitiveType.Capsule, new Vector3(0.2f, 0.15f, 0.24f), BaseDrag.LightBlue)
  482. .AddComponent<DragPelvis>();
  483. Transform pelvisTrans = BoneTransform[Bone.Pelvis];
  484. Transform spineTrans = BoneTransform[Bone.Spine];
  485. DragPelvis dragPelvis = (DragPelvis)DragPoint[Bone.Pelvis];
  486. dragPelvis.Initialize(BoneTransform[Bone.Pelvis], meido,
  487. () => new Vector3(
  488. pelvisTrans.position.x,
  489. (pelvisTrans.position.y + spineTrans.position.y) / 2f,
  490. pelvisTrans.position.z
  491. ),
  492. () => new Vector3(
  493. pelvisTrans.eulerAngles.x + 90f,
  494. pelvisTrans.eulerAngles.y + 90f,
  495. pelvisTrans.eulerAngles.z
  496. )
  497. );
  498. // Left Mune Dragpoint
  499. DragPoint[Bone.MuneL] =
  500. BaseDrag.MakeDragPoint(PrimitiveType.Sphere, Vector3.one * 0.12f, BaseDrag.LightBlue)
  501. .AddComponent<DragMune>();
  502. Transform[] muneIKChainL = new Transform[3] {
  503. BoneTransform[Bone.MuneL],
  504. BoneTransform[Bone.MuneL],
  505. BoneTransform[Bone.MuneSubL]
  506. };
  507. DragMune dragMuneL = (DragMune)DragPoint[Bone.MuneL];
  508. dragMuneL.Initialize(muneIKChainL, meido,
  509. () => (BoneTransform[Bone.MuneL].position + BoneTransform[Bone.MuneSubL].position) / 2f,
  510. () => Vector3.zero
  511. );
  512. // Right Mune Dragpoint
  513. DragPoint[Bone.MuneR] =
  514. BaseDrag.MakeDragPoint(PrimitiveType.Sphere, Vector3.one * 0.12f, BaseDrag.LightBlue)
  515. .AddComponent<DragMune>();
  516. Transform[] muneIKChainR = new Transform[3] {
  517. BoneTransform[Bone.MuneR],
  518. BoneTransform[Bone.MuneR],
  519. BoneTransform[Bone.MuneSubR]
  520. };
  521. DragMune dragMuneR = (DragMune)DragPoint[Bone.MuneR];
  522. dragMuneR.Initialize(muneIKChainR, meido,
  523. () => (BoneTransform[Bone.MuneR].position + BoneTransform[Bone.MuneSubR].position) / 2f,
  524. () => Vector3.zero
  525. );
  526. // Left Arm Dragpoint
  527. BaseDrag[] ikChainArmL = MakeIKChainDragPoint(
  528. new Transform[3] {
  529. BoneTransform[Bone.ClavicleL],
  530. BoneTransform[Bone.ClavicleL],
  531. BoneTransform[Bone.UpperArmL]
  532. },
  533. new Transform[3] {
  534. BoneTransform[Bone.UpperArmL],
  535. BoneTransform[Bone.UpperArmL],
  536. BoneTransform[Bone.ForearmL]
  537. },
  538. new Transform[3] {
  539. BoneTransform[Bone.UpperArmL],
  540. BoneTransform[Bone.ForearmL],
  541. BoneTransform[Bone.HandL]
  542. },
  543. false
  544. );
  545. DragPoint[Bone.UpperArmL] = ikChainArmL[0];
  546. DragPoint[Bone.ForearmL] = ikChainArmL[1];
  547. DragPoint[Bone.HandL] = ikChainArmL[2];
  548. // Right Arm Dragpoint
  549. BaseDrag[] ikChainArmR = MakeIKChainDragPoint(
  550. new Transform[3] {
  551. BoneTransform[Bone.ClavicleR],
  552. BoneTransform[Bone.ClavicleR],
  553. BoneTransform[Bone.UpperArmR]
  554. },
  555. new Transform[3] {
  556. BoneTransform[Bone.UpperArmR],
  557. BoneTransform[Bone.UpperArmR],
  558. BoneTransform[Bone.ForearmR]
  559. },
  560. new Transform[3] {
  561. BoneTransform[Bone.UpperArmR],
  562. BoneTransform[Bone.ForearmR],
  563. BoneTransform[Bone.HandR]
  564. },
  565. false
  566. );
  567. DragPoint[Bone.UpperArmR] = ikChainArmR[0];
  568. DragPoint[Bone.ForearmR] = ikChainArmR[1];
  569. DragPoint[Bone.HandR] = ikChainArmR[2];
  570. // Left Leg Dragpoint
  571. BaseDrag[] ikChainLegL = MakeIKChainDragPoint(
  572. new Transform[3] {
  573. BoneTransform[Bone.ThighL],
  574. BoneTransform[Bone.CalfL],
  575. BoneTransform[Bone.FootL]
  576. },
  577. new Transform[3] {
  578. BoneTransform[Bone.ThighL],
  579. BoneTransform[Bone.ThighL],
  580. BoneTransform[Bone.CalfL]
  581. },
  582. new Transform[3] {
  583. BoneTransform[Bone.ThighL],
  584. BoneTransform[Bone.CalfL],
  585. BoneTransform[Bone.FootL]
  586. },
  587. true
  588. );
  589. DragPoint[Bone.CalfL] = ikChainLegL[1];
  590. DragPoint[Bone.FootL] = ikChainLegL[2];
  591. // Right Arm Dragpoint
  592. BaseDrag[] ikChainLegR = MakeIKChainDragPoint(
  593. new Transform[3] {
  594. BoneTransform[Bone.ThighR],
  595. BoneTransform[Bone.CalfR],
  596. BoneTransform[Bone.FootR]
  597. },
  598. new Transform[3] {
  599. BoneTransform[Bone.ThighR],
  600. BoneTransform[Bone.ThighR],
  601. BoneTransform[Bone.CalfR]
  602. },
  603. new Transform[3] {
  604. BoneTransform[Bone.ThighR],
  605. BoneTransform[Bone.CalfR],
  606. BoneTransform[Bone.FootR]
  607. },
  608. true
  609. );
  610. DragPoint[Bone.CalfR] = ikChainLegR[1];
  611. DragPoint[Bone.FootR] = ikChainLegR[2];
  612. // destroy unused thigh dragpoints
  613. GameObject.Destroy(ikChainLegL[0].gameObject);
  614. GameObject.Destroy(ikChainLegR[0].gameObject);
  615. // Spine Dragpoints
  616. for (Bone bone = Bone.Neck; bone <= Bone.ThighR; ++bone)
  617. {
  618. Transform pos = BoneTransform[bone];
  619. DragPoint[bone] = BaseDrag.MakeDragPoint(PrimitiveType.Sphere, Vector3.one * 0.04f, BaseDrag.LightBlue)
  620. .AddComponent<DragSpine>()
  621. .Initialize(BoneTransform[bone], false, meido,
  622. () => pos.position,
  623. () => Vector3.zero
  624. );
  625. }
  626. // Hip DragPoint
  627. DragPoint[Bone.Hip] = BaseDrag.MakeDragPoint(PrimitiveType.Cube, Vector3.one * 0.045f, BaseDrag.LightBlue)
  628. .AddComponent<DragSpine>()
  629. .Initialize(BoneTransform[Bone.Hip], true, meido,
  630. () => BoneTransform[Bone.Hip].position,
  631. () => Vector3.zero
  632. );
  633. MakeFingerDragPoint(Bone.Finger0L, Bone.Finger4R, 4);
  634. MakeFingerDragPoint(Bone.Toe0L, Bone.Toe2R, 3);
  635. }
  636. private void InitializeBones()
  637. {
  638. BoneTransform = new Dictionary<Bone, Transform>()
  639. {
  640. [Bone.Head] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Head", true),
  641. [Bone.Neck] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Neck", true),
  642. [Bone.HeadNub] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 HeadNub", true),
  643. [Bone.IKHandL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "_IK_handL", true),
  644. [Bone.IKHandR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "_IK_handR", true),
  645. [Bone.MuneL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_L", true),
  646. [Bone.MuneSubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_L_sub", true),
  647. [Bone.MuneR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_R", true),
  648. [Bone.MuneSubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Mune_R_sub", true),
  649. [Bone.Pelvis] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Pelvis", true),
  650. [Bone.Hip] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01", true),
  651. [Bone.Spine] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine", true),
  652. [Bone.Spine0a] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine0a", true),
  653. [Bone.Spine1] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine1", true),
  654. [Bone.Spine1a] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 Spine1a", true),
  655. [Bone.ClavicleL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Clavicle", true),
  656. [Bone.ClavicleR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Clavicle", true),
  657. [Bone.UpperArmL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L UpperArm", true),
  658. [Bone.ForearmL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Forearm", true),
  659. [Bone.HandL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Hand", true),
  660. [Bone.UpperArmR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R UpperArm", true),
  661. [Bone.ForearmR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Forearm", true),
  662. [Bone.HandR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Hand", true),
  663. [Bone.ThighL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Thigh", true),
  664. [Bone.CalfL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Calf", true),
  665. [Bone.FootL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Foot", true),
  666. [Bone.ThighR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Thigh", true),
  667. [Bone.CalfR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Calf", true),
  668. [Bone.FootR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Foot", true),
  669. // fingers
  670. [Bone.Finger0L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger0", true),
  671. [Bone.Finger01L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger01", true),
  672. [Bone.Finger02L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger02", true),
  673. [Bone.Finger0NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger0Nub", true),
  674. [Bone.Finger1L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger1", true),
  675. [Bone.Finger11L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger11", true),
  676. [Bone.Finger12L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger12", true),
  677. [Bone.Finger1NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger1Nub", true),
  678. [Bone.Finger2L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger2", true),
  679. [Bone.Finger21L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger21", true),
  680. [Bone.Finger22L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger22", true),
  681. [Bone.Finger2NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger2Nub", true),
  682. [Bone.Finger3L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger3", true),
  683. [Bone.Finger31L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger31", true),
  684. [Bone.Finger32L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger32", true),
  685. [Bone.Finger3NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger3Nub", true),
  686. [Bone.Finger4L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger4", true),
  687. [Bone.Finger41L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger41", true),
  688. [Bone.Finger42L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger42", true),
  689. [Bone.Finger4NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Finger4Nub", true),
  690. [Bone.Finger0R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger0", true),
  691. [Bone.Finger01R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger01", true),
  692. [Bone.Finger02R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger02", true),
  693. [Bone.Finger0NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger0Nub", true),
  694. [Bone.Finger1R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger1", true),
  695. [Bone.Finger11R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger11", true),
  696. [Bone.Finger12R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger12", true),
  697. [Bone.Finger1NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger1Nub", true),
  698. [Bone.Finger2R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger2", true),
  699. [Bone.Finger21R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger21", true),
  700. [Bone.Finger22R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger22", true),
  701. [Bone.Finger2NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger2Nub", true),
  702. [Bone.Finger3R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger3", true),
  703. [Bone.Finger31R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger31", true),
  704. [Bone.Finger32R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger32", true),
  705. [Bone.Finger3NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger3Nub", true),
  706. [Bone.Finger4R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger4", true),
  707. [Bone.Finger41R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger41", true),
  708. [Bone.Finger42R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger42", true),
  709. [Bone.Finger4NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Finger4Nub", true),
  710. // Toes
  711. [Bone.Toe0L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe0", true),
  712. [Bone.Toe01L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe01", true),
  713. [Bone.Toe0NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe0Nub", true),
  714. [Bone.Toe1L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe1", true),
  715. [Bone.Toe11L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe11", true),
  716. [Bone.Toe1NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe1Nub", true),
  717. [Bone.Toe2L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe2", true),
  718. [Bone.Toe21L] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe21", true),
  719. [Bone.Toe2NubL] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 L Toe2Nub", true),
  720. [Bone.Toe0R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe0", true),
  721. [Bone.Toe01R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe01", true),
  722. [Bone.Toe0NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe0Nub", true),
  723. [Bone.Toe1R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe1", true),
  724. [Bone.Toe11R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe11", true),
  725. [Bone.Toe1NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe1Nub", true),
  726. [Bone.Toe2R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe2", true),
  727. [Bone.Toe21R] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe21", true),
  728. [Bone.Toe2NubR] = CMT.SearchObjName(maid.body0.m_Bones.transform, "Bip01 R Toe2Nub", true)
  729. };
  730. }
  731. private struct DragInfo
  732. {
  733. public Bone Bone { get; }
  734. public bool GizmoActive { get; }
  735. public bool DragPointActive { get; }
  736. public bool DragPointVisible { get; }
  737. public DragInfo(Bone bone, bool gizmoActive, bool dragPointActive, bool dragPointVisible)
  738. {
  739. this.Bone = bone;
  740. this.GizmoActive = gizmoActive;
  741. this.DragPointActive = dragPointActive;
  742. this.DragPointVisible = dragPointVisible;
  743. }
  744. public static DragInfo Gizmo(Bone bone)
  745. {
  746. return new DragInfo(bone, true, false, false);
  747. }
  748. public static DragInfo Drag(Bone bone)
  749. {
  750. return new DragInfo(bone, false, true, false);
  751. }
  752. public static DragInfo DragBone(Bone bone)
  753. {
  754. return new DragInfo(bone, false, true, true);
  755. }
  756. public static DragInfo DragAll(Bone bone)
  757. {
  758. return new DragInfo(bone, true, true, true);
  759. }
  760. }
  761. }
  762. }