DragJointHand.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. using System;
  2. using UnityEngine;
  3. namespace COM3D2.MeidoPhotoStudio.Plugin
  4. {
  5. internal class DragJointHand : BaseDrag
  6. {
  7. private readonly TBody.IKCMO IK = new TBody.IKCMO();
  8. private readonly GameObject[] otherIK = new GameObject[3];
  9. private Transform[] ikChain;
  10. private Transform[] ikChainLock;
  11. private Vector3[] jointRotation = new Vector3[2];
  12. private Vector3 off;
  13. private Vector3 off2;
  14. private int foot = 1;
  15. public DragJointHand Initialize(
  16. Transform[] ikChain, bool foot,
  17. Meido meido, Func<Vector3> position, Func<Vector3> rotation
  18. )
  19. {
  20. base.Initialize(meido, position, rotation);
  21. this.ikChain = ikChain;
  22. this.foot = foot ? -1 : 1;
  23. this.ikChainLock = new Transform[3] {
  24. ikChain[foreArm],
  25. ikChain[foreArm],
  26. ikChain[hand]
  27. };
  28. InitializeIK();
  29. InitializeIK2();
  30. InitializeGizmo(this.ikChain[hand]);
  31. return this;
  32. }
  33. public void InitializeIK()
  34. {
  35. IK.Init(ikChain[upperArm], ikChain[foreArm], ikChain[hand], maid.body0);
  36. }
  37. private void InitializeIK2()
  38. {
  39. for (int i = 0; i < otherIK.Length; i++)
  40. {
  41. otherIK[i] = new GameObject();
  42. otherIK[i].transform.position = this.ikChain[i].position;
  43. otherIK[i].transform.localRotation = this.ikChain[i].localRotation;
  44. }
  45. }
  46. protected override void GetDragType()
  47. {
  48. if (Utility.GetModKey(Utility.ModKey.Shift) && Utility.GetModKey(Utility.ModKey.Alt))
  49. {
  50. CurrentDragType = DragType.RotLocalY;
  51. }
  52. else if (Utility.GetModKey(Utility.ModKey.Alt))
  53. {
  54. CurrentDragType = DragType.RotLocalXZ;
  55. }
  56. else if (Utility.GetModKey(Utility.ModKey.Control))
  57. {
  58. CurrentDragType = DragType.MoveXZ;
  59. }
  60. else
  61. {
  62. CurrentDragType = DragType.None;
  63. }
  64. }
  65. protected override void InitializeDrag()
  66. {
  67. base.InitializeDrag();
  68. Transform[] ikChain = CurrentDragType == DragType.MoveXZ ? this.ikChainLock : this.ikChain;
  69. IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
  70. off = transform.position - Camera.main.ScreenToWorldPoint(
  71. new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
  72. );
  73. off2 = new Vector3(
  74. transform.position.x - ikChain[hand].position.x,
  75. transform.position.y - ikChain[hand].position.y,
  76. transform.position.z - ikChain[hand].position.z);
  77. jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
  78. jointRotation[handRot] = ikChain[hand].localEulerAngles;
  79. InitializeIK();
  80. }
  81. protected override void Drag()
  82. {
  83. if (isPlaying) meido.IsStop = true;
  84. IKCtrlData ikData = maid.body0.IKCtrl.GetIKData("左手");
  85. Vector3 pos = Camera.main.ScreenToWorldPoint(
  86. new Vector3(Input.mousePosition.x, Input.mousePosition.y, worldPoint.z)
  87. ) + off - off2;
  88. if (CurrentDragType == DragType.None || CurrentDragType == DragType.MoveXZ)
  89. {
  90. Transform[] ikChain = CurrentDragType == DragType.MoveXZ ? this.ikChainLock : this.ikChain;
  91. IK.Porc(ikChain[upperArm], ikChain[foreArm], ikChain[hand], pos, Vector3.zero, ikData);
  92. jointRotation[handRot] = ikChain[hand].localEulerAngles;
  93. jointRotation[upperArmRot] = ikChain[upperArm].localEulerAngles;
  94. ikChain[upperArm].localEulerAngles = jointRotation[upperArm];
  95. ikChain[hand].localEulerAngles = jointRotation[handRot];
  96. }
  97. else
  98. {
  99. Vector3 vec31 = Input.mousePosition - mousePos;
  100. if (CurrentDragType == DragType.RotLocalY)
  101. {
  102. ikChain[hand].localEulerAngles = jointRotation[handRot];
  103. ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
  104. * Quaternion.AngleAxis(vec31.x / 1.5f, Vector3.right);
  105. }
  106. if (CurrentDragType == DragType.RotLocalXZ)
  107. {
  108. ikChain[hand].localEulerAngles = jointRotation[handRot];
  109. ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
  110. * Quaternion.AngleAxis(foot * vec31.x / 1.5f, Vector3.up);
  111. ikChain[hand].localRotation = Quaternion.Euler(ikChain[hand].localEulerAngles)
  112. * Quaternion.AngleAxis(foot * vec31.y / 1.5f, Vector3.forward);
  113. }
  114. }
  115. }
  116. }
  117. }