PenisIKCtrl.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. using System;
  2. using System.Collections.Generic;
  3. using kt.ik;
  4. using kt.Utility;
  5. using UnityEngine;
  6. [Serializable]
  7. public class PenisIKCtrl : AIKCtrl
  8. {
  9. public PenisIKCtrl(FullBodyIKMgr ik_mgr) : base(ik_mgr, FullBodyIKMgr.IKEffectorType.Penis)
  10. {
  11. base.isUpperBody = false;
  12. foreach (Transform transform in base.chainBones)
  13. {
  14. this.BoneDataDic[transform] = new PenisIKCtrl.BoneData(transform);
  15. }
  16. }
  17. public AutoKupaCtrl kupaCtrl { get; private set; }
  18. public override void Reset()
  19. {
  20. base.Reset();
  21. this.LastIsInserted = this.IsInserted;
  22. this.IsInserted = false;
  23. this.IsNotEscape = false;
  24. foreach (PenisIKCtrl.BoneData boneData in this.BoneDataDic.Values)
  25. {
  26. boneData.isInsertedOnce = false;
  27. boneData.lastIsScaleVariable = boneData.isScaleVariable;
  28. if (boneData.isScaleVariable)
  29. {
  30. boneData.isScaleVariable = false;
  31. boneData.bone.localScale = Vector3.one;
  32. }
  33. }
  34. }
  35. public override void SetIKSetting(IKAttachParam param)
  36. {
  37. PenisIKParam penisIKParam = param as PenisIKParam;
  38. this.insertBeforeAxis = penisIKParam.insertBefore;
  39. this.insertAfterAxis = penisIKParam.insertAfter;
  40. this.sensorLength = penisIKParam.sensorLength;
  41. this.IsNotEscape = penisIKParam.isNotEscape;
  42. this.IsForciblyBend = penisIKParam.isForciblyBend;
  43. this.AlwaysLookTarget = penisIKParam.alwaysLookTarget;
  44. if (this.LastIsInserted)
  45. {
  46. this.IsInserted |= (base.GetIKSettingData(param.attachType).curTargetData.target == param.attachTarget);
  47. }
  48. base.SetIKSetting(param);
  49. this.kupaCtrl = penisIKParam.kupaCtrl;
  50. if (this.kupaCtrl != null)
  51. {
  52. this.kupaCtrl.SetKupaInsert(base.chainBones, this.insertBeforeAxis);
  53. this.kupaCtrl.isUpdateTBody = false;
  54. }
  55. foreach (KeyValuePair<string, float> keyValuePair in penisIKParam.boneNameScaleValPair)
  56. {
  57. Transform bone = this.myIKMgr.body.GetBone(keyValuePair.Key);
  58. this.BoneDataDic[bone].isScaleVariable = true;
  59. this.BoneDataDic[bone].scaleValue = keyValuePair.Value;
  60. }
  61. this.MotionCtrlBoneName = penisIKParam.motionCtrlBoneName;
  62. this.MotionCtrlWeight = penisIKParam.motionCtrlWeight;
  63. }
  64. public override void Detach()
  65. {
  66. if (this.kupaCtrl != null && this.kupaCtrl.morphInsert.chainEndBone == base.bone)
  67. {
  68. this.kupaCtrl.SetKupaInsert(AutoKupaCtrl.KupaType.Close, base.chainBones, this.insertBeforeAxis);
  69. this.kupaCtrl.isUpdateTBody = true;
  70. }
  71. this.kupaCtrl = null;
  72. this.IsInserted = false;
  73. this.IsNotEscape = false;
  74. foreach (PenisIKCtrl.BoneData boneData in this.BoneDataDic.Values)
  75. {
  76. if (boneData.bone)
  77. {
  78. boneData.bone.localPosition = boneData.initLocalPos;
  79. }
  80. boneData.isScaleVariable = boneData.lastIsScaleVariable;
  81. }
  82. base.Detach();
  83. }
  84. protected override void SetTargetTransform(AIKCtrl.IKSettingData data, Vector3 pos, Quaternion rot)
  85. {
  86. if (data.blendType == AIKCtrl.IKBlendType.IK_To_Detach && data.curTargetData.lastTarget)
  87. {
  88. pos = data.curTargetData.lastTarget.position;
  89. rot = data.curTargetData.lastTarget.rotation;
  90. }
  91. base.SetTargetTransform(data, pos, rot);
  92. if (!data.isPointAttach)
  93. {
  94. return;
  95. }
  96. base.constraintTarget.rotation = rot;
  97. Vector3 vector = rot * this.insertBeforeAxis;
  98. Vector3 vector2 = rot * this.insertAfterAxis;
  99. for (int i = 1; i < base.chainBones.Length; i++)
  100. {
  101. Transform transform = base.chainBones[i];
  102. if (this.BoneDataDic[transform].isScaleVariable)
  103. {
  104. transform.localScale = Vector3.one;
  105. }
  106. transform.localPosition = this.BoneDataDic[transform].initLocalPos;
  107. Transform transform2 = base.chainBones[i - 1];
  108. Color magenta = Color.magenta;
  109. magenta.a = base.positionWeight;
  110. Debug.DrawLine(transform2.position, transform.position, magenta);
  111. }
  112. if ((this.IsNotEscape && this.IsForciblyBend) || this.AlwaysLookTarget)
  113. {
  114. Vector3 fromDirection = base.chainBones[1].position - base.chainBones[0].position;
  115. Vector3 toDirection = base.constraintTarget.position - base.chainBones[0].position;
  116. Quaternion quaternion = Quaternion.FromToRotation(fromDirection, toDirection) * base.chainBones[0].rotation;
  117. if (this.AlwaysLookTarget)
  118. {
  119. quaternion = Quaternion.Lerp(base.chainBones[0].rotation, quaternion, base.positionWeight);
  120. }
  121. Debug.DrawLine(base.chainBones[0].position, base.bone.position, UnityUtility.SetAlpha(Color.cyan, base.positionWeight));
  122. base.chainBones[0].rotation = quaternion;
  123. }
  124. float num = Vector3.Dot(base.bone.position - base.constraintTarget.position, vector);
  125. if (!this.IsNotEscape || !this.IsInserted)
  126. {
  127. this.IsInserted = (num <= 0f);
  128. if (this.IsInserted)
  129. {
  130. for (int j = 1; j < base.chainBones.Length; j++)
  131. {
  132. Transform transform3 = base.chainBones[j];
  133. float num2 = Vector3.Dot(transform3.position - base.constraintTarget.position, vector);
  134. if (num2 <= 0f)
  135. {
  136. this.IsInserted &= this.IsInsertRangeIn(transform3.position);
  137. break;
  138. }
  139. }
  140. }
  141. }
  142. Debug.DrawRay(pos, vector * 0.025f, UnityUtility.SetAlpha(Color.blue, base.positionWeight));
  143. Debug.DrawRay(pos, vector2 * 0.025f, UnityUtility.SetAlpha(Color.red, base.positionWeight));
  144. if (!this.IsInserted)
  145. {
  146. base.positionWeight = 0f;
  147. }
  148. else if (this.sensorLength > 0f && num > 0f)
  149. {
  150. base.positionWeight *= 1f - num / this.sensorLength;
  151. }
  152. if (!this.IsNotEscape && this.IsForciblyBend)
  153. {
  154. Vector3 fromDirection2 = base.chainBones[1].position - base.chainBones[0].position;
  155. Vector3 toDirection2 = base.constraintTarget.position - base.chainBones[0].position;
  156. Quaternion quaternion2 = Quaternion.FromToRotation(fromDirection2, toDirection2) * base.chainBones[0].rotation;
  157. quaternion2 = Quaternion.Lerp(base.chainBones[0].rotation, quaternion2, base.positionWeight);
  158. Debug.DrawLine(base.chainBones[0].position, base.bone.position, UnityUtility.SetAlpha(Color.cyan, base.positionWeight));
  159. base.chainBones[0].rotation = quaternion2;
  160. }
  161. num -= this.sensorLength;
  162. bool flag = true;
  163. float num3 = -1f;
  164. bool flag2 = false;
  165. for (int k = 1; k < base.chainBones.Length; k++)
  166. {
  167. Transform transform4 = base.chainBones[k];
  168. PenisIKCtrl.BoneData boneData = this.BoneDataDic[transform4];
  169. Transform transform5 = base.chainBones[k - 1];
  170. if (k == 1)
  171. {
  172. this.BoneDataDic[transform5].orijinPos = transform5.position;
  173. this.BoneDataDic[transform5].solvePos = transform5.position;
  174. }
  175. Vector3 solvePos = this.BoneDataDic[transform5].solvePos;
  176. Vector3 vector3;
  177. if (this.MotionCtrlWeight < 1f)
  178. {
  179. Matrix4x4 localToWorldMatrix = transform5.localToWorldMatrix;
  180. localToWorldMatrix.SetColumn(3, transform5.position);
  181. vector3 = localToWorldMatrix.MultiplyPoint3x4(transform4.localPosition);
  182. }
  183. else
  184. {
  185. vector3 = transform4.position;
  186. }
  187. float num4 = Vector3.Dot(vector3 - base.constraintTarget.position, vector);
  188. Vector3 vector4 = Vector3.zero;
  189. boneData.insertValueSelf = 0f;
  190. boneData.insertValueParent = 0f;
  191. if (!flag2)
  192. {
  193. flag2 = (this.MotionCtrlBoneName == transform4.name);
  194. }
  195. if (num4 <= 0f)
  196. {
  197. float num5 = (!flag) ? (Mathf.Abs(num4) / (Mathf.Abs(num4) + num3)) : 1f;
  198. Vector3 a = base.constraintTarget.position + vector * num4;
  199. Vector3 b = base.constraintTarget.position + vector2 * Vector3.Dot(vector3 - base.constraintTarget.position, vector2);
  200. vector4 = Vector3.Lerp(a, b, num5);
  201. boneData.insertValueSelf = 1f;
  202. boneData.insertValueParent = num5;
  203. flag = true;
  204. }
  205. else
  206. {
  207. Vector3 vector5 = base.constraintTarget.position + vector * num4;
  208. float num5 = Mathf.Abs(num) / (num4 + Mathf.Abs(num));
  209. if (this.IsNotEscape && this.IsForciblyBend)
  210. {
  211. vector4 = vector5;
  212. }
  213. else
  214. {
  215. vector4 = Vector3.Lerp(vector3, vector5, num5);
  216. }
  217. boneData.insertValueSelf = num5;
  218. flag = false;
  219. }
  220. if (!boneData.isInsertedOnce && !data.isBlendNow)
  221. {
  222. boneData.isInsertedOnce = (num4 <= 0f);
  223. }
  224. this.BoneDataDic[transform4].orijinPos = vector3;
  225. float d = Vector3.Distance(transform5.position, transform4.position);
  226. if (flag2)
  227. {
  228. vector4 = Vector3.Lerp(vector4, vector3, this.MotionCtrlWeight);
  229. }
  230. if (this.MotionCtrlWeight < 1f)
  231. {
  232. Vector3 a2 = vector4 - solvePos;
  233. float magnitude = a2.magnitude;
  234. if (magnitude > 0f)
  235. {
  236. vector4 = solvePos + a2 / magnitude * d;
  237. }
  238. }
  239. this.BoneDataDic[transform4].solvePos = vector4;
  240. num3 = num4;
  241. }
  242. }
  243. private bool IsInsertRangeIn(Vector3 position)
  244. {
  245. Vector3 lhs = position - base.constraintTarget.position;
  246. Quaternion rotation = Quaternion.FromToRotation(Vector3.forward, base.constraintTarget.rotation * this.insertBeforeAxis);
  247. Vector3 rhs = rotation * Vector3.up;
  248. Vector3 rhs2 = rotation * Vector3.right;
  249. float num = Mathf.Abs(Vector3.Dot(lhs, rhs));
  250. float num2 = Mathf.Abs(Vector3.Dot(lhs, rhs2));
  251. return num <= 0.05f && num2 <= 0.05f;
  252. }
  253. public override void OnPostFullBodySolverUpdate()
  254. {
  255. if (!base.pointIKData.isIKExec)
  256. {
  257. return;
  258. }
  259. for (int i = 1; i < base.chainBones.Length; i++)
  260. {
  261. Transform transform = base.chainBones[i - 1];
  262. Transform transform2 = base.chainBones[i];
  263. PenisIKCtrl.BoneData boneData = this.BoneDataDic[transform2];
  264. Vector3 orijinPos = boneData.orijinPos;
  265. Vector3 solvePos = boneData.solvePos;
  266. Vector3 a = Vector3.Lerp(orijinPos, solvePos, base.positionWeight);
  267. Vector3 fromDirection = transform2.position - transform.position;
  268. Vector3 toDirection = a - transform.position;
  269. transform.rotation = Quaternion.FromToRotation(fromDirection, toDirection) * transform.rotation;
  270. if (boneData.isScaleVariable)
  271. {
  272. Vector3 vector = new Vector3(1f, boneData.scaleValue, boneData.scaleValue);
  273. if (base.pointIKData.blendType != AIKCtrl.IKBlendType.IK_To_Detach)
  274. {
  275. if (!boneData.isInsertedOnce)
  276. {
  277. transform2.localScale = Vector3.Lerp(Vector3.one, vector, boneData.insertValueSelf * base.positionWeight);
  278. }
  279. else
  280. {
  281. transform2.localScale = vector;
  282. }
  283. }
  284. else
  285. {
  286. transform2.localScale = Vector3.Lerp(Vector3.one, vector, boneData.insertValueSelf * base.positionWeight);
  287. }
  288. }
  289. }
  290. if (this.kupaCtrl != null)
  291. {
  292. this.kupaCtrl.KupaUpdate();
  293. }
  294. if (this.IsInserted && this.IsNotEscape)
  295. {
  296. bool flag = false;
  297. AIKCtrl.PosRotPair posRotPair = default(AIKCtrl.PosRotPair);
  298. for (int j = 1; j < base.chainBones.Length; j++)
  299. {
  300. Transform transform3 = base.chainBones[j];
  301. Vector3 rhs = base.constraintTarget.rotation * this.insertBeforeAxis;
  302. float num = Vector3.Dot(transform3.position - base.constraintTarget.position, rhs);
  303. if (!flag && num <= 0f)
  304. {
  305. flag = true;
  306. posRotPair.Copy(transform3);
  307. }
  308. if (flag)
  309. {
  310. transform3.position = posRotPair.pos;
  311. transform3.rotation = posRotPair.rot;
  312. }
  313. else if (j == base.chainBones.Length - 2)
  314. {
  315. transform3.position = base.constraintTarget.position;
  316. break;
  317. }
  318. }
  319. }
  320. }
  321. public void PenisRotateReset()
  322. {
  323. for (int i = 1; i < base.chainBones.Length; i++)
  324. {
  325. Transform transform = base.chainBones[i];
  326. transform.localPosition = this.BoneDataDic[transform].initLocalPos;
  327. transform.localRotation = this.BoneDataDic[transform].initLocalRot;
  328. }
  329. }
  330. private const float INSERT_RANGE_MAX = 0.05f;
  331. private Dictionary<Transform, PenisIKCtrl.BoneData> BoneDataDic = new Dictionary<Transform, PenisIKCtrl.BoneData>();
  332. public Vector3 insertBeforeAxis = Vector3.back;
  333. public Vector3 insertAfterAxis = Vector3.forward;
  334. [Space]
  335. public float sensorLength;
  336. private bool IsInserted;
  337. private bool LastIsInserted;
  338. [SerializeField]
  339. [Header("ちんこを抜けないようにする")]
  340. private bool IsNotEscape;
  341. [SerializeField]
  342. [Header("ちんこを無理やり曲げる")]
  343. private bool IsForciblyBend;
  344. [SerializeField]
  345. private bool AlwaysLookTarget;
  346. [Space]
  347. [SerializeField]
  348. [Header("モーション側で制御するボーン名")]
  349. private string MotionCtrlBoneName = string.Empty;
  350. [SerializeField]
  351. [Header("制御のウェイト")]
  352. [Range(0f, 1f)]
  353. private float MotionCtrlWeight;
  354. private class BoneData
  355. {
  356. public BoneData(Transform bone)
  357. {
  358. this.bone = bone;
  359. this.initLocalPos = bone.localPosition;
  360. this.initLocalRot = bone.localRotation;
  361. }
  362. public readonly Transform bone;
  363. public readonly Vector3 initLocalPos;
  364. public readonly Quaternion initLocalRot;
  365. public bool isInsertedOnce;
  366. public float insertValueSelf;
  367. public float insertValueParent;
  368. public Vector3 orijinPos;
  369. public Vector3 solvePos;
  370. public bool isScaleVariable;
  371. public bool lastIsScaleVariable;
  372. public float scaleValue = 1f;
  373. }
  374. }