Geen omschrijving
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CCDSolver2D.cs 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System.Collections.Generic;
  2. using UnityEngine.Profiling;
  3. using UnityEngine.Scripting.APIUpdating;
  4. namespace UnityEngine.U2D.IK
  5. {
  6. /// <summary>
  7. /// Component for 2D Cyclic Coordinate Descent (CCD) IK.
  8. /// </summary>
  9. [MovedFrom("UnityEngine.Experimental.U2D.IK")]
  10. [Solver2DMenuAttribute("Chain (CCD)")]
  11. public class CCDSolver2D : Solver2D
  12. {
  13. const int k_MinIterations = 1;
  14. const float k_MinTolerance = 0.001f;
  15. const float k_MinVelocity = 0.01f;
  16. const float k_MaxVelocity = 1f;
  17. [SerializeField]
  18. IKChain2D m_Chain = new IKChain2D();
  19. [SerializeField]
  20. [Range(k_MinIterations, 50)]
  21. int m_Iterations = 10;
  22. [SerializeField]
  23. [Range(k_MinTolerance, 0.1f)]
  24. float m_Tolerance = 0.01f;
  25. [SerializeField]
  26. [Range(0f, 1f)]
  27. float m_Velocity = 0.5f;
  28. Vector3[] m_Positions;
  29. /// <summary>
  30. /// Get and Set the solver's integration count.
  31. /// </summary>
  32. public int iterations
  33. {
  34. get => m_Iterations;
  35. set => m_Iterations = Mathf.Max(value, k_MinIterations);
  36. }
  37. /// <summary>
  38. /// Get and Set target distance tolerance.
  39. /// </summary>
  40. public float tolerance
  41. {
  42. get => m_Tolerance;
  43. set => m_Tolerance = Mathf.Max(value, k_MinTolerance);
  44. }
  45. /// <summary>
  46. /// Get and Set the solver velocity.
  47. /// </summary>
  48. public float velocity
  49. {
  50. get => m_Velocity;
  51. set => m_Velocity = Mathf.Clamp01(value);
  52. }
  53. /// <summary>
  54. /// Returns the number of chain in the solver.
  55. /// </summary>
  56. /// <returns>This always returns 1</returns>
  57. protected override int GetChainCount() => 1;
  58. /// <summary>
  59. /// Gets the chain in the solver by index.
  60. /// </summary>
  61. /// <param name="index">Chain index.</param>
  62. /// <returns>Returns IKChain2D at the index.</returns>
  63. public override IKChain2D GetChain(int index) => m_Chain;
  64. /// <summary>
  65. /// DoPrepare override from base class.
  66. /// </summary>
  67. protected override void DoPrepare()
  68. {
  69. if (m_Positions == null || m_Positions.Length != m_Chain.transformCount)
  70. m_Positions = new Vector3[m_Chain.transformCount];
  71. for (var i = 0; i < m_Chain.transformCount; ++i)
  72. m_Positions[i] = m_Chain.transforms[i].position;
  73. }
  74. /// <summary>
  75. /// DoUpdateIK override from base class.
  76. /// </summary>
  77. /// <param name="effectorPositions">Target position for the chain.</param>
  78. protected override void DoUpdateIK(List<Vector3> effectorPositions)
  79. {
  80. Profiler.BeginSample(nameof(CCDSolver2D.DoUpdateIK));
  81. var effectorPosition = effectorPositions[0];
  82. var effectorLocalPosition2D = m_Chain.transforms[0].InverseTransformPoint(effectorPosition);
  83. effectorPosition = m_Chain.transforms[0].TransformPoint(effectorLocalPosition2D);
  84. if (CCD2D.Solve(effectorPosition, GetPlaneRootTransform().forward, iterations, tolerance, Mathf.Lerp(k_MinVelocity, k_MaxVelocity, m_Velocity), ref m_Positions))
  85. {
  86. for (var i = 0; i < m_Chain.transformCount - 1; ++i)
  87. {
  88. var startLocalPosition = m_Chain.transforms[i + 1].localPosition;
  89. var endLocalPosition = m_Chain.transforms[i].InverseTransformPoint(m_Positions[i + 1]);
  90. m_Chain.transforms[i].localRotation *= Quaternion.FromToRotation(startLocalPosition, endLocalPosition);
  91. }
  92. }
  93. Profiler.EndSample();
  94. }
  95. }
  96. }