IKSolver.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. //
  2. // Copyright (c) 2008-2016 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Scene/Component.h"
  24. struct ik_solver_t;
  25. struct ik_node_t;
  26. namespace Urho3D
  27. {
  28. class AnimationState;
  29. class IKConstraint;
  30. class IKEffector;
  31. /*!
  32. * @brief Marks the root or "beginning" of an IK chain or multiple IK chains.
  33. * The solving algorithm can be set along with other solver related parameters.
  34. * The IK problem is solved starting from the node this component is attached
  35. * to and ending at all nodes that have an IKEffector component attached.
  36. */
  37. class URHO3D_API IKSolver : public Component
  38. {
  39. URHO3D_OBJECT(IKSolver, Component)
  40. public:
  41. enum Algorithm
  42. {
  43. FABRIK
  44. /* not implemented yet
  45. JACOBIAN_INVERSE,
  46. JACOBIAN_TRANSPOSE*/
  47. };
  48. /// Construct an IK root component.
  49. IKSolver(Context* context);
  50. /// Default destructor.
  51. virtual ~IKSolver();
  52. /// Registers this class to the context.
  53. static void RegisterObject(Context* context);
  54. /// Returns the active algorithm
  55. Algorithm GetAlgorithm() const;
  56. /*!
  57. * @brief Selects the solver algorithm. Default is FABRIK.
  58. *
  59. * The currently supported solvers are listed below.
  60. * + **FABRIK**: This is a fairly new and highly efficient inverse
  61. * kinematic solving algorithm. It requires the least iterations to
  62. * reach its goal, it does not suffer from singularities (nearly no
  63. * violent snapping about), and it always converges.
  64. */
  65. void SetAlgorithm(Algorithm algorithm);
  66. /// Returns the configured maximum number of iterations.
  67. unsigned GetMaximumIterations() const;
  68. /*!
  69. * @brief Sets the maximum number of iterations the solver is allowed to
  70. * perform before applying the result.
  71. *
  72. * Depending on the algorithm, you may want higher or lower values.
  73. * FABRIK looks decent after only 10 iterations, whereas Jacobian based
  74. * methods often require more than a 100.
  75. *
  76. * The default value is 20.
  77. *
  78. * @note Most algorithms have a convergence criteria at which the solver
  79. * will stop iterating, so most of the time the maximum number of
  80. * iterations isn't even reached.
  81. *
  82. * @param[in] iterations Number of iterations. Must be greater than 0. Higher
  83. * values yield more accurate results, but at the cost of performance.
  84. */
  85. void SetMaximumIterations(unsigned iterations);
  86. /// Returns the configured tolerance.
  87. float GetTolerance() const;
  88. /*!
  89. * @brief Sets the distance at which the effector is "close enough" to the
  90. * target node, at which point the algorithm will stop iterating.
  91. *
  92. * @param tolerance The distance to set. Smaller values yield more accurate
  93. * results, but at the cost of more iterations. Generally you'll want to
  94. * specify a number that is about 1/100th to 1/1000th of the total size of
  95. * the IK chain, e.g. if your human character has a leg that is 1 Urho3D
  96. * unit long, a good starting tolerance would be 0.01.
  97. */
  98. void SetTolerance(float tolerance);
  99. /// Whether or not rotations should be calculated.
  100. bool BoneRotationsEnabled() const;
  101. /*!
  102. * @brief When enabled, final joint rotations are calculated as a post
  103. * processing step. If you are using IK on a model with skinning, you will
  104. * want to enable this or it will look wrong. If you disable this, then
  105. * you will get a slight performance boost (less calculations are required)
  106. * but only the node positions are updated. This can be useful for scene
  107. * IK (perhaps a chain of platforms, where each platform should retain its
  108. * initial world rotation?)
  109. */
  110. void EnableBoneRotations(bool enable);
  111. /// Whether or not target rotation is enabled
  112. bool TargetRotationEnabled() const;
  113. /*!
  114. * @brief When enabled, the effector will try to match the target's
  115. * rotation as well as the effectors position. When disabled, the target
  116. * node will reach the effector with any rotation necessary.
  117. *
  118. * If the target position goes out of range of the effector then the
  119. * rotation will no longer be matched. The chain will try to reach out to
  120. * reach the target position, even if it means rotating towards it.
  121. */
  122. void EnableTargetRotation(bool enable);
  123. /// Whether or not continuous solving is enabled or not.
  124. bool ContinuousSolvingEnabled() const;
  125. /*!
  126. * @brief When enabled, the solver will refrain from applying the initial
  127. * pose before solving. The result is that it will use the previously
  128. * solved tree as a basis for the new calculation instead of using the
  129. * initial tree. This can be useful if you want to simulate chains or
  130. * something similar. When disabled, the solver will use the initial
  131. * positions/rotations which where set when the solver was first created.
  132. *
  133. * If you call UpdateInitialPose() then the initial tree will be matched to
  134. * the current nodes in the scene graph.
  135. *
  136. * If you call ResetToInitialPose() then you will do the opposite of
  137. * UpdateInitialPose() -- the initial pose is applied back to the scene
  138. * graph.
  139. *
  140. * If you enable pose updating with EnableUpdatePose(), then the initial
  141. * tree will automatically be matched to the current nodes in the scene
  142. * graph.
  143. */
  144. void EnableContinuousSolving(bool enable);
  145. /// Whether or not the initial pose is updated for every solution
  146. bool UpdatePoseEnabled() const;
  147. /*!
  148. * @brief When enabled, the current Urho3D node positions and rotations in
  149. * the scene graph will be copied into the solver's initial tree right
  150. * before solving. This should generally be enabled for animated models
  151. * so the solver refers to the current frame of animation rather than to
  152. * the animation's initial pose.
  153. *
  154. * When disabled, the initial pose will remain unmodified. The initial pose
  155. * is set when the solver is first created. You can manually update the
  156. * initial pose at any time by calling UpdateInitialPose().
  157. */
  158. void EnableUpdatePose(bool enable);
  159. /// Whether or not the solver should be invoked automatically
  160. bool AutoSolveEnabled() const;
  161. /*!
  162. * @brief Mostly exists because of the editor. When enabled, the solver
  163. * will be invoked automatically for you. If you need to do additional
  164. * calculations before being able to set the effector target data, you will
  165. * want to disable this and call Solve() manually.
  166. */
  167. void EnableAutoSolve(bool enable);
  168. /*!
  169. * @brief Invokes the solver. The solution is applied back to the scene
  170. * graph automatically.
  171. * @note You will want to register to E_SCENEDRAWABLEUPDATEFINISHED and
  172. * call this method there. This is right after the animations have been
  173. * applied.
  174. */
  175. void Solve();
  176. /*!
  177. * @brief Causes the initial tree to be applied back to Urho3D's scene
  178. * graph. This is what gets called when continuous solving is disabled.
  179. */
  180. void ResetToInitialPose();
  181. /*!
  182. * @brief Causes the current scene graph data to be copied into the solvers
  183. * initial pose. This should generally be called before solving if you
  184. * are using IK on an animated model. If you don't update the initial pose,
  185. * then the result will be a "continuous solution", where the solver will
  186. * use the previously calculated tree as a basis for the new solution.
  187. */
  188. void UpdateInitialPose();
  189. /// Causes the solver tree to be rebuilt before solving the next time.
  190. void MarkSolverTreeDirty();
  191. void DrawDebugGeometry(bool depthTest);
  192. virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
  193. private:
  194. /// Subscribe to drawable update finished event here
  195. virtual void OnSceneSet(Scene* scene);
  196. /// Destroys and creates the tree
  197. virtual void OnNodeSet(Node* scene);
  198. /// Creates the ik library node and sets the current rotation/position and user data correctly.
  199. ik_node_t* CreateIKNode(const Node* node);
  200. /// Destroys the solver's tree
  201. void DestroyTree();
  202. /// Builds the solver's tree to match the scene graph's tree. If a tree already exists, it is first destroyed
  203. void RebuildTree();
  204. /// Builds a chain of nodes up to the specified node and adds an effector. Thus, the specified node must have an IKEffector attached.
  205. void BuildTreeToEffector(const Node* node);
  206. void HandleComponentAdded(StringHash eventType, VariantMap& eventData);
  207. void HandleComponentRemoved(StringHash eventType, VariantMap& eventData);
  208. void HandleNodeAdded(StringHash eventType, VariantMap& eventData);
  209. void HandleNodeRemoved(StringHash eventType, VariantMap& eventData);
  210. /// Invokes the IK solver
  211. void HandleSceneDrawableUpdateFinished(StringHash eventType, VariantMap& eventData);
  212. PODVector<IKEffector*> effectorList_;
  213. ik_solver_t* solver_;
  214. Algorithm algorithm_;
  215. bool solverTreeNeedsRebuild_;
  216. bool updateInitialPose_;
  217. bool autoSolveEnabled_;
  218. };
  219. } // namespace Urho3D