MeidoDragPointManager.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. using System;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. namespace COM3D2.MeidoPhotoStudio.Plugin
  6. {
  7. internal enum AttachPoint
  8. {
  9. None, Head, Neck, UpperArmL, UpperArmR, ForearmL, ForearmR, MuneL, MuneR, HandL, HandR,
  10. Pelvis, ThighL, ThighR, CalfL, CalfR, FootL, FootR
  11. }
  12. internal class MeidoDragPointManager
  13. {
  14. private enum Bone
  15. {
  16. Head, HeadNub, ClavicleL, ClavicleR,
  17. UpperArmL, UpperArmR, ForearmL, ForearmR,
  18. HandL, HandR, IKHandL, IKHandR,
  19. MuneL, MuneSubL, MuneR, MuneSubR,
  20. Neck, Spine, Spine0a, Spine1, Spine1a, ThighL, ThighR,
  21. Pelvis, Hip,
  22. CalfL, CalfR, FootL, FootR,
  23. // Dragpoint specific
  24. Cube, Body, Torso,
  25. // Fingers
  26. Finger0L, Finger01L, Finger02L, Finger0NubL,
  27. Finger1L, Finger11L, Finger12L, Finger1NubL,
  28. Finger2L, Finger21L, Finger22L, Finger2NubL,
  29. Finger3L, Finger31L, Finger32L, Finger3NubL,
  30. Finger4L, Finger41L, Finger42L, Finger4NubL,
  31. Finger0R, Finger01R, Finger02R, Finger0NubR,
  32. Finger1R, Finger11R, Finger12R, Finger1NubR,
  33. Finger2R, Finger21R, Finger22R, Finger2NubR,
  34. Finger3R, Finger31R, Finger32R, Finger3NubR,
  35. Finger4R, Finger41R, Finger42R, Finger4NubR,
  36. // Toes
  37. Toe0L, Toe01L, Toe0NubL,
  38. Toe1L, Toe11L, Toe1NubL,
  39. Toe2L, Toe21L, Toe2NubL,
  40. Toe0R, Toe01R, Toe0NubR,
  41. Toe1R, Toe11R, Toe1NubR,
  42. Toe2R, Toe21R, Toe2NubR
  43. }
  44. private static readonly Dictionary<AttachPoint, Bone> PointToBone = new Dictionary<AttachPoint, Bone>()
  45. {
  46. [AttachPoint.Head] = Bone.Head,
  47. [AttachPoint.Neck] = Bone.HeadNub,
  48. [AttachPoint.UpperArmL] = Bone.UpperArmL,
  49. [AttachPoint.UpperArmR] = Bone.UpperArmR,
  50. [AttachPoint.ForearmL] = Bone.ForearmL,
  51. [AttachPoint.ForearmR] = Bone.ForearmR,
  52. [AttachPoint.MuneL] = Bone.MuneL,
  53. [AttachPoint.MuneR] = Bone.MuneR,
  54. [AttachPoint.HandL] = Bone.HandL,
  55. [AttachPoint.HandR] = Bone.HandR,
  56. [AttachPoint.Pelvis] = Bone.Pelvis,
  57. [AttachPoint.ThighL] = Bone.ThighL,
  58. [AttachPoint.ThighR] = Bone.ThighR,
  59. [AttachPoint.CalfL] = Bone.CalfL,
  60. [AttachPoint.CalfR] = Bone.CalfR,
  61. [AttachPoint.FootL] = Bone.FootL,
  62. [AttachPoint.FootR] = Bone.FootR,
  63. };
  64. private static bool cubeActive;
  65. public static bool CubeActive
  66. {
  67. get => cubeActive;
  68. set
  69. {
  70. if (value != cubeActive)
  71. {
  72. cubeActive = value;
  73. CubeActiveChange?.Invoke(null, EventArgs.Empty);
  74. }
  75. }
  76. }
  77. private static bool cubeSmall = false;
  78. public static bool CubeSmall
  79. {
  80. get => cubeSmall;
  81. set
  82. {
  83. if (value != cubeSmall)
  84. {
  85. cubeSmall = value;
  86. CubeSmallChange?.Invoke(null, EventArgs.Empty);
  87. }
  88. }
  89. }
  90. private static EventHandler CubeActiveChange;
  91. private static EventHandler CubeSmallChange;
  92. private Meido meido;
  93. private Maid maid;
  94. private Dictionary<Bone, Transform> BoneTransform;
  95. private Dictionary<Bone, DragPointMeido> DragPoints;
  96. private DragPointBody dragBody;
  97. private DragPointBody dragCube;
  98. public event EventHandler<MeidoUpdateEventArgs> SelectMaid;
  99. private bool isBone = false;
  100. public bool IsBone
  101. {
  102. get => isBone;
  103. set
  104. {
  105. if (isBone != value)
  106. {
  107. isBone = value;
  108. foreach (DragPointMeido dragPoint in DragPoints.Values)
  109. {
  110. dragPoint.IsBone = isBone;
  111. }
  112. }
  113. }
  114. }
  115. private bool active = true;
  116. public bool Active
  117. {
  118. get => active;
  119. set
  120. {
  121. if (active != value)
  122. {
  123. active = value;
  124. foreach (DragPointMeido dragPoint in DragPoints.Values)
  125. {
  126. dragPoint.gameObject.SetActive(active);
  127. }
  128. DragPointHead head = (DragPointHead)DragPoints[Bone.Head];
  129. head.gameObject.SetActive(true);
  130. head.IsIK = !active;
  131. }
  132. }
  133. }
  134. public MeidoDragPointManager(Meido meido)
  135. {
  136. this.meido = meido;
  137. this.maid = meido.Maid;
  138. this.meido.BodyLoad += Initialize;
  139. }
  140. public Transform GetAttachPointTransform(AttachPoint point)
  141. {
  142. if (point == AttachPoint.None) return null;
  143. return BoneTransform[PointToBone[point]];
  144. }
  145. public void Destroy()
  146. {
  147. foreach (DragPointMeido dragPoint in DragPoints.Values)
  148. {
  149. GameObject.Destroy(dragPoint.gameObject);
  150. }
  151. GameObject.Destroy(dragCube.gameObject);
  152. GameObject.Destroy(dragBody.gameObject);
  153. BoneTransform.Clear();
  154. DragPoints.Clear();
  155. CubeActiveChange -= OnCubeActive;
  156. CubeSmallChange -= OnCubeSmall;
  157. }
  158. private void Initialize(object sender, EventArgs args)
  159. {
  160. meido.BodyLoad -= Initialize;
  161. CubeActiveChange += OnCubeActive;
  162. CubeSmallChange += OnCubeSmall;
  163. InitializeBones();
  164. InitializeDragPoints();
  165. }
  166. private void InitializeDragPoints()
  167. {
  168. DragPoints = new Dictionary<Bone, DragPointMeido>();
  169. dragCube = DragPoint.Make<DragPointBody>(
  170. PrimitiveType.Cube, Vector3.one * 0.12f, DragPoint.Blue
  171. );
  172. dragCube.Initialize(() => maid.transform.position, () => Vector3.zero);
  173. dragCube.Set(maid.transform);
  174. dragCube.IsCube = true;
  175. dragCube.ConstantScale = true;
  176. dragCube.Select += OnSelectBody;
  177. dragCube.EndScale += OnSetDragPointScale;
  178. dragCube.gameObject.SetActive(CubeActive);
  179. dragBody = DragPoint.Make<DragPointBody>(
  180. PrimitiveType.Capsule, new Vector3(0.2f, 0.3f, 0.24f), DragPoint.LightBlue
  181. );
  182. dragBody.Initialize(
  183. () => new Vector3(
  184. (BoneTransform[Bone.Hip].position.x + BoneTransform[Bone.Spine0a].position.x) / 2f,
  185. (BoneTransform[Bone.Spine1].position.y + BoneTransform[Bone.Spine0a].position.y) / 2f,
  186. (BoneTransform[Bone.Spine0a].position.z + BoneTransform[Bone.Hip].position.z) / 2f
  187. ),
  188. () => new Vector3(
  189. BoneTransform[Bone.Spine0a].eulerAngles.x,
  190. BoneTransform[Bone.Spine0a].eulerAngles.y,
  191. BoneTransform[Bone.Spine0a].eulerAngles.z + 90f
  192. )
  193. );
  194. dragBody.Set(maid.transform);
  195. dragBody.Select += OnSelectBody;
  196. dragBody.EndScale += OnSetDragPointScale;
  197. // Head Dragpoint
  198. DragPointHead dragHead = DragPoint.Make<DragPointHead>(
  199. PrimitiveType.Sphere, new Vector3(0.2f, 0.24f, 0.2f), DragPoint.LightBlue
  200. );
  201. dragHead.Initialize(meido,
  202. () => new Vector3(
  203. BoneTransform[Bone.Head].position.x,
  204. (BoneTransform[Bone.Head].position.y * 1.2f + BoneTransform[Bone.HeadNub].position.y * 0.8f) / 2f,
  205. BoneTransform[Bone.Head].position.z
  206. ),
  207. () => new Vector3(
  208. BoneTransform[Bone.Head].eulerAngles.x,
  209. BoneTransform[Bone.Head].eulerAngles.y,
  210. BoneTransform[Bone.Head].eulerAngles.z + 90f
  211. )
  212. );
  213. dragHead.Set(BoneTransform[Bone.Neck]);
  214. dragHead.Select += OnSelectFace;
  215. DragPoints[Bone.Head] = dragHead;
  216. // Torso Dragpoint
  217. Transform spineTrans1 = BoneTransform[Bone.Spine1];
  218. Transform spineTrans2 = BoneTransform[Bone.Spine1a];
  219. DragPointTorso dragTorso = DragPoint.Make<DragPointTorso>(
  220. PrimitiveType.Capsule, new Vector3(0.2f, 0.19f, 0.24f), DragPoint.LightBlue
  221. );
  222. dragTorso.Initialize(meido,
  223. () => new Vector3(
  224. spineTrans1.position.x,
  225. spineTrans2.position.y,
  226. spineTrans1.position.z - 0.05f
  227. ),
  228. () => new Vector3(
  229. spineTrans1.eulerAngles.x,
  230. spineTrans1.eulerAngles.y,
  231. spineTrans1.eulerAngles.z + 90f
  232. )
  233. );
  234. dragTorso.Set(BoneTransform[Bone.Spine1a]);
  235. DragPoints[Bone.Torso] = dragTorso;
  236. // Pelvis Dragpoint
  237. Transform pelvisTrans = BoneTransform[Bone.Pelvis];
  238. Transform spineTrans = BoneTransform[Bone.Spine];
  239. DragPointPelvis dragPelvis = DragPoint.Make<DragPointPelvis>(
  240. PrimitiveType.Capsule, new Vector3(0.2f, 0.15f, 0.24f), DragPoint.LightBlue
  241. );
  242. dragPelvis.Initialize(meido,
  243. () => new Vector3(
  244. pelvisTrans.position.x,
  245. (pelvisTrans.position.y + spineTrans.position.y) / 2f,
  246. pelvisTrans.position.z
  247. ),
  248. () => new Vector3(
  249. pelvisTrans.eulerAngles.x + 90f,
  250. pelvisTrans.eulerAngles.y + 90f,
  251. pelvisTrans.eulerAngles.z
  252. )
  253. );
  254. dragPelvis.Set(BoneTransform[Bone.Pelvis]);
  255. DragPoints[Bone.Pelvis] = dragPelvis;
  256. InitializeMuneDragPoint(left: true);
  257. InitializeMuneDragPoint(left: false);
  258. DragPointChain[] armDragPointL = MakeIKChain(BoneTransform[Bone.HandL]);
  259. DragPoints[Bone.UpperArmL] = armDragPointL[0];
  260. DragPoints[Bone.ForearmL] = armDragPointL[1];
  261. DragPoints[Bone.HandL] = armDragPointL[2];
  262. DragPointChain[] armDragPointR = MakeIKChain(BoneTransform[Bone.HandR]);
  263. DragPoints[Bone.UpperArmR] = armDragPointR[0];
  264. DragPoints[Bone.ForearmR] = armDragPointR[1];
  265. DragPoints[Bone.HandR] = armDragPointR[2];
  266. DragPointChain[] legDragPointL = MakeIKChain(BoneTransform[Bone.FootL]);
  267. DragPoints[Bone.CalfL] = legDragPointL[0];
  268. DragPoints[Bone.FootL] = legDragPointL[1];
  269. DragPointChain[] legDragPointR = MakeIKChain(BoneTransform[Bone.FootR]);
  270. DragPoints[Bone.CalfR] = legDragPointR[0];
  271. DragPoints[Bone.FootR] = legDragPointR[1];
  272. InitializeSpineDragPoint(
  273. Bone.Neck, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Hip, Bone.ThighL, Bone.ThighR
  274. );
  275. InitializeFingerDragPoint(Bone.Finger0L, Bone.Finger4R);
  276. InitializeFingerDragPoint(Bone.Toe0L, Bone.Toe2R);
  277. }
  278. private void InitializeMuneDragPoint(bool left)
  279. {
  280. Bone mune = left ? Bone.MuneL : Bone.MuneR;
  281. Bone sub = left ? Bone.MuneSubL : Bone.MuneSubR;
  282. DragPointChain muneDragPoint = DragPoint.Make<DragPointChain>(
  283. PrimitiveType.Sphere, Vector3.one * 0.12f, DragPoint.LightBlue
  284. );
  285. muneDragPoint.Initialize(meido,
  286. () => (BoneTransform[mune].position + BoneTransform[sub].position) / 2f,
  287. () => Vector3.zero
  288. );
  289. muneDragPoint.Set(BoneTransform[sub]);
  290. DragPoints[mune] = muneDragPoint;
  291. }
  292. private DragPointChain[] MakeIKChain(Transform lower)
  293. {
  294. Vector3 limbDragPointSize = Vector3.one * 0.12f;
  295. // Ignore Thigh transform when making a leg IK chain
  296. bool isLeg = lower.name.EndsWith("Foot");
  297. DragPointChain[] dragPoints = new DragPointChain[isLeg ? 2 : 3];
  298. for (int i = dragPoints.Length - 1; i >= 0; i--)
  299. {
  300. Transform joint = lower;
  301. dragPoints[i] = DragPoint.Make<DragPointChain>(
  302. PrimitiveType.Sphere, limbDragPointSize, DragPoint.LightBlue
  303. );
  304. dragPoints[i].Initialize(meido, () => joint.position, () => Vector3.zero);
  305. dragPoints[i].Set(joint);
  306. dragPoints[i].AddGizmo();
  307. lower = lower.parent;
  308. }
  309. return dragPoints;
  310. }
  311. private void InitializeFingerDragPoint(Bone start, Bone end)
  312. {
  313. Vector3 fingerDragPointSize = Vector3.one * 0.015f;
  314. int joints = BoneTransform[start].name.Split(' ')[2].StartsWith("Finger") ? 4 : 3;
  315. for (Bone bone = start; bone <= end; bone += joints)
  316. {
  317. for (int i = 1; i < joints; i++)
  318. {
  319. Transform trans = BoneTransform[bone + i];
  320. DragPointFinger chain = DragPoint.Make<DragPointFinger>(
  321. PrimitiveType.Sphere, fingerDragPointSize, DragPoint.Blue
  322. );
  323. chain.Initialize(meido, () => trans.position, () => Vector3.zero);
  324. chain.Set(trans);
  325. DragPoints[bone + i] = chain;
  326. }
  327. }
  328. }
  329. private void InitializeSpineDragPoint(params Bone[] bones)
  330. {
  331. Vector3 spineDragPointSize = Vector3.one * 0.045f;
  332. foreach (Bone bone in bones)
  333. {
  334. Transform spine = BoneTransform[bone];
  335. PrimitiveType primitive = bone == Bone.Hip ? PrimitiveType.Cube : PrimitiveType.Sphere;
  336. DragPointSpine dragPoint = DragPoint.Make<DragPointSpine>(
  337. primitive, spineDragPointSize, DragPoint.LightBlue
  338. );
  339. dragPoint.Initialize(meido,
  340. () => spine.position,
  341. () => Vector3.zero
  342. );
  343. dragPoint.Set(spine);
  344. dragPoint.AddGizmo();
  345. DragPoints[bone] = dragPoint;
  346. }
  347. }
  348. private void OnCubeActive(object sender, EventArgs args)
  349. {
  350. dragCube.gameObject.SetActive(CubeActive);
  351. }
  352. private void OnCubeSmall(object sender, EventArgs args)
  353. {
  354. dragCube.DragPointScale = CubeSmall ? DragPointGeneral.smallCube : 1f;
  355. }
  356. private void OnSetDragPointScale(object sender, EventArgs args)
  357. {
  358. this.SetDragPointScale(maid.transform.localScale.x);
  359. }
  360. private void OnSelectBody(object sender, EventArgs args)
  361. {
  362. SelectMaid?.Invoke(this, new MeidoUpdateEventArgs(meido.ActiveSlot, fromMaid: true, isBody: true));
  363. }
  364. private void OnSelectFace(object sender, EventArgs args)
  365. {
  366. SelectMaid?.Invoke(this, new MeidoUpdateEventArgs(meido.ActiveSlot, fromMaid: true, isBody: false));
  367. }
  368. private void SetDragPointScale(float scale)
  369. {
  370. foreach (DragPointMeido dragPoint in DragPoints.Values)
  371. {
  372. dragPoint.DragPointScale = scale;
  373. }
  374. dragBody.DragPointScale = scale;
  375. }
  376. private void InitializeBones()
  377. {
  378. // TODO: Move to external file somehow
  379. Transform transform = maid.body0.m_Bones.transform;
  380. BoneTransform = new Dictionary<Bone, Transform>()
  381. {
  382. [Bone.Head] = CMT.SearchObjName(transform, "Bip01 Head"),
  383. [Bone.Neck] = CMT.SearchObjName(transform, "Bip01 Neck"),
  384. [Bone.HeadNub] = CMT.SearchObjName(transform, "Bip01 HeadNub"),
  385. [Bone.IKHandL] = CMT.SearchObjName(transform, "_IK_handL"),
  386. [Bone.IKHandR] = CMT.SearchObjName(transform, "_IK_handR"),
  387. [Bone.MuneL] = CMT.SearchObjName(transform, "Mune_L"),
  388. [Bone.MuneSubL] = CMT.SearchObjName(transform, "Mune_L_sub"),
  389. [Bone.MuneR] = CMT.SearchObjName(transform, "Mune_R"),
  390. [Bone.MuneSubR] = CMT.SearchObjName(transform, "Mune_R_sub"),
  391. [Bone.Pelvis] = CMT.SearchObjName(transform, "Bip01 Pelvis"),
  392. [Bone.Hip] = CMT.SearchObjName(transform, "Bip01"),
  393. [Bone.Spine] = CMT.SearchObjName(transform, "Bip01 Spine"),
  394. [Bone.Spine0a] = CMT.SearchObjName(transform, "Bip01 Spine0a"),
  395. [Bone.Spine1] = CMT.SearchObjName(transform, "Bip01 Spine1"),
  396. [Bone.Spine1a] = CMT.SearchObjName(transform, "Bip01 Spine1a"),
  397. [Bone.ClavicleL] = CMT.SearchObjName(transform, "Bip01 L Clavicle"),
  398. [Bone.ClavicleR] = CMT.SearchObjName(transform, "Bip01 R Clavicle"),
  399. [Bone.UpperArmL] = CMT.SearchObjName(transform, "Bip01 L UpperArm"),
  400. [Bone.ForearmL] = CMT.SearchObjName(transform, "Bip01 L Forearm"),
  401. [Bone.HandL] = CMT.SearchObjName(transform, "Bip01 L Hand"),
  402. [Bone.UpperArmR] = CMT.SearchObjName(transform, "Bip01 R UpperArm"),
  403. [Bone.ForearmR] = CMT.SearchObjName(transform, "Bip01 R Forearm"),
  404. [Bone.HandR] = CMT.SearchObjName(transform, "Bip01 R Hand"),
  405. [Bone.ThighL] = CMT.SearchObjName(transform, "Bip01 L Thigh"),
  406. [Bone.CalfL] = CMT.SearchObjName(transform, "Bip01 L Calf"),
  407. [Bone.FootL] = CMT.SearchObjName(transform, "Bip01 L Foot"),
  408. [Bone.ThighR] = CMT.SearchObjName(transform, "Bip01 R Thigh"),
  409. [Bone.CalfR] = CMT.SearchObjName(transform, "Bip01 R Calf"),
  410. [Bone.FootR] = CMT.SearchObjName(transform, "Bip01 R Foot"),
  411. // fingers
  412. [Bone.Finger0L] = CMT.SearchObjName(transform, "Bip01 L Finger0"),
  413. [Bone.Finger01L] = CMT.SearchObjName(transform, "Bip01 L Finger01"),
  414. [Bone.Finger02L] = CMT.SearchObjName(transform, "Bip01 L Finger02"),
  415. [Bone.Finger0NubL] = CMT.SearchObjName(transform, "Bip01 L Finger0Nub"),
  416. [Bone.Finger1L] = CMT.SearchObjName(transform, "Bip01 L Finger1"),
  417. [Bone.Finger11L] = CMT.SearchObjName(transform, "Bip01 L Finger11"),
  418. [Bone.Finger12L] = CMT.SearchObjName(transform, "Bip01 L Finger12"),
  419. [Bone.Finger1NubL] = CMT.SearchObjName(transform, "Bip01 L Finger1Nub"),
  420. [Bone.Finger2L] = CMT.SearchObjName(transform, "Bip01 L Finger2"),
  421. [Bone.Finger21L] = CMT.SearchObjName(transform, "Bip01 L Finger21"),
  422. [Bone.Finger22L] = CMT.SearchObjName(transform, "Bip01 L Finger22"),
  423. [Bone.Finger2NubL] = CMT.SearchObjName(transform, "Bip01 L Finger2Nub"),
  424. [Bone.Finger3L] = CMT.SearchObjName(transform, "Bip01 L Finger3"),
  425. [Bone.Finger31L] = CMT.SearchObjName(transform, "Bip01 L Finger31"),
  426. [Bone.Finger32L] = CMT.SearchObjName(transform, "Bip01 L Finger32"),
  427. [Bone.Finger3NubL] = CMT.SearchObjName(transform, "Bip01 L Finger3Nub"),
  428. [Bone.Finger4L] = CMT.SearchObjName(transform, "Bip01 L Finger4"),
  429. [Bone.Finger41L] = CMT.SearchObjName(transform, "Bip01 L Finger41"),
  430. [Bone.Finger42L] = CMT.SearchObjName(transform, "Bip01 L Finger42"),
  431. [Bone.Finger4NubL] = CMT.SearchObjName(transform, "Bip01 L Finger4Nub"),
  432. [Bone.Finger0R] = CMT.SearchObjName(transform, "Bip01 R Finger0"),
  433. [Bone.Finger01R] = CMT.SearchObjName(transform, "Bip01 R Finger01"),
  434. [Bone.Finger02R] = CMT.SearchObjName(transform, "Bip01 R Finger02"),
  435. [Bone.Finger0NubR] = CMT.SearchObjName(transform, "Bip01 R Finger0Nub"),
  436. [Bone.Finger1R] = CMT.SearchObjName(transform, "Bip01 R Finger1"),
  437. [Bone.Finger11R] = CMT.SearchObjName(transform, "Bip01 R Finger11"),
  438. [Bone.Finger12R] = CMT.SearchObjName(transform, "Bip01 R Finger12"),
  439. [Bone.Finger1NubR] = CMT.SearchObjName(transform, "Bip01 R Finger1Nub"),
  440. [Bone.Finger2R] = CMT.SearchObjName(transform, "Bip01 R Finger2"),
  441. [Bone.Finger21R] = CMT.SearchObjName(transform, "Bip01 R Finger21"),
  442. [Bone.Finger22R] = CMT.SearchObjName(transform, "Bip01 R Finger22"),
  443. [Bone.Finger2NubR] = CMT.SearchObjName(transform, "Bip01 R Finger2Nub"),
  444. [Bone.Finger3R] = CMT.SearchObjName(transform, "Bip01 R Finger3"),
  445. [Bone.Finger31R] = CMT.SearchObjName(transform, "Bip01 R Finger31"),
  446. [Bone.Finger32R] = CMT.SearchObjName(transform, "Bip01 R Finger32"),
  447. [Bone.Finger3NubR] = CMT.SearchObjName(transform, "Bip01 R Finger3Nub"),
  448. [Bone.Finger4R] = CMT.SearchObjName(transform, "Bip01 R Finger4"),
  449. [Bone.Finger41R] = CMT.SearchObjName(transform, "Bip01 R Finger41"),
  450. [Bone.Finger42R] = CMT.SearchObjName(transform, "Bip01 R Finger42"),
  451. [Bone.Finger4NubR] = CMT.SearchObjName(transform, "Bip01 R Finger4Nub"),
  452. // Toes
  453. [Bone.Toe0L] = CMT.SearchObjName(transform, "Bip01 L Toe0"),
  454. [Bone.Toe01L] = CMT.SearchObjName(transform, "Bip01 L Toe01"),
  455. [Bone.Toe0NubL] = CMT.SearchObjName(transform, "Bip01 L Toe0Nub"),
  456. [Bone.Toe1L] = CMT.SearchObjName(transform, "Bip01 L Toe1"),
  457. [Bone.Toe11L] = CMT.SearchObjName(transform, "Bip01 L Toe11"),
  458. [Bone.Toe1NubL] = CMT.SearchObjName(transform, "Bip01 L Toe1Nub"),
  459. [Bone.Toe2L] = CMT.SearchObjName(transform, "Bip01 L Toe2"),
  460. [Bone.Toe21L] = CMT.SearchObjName(transform, "Bip01 L Toe21"),
  461. [Bone.Toe2NubL] = CMT.SearchObjName(transform, "Bip01 L Toe2Nub"),
  462. [Bone.Toe0R] = CMT.SearchObjName(transform, "Bip01 R Toe0"),
  463. [Bone.Toe01R] = CMT.SearchObjName(transform, "Bip01 R Toe01"),
  464. [Bone.Toe0NubR] = CMT.SearchObjName(transform, "Bip01 R Toe0Nub"),
  465. [Bone.Toe1R] = CMT.SearchObjName(transform, "Bip01 R Toe1"),
  466. [Bone.Toe11R] = CMT.SearchObjName(transform, "Bip01 R Toe11"),
  467. [Bone.Toe1NubR] = CMT.SearchObjName(transform, "Bip01 R Toe1Nub"),
  468. [Bone.Toe2R] = CMT.SearchObjName(transform, "Bip01 R Toe2"),
  469. [Bone.Toe21R] = CMT.SearchObjName(transform, "Bip01 R Toe21"),
  470. [Bone.Toe2NubR] = CMT.SearchObjName(transform, "Bip01 R Toe2Nub")
  471. };
  472. }
  473. }
  474. internal struct AttachPointInfo
  475. {
  476. public AttachPoint AttachPoint { get; }
  477. public string MaidGuid { get; }
  478. public int MaidIndex { get; }
  479. public static AttachPointInfo Empty
  480. {
  481. get => new AttachPointInfo(AttachPoint.None, String.Empty, -1);
  482. }
  483. public AttachPointInfo(AttachPoint attachPoint, string maidGuid, int maidIndex)
  484. {
  485. this.AttachPoint = attachPoint;
  486. this.MaidGuid = maidGuid;
  487. this.MaidIndex = maidIndex;
  488. }
  489. }
  490. }