IKSolver.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. //
  2. // Copyright (c) 2008-2020 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. ONE_BONE = 0,
  44. TWO_BONE,
  45. FABRIK
  46. /* not implemented yet
  47. MSD,
  48. JACOBIAN_INVERSE,
  49. JACOBIAN_TRANSPOSE*/
  50. };
  51. enum Feature
  52. {
  53. /*!
  54. * @brief Should be enabled if your model uses skinning or if you are
  55. * generally interested in correct joint rotations. Has a minor
  56. * performance impact.
  57. *
  58. * When enabled, final joint rotations are calculated as a post
  59. * processing step. If you are using IK on a model with skinning, you will
  60. * want to enable this or it will look wrong. If you disable this, then
  61. * you will get a slight performance boost (less calculations are required)
  62. * but only the node positions are updated. This can be useful for scene
  63. * IK (perhaps a chain of platforms, where each platform should retain its
  64. * initial world rotation?)
  65. */
  66. JOINT_ROTATIONS = 0x01,
  67. /*!
  68. * @brief When enabled, the effector will try to match the target's
  69. * rotation as well as the effectors position. When disabled, the target
  70. * node will reach the effector with any rotation necessary.
  71. *
  72. * If the target position goes out of range of the effector then the
  73. * rotation will no longer be matched. The chain will try to reach out to
  74. * reach the target position, even if it means rotating towards it.
  75. */
  76. TARGET_ROTATIONS = 0x02,
  77. /*!
  78. * When the solver is first initialized, it will copy the positions
  79. * and rotations of the current Urho3D scene graph into an internal
  80. * structure. This is referred to as the "original pose" and will by
  81. * default never change for the duration of the solver's life cycle.
  82. * When the solver is destroyed, the original pose is applied back to
  83. * Urho3D's scene graph so the nodes are restored to whatever they were
  84. * before the solver was created.
  85. *
  86. * By enabling UPDATE_ORIGINAL_POSE, the original pose will be updated
  87. * right before solving to reflect the current Urho3D scene graph. As
  88. * a consequence, there will no longer be an original pose to restore
  89. * when the solver is destroyed.
  90. *
  91. * When disabled, the original pose will remain unmodified. The original
  92. * pose is set when the solver is first created. You can manually update the
  93. * original pose at any time by calling UpdateInitialPose().
  94. */
  95. UPDATE_ORIGINAL_POSE = 0x04,
  96. /*!
  97. * @brief Should be enabled if you are using IK on an animated model,
  98. * along with disabling USE_ORIGINAL_POSE.
  99. *
  100. * The "active pose" has two purposes: The solver uses it as the
  101. * initial tree to derive a solution from, and at the same time uses it
  102. * to store the solution into. Thus, the typical solving process is:
  103. * 1) The active pose needs to be updated to reflect a preferred
  104. * initial condition (such as the current frame of animation)
  105. * 2) Call Solve()
  106. * 3) The active pose now holds the solution, so it must be applied
  107. * back to the Urho3D scene graph.
  108. *
  109. * When enabled, the active pose is updated right before solving to
  110. * reflect the current state of the Urho3D scene graph.
  111. *
  112. * When disabled, the active pose will simply remain as it was since
  113. * the last time Solve() was called.
  114. *
  115. * @note This option conflicts with USE_ORIGINAL_POSE. Make sure to
  116. * disable USE_ORIGINAL_POSE if you enable this feature.
  117. */
  118. UPDATE_ACTIVE_POSE = 0x08,
  119. /*!
  120. * @brief Choose between using the original pose or the active pose as
  121. * a basis for a solution.
  122. *
  123. * When enabled, the solver will copy the original pose
  124. * (see UPDATE_ORIGINAL_POSE) into the active pose before solving (and
  125. * thus use the original pose as a basis for a solution).
  126. *
  127. * @note This option conflicts with UPDATE_ACTIVE_POSE. If you enable
  128. * this feature, make sure to disable UPDATE_ACTIVE_POSE.
  129. *
  130. * If both UPDATE_ACTIVE_POSE and USE_ORIGINAL_POSE are disabled, then
  131. * the solver will use the previously solved tree as a basis for the new
  132. * calculation. The result is a more "continuous" solution that unfolds
  133. * over time. This can be useful if you want to simulate chains or
  134. * something similar.
  135. */
  136. USE_ORIGINAL_POSE = 0x10,
  137. /*!
  138. * Due to the somewhat unfortunate performance impacts, the solver
  139. * does not enable constraints by default. Enabling constraints causes
  140. * the solver's tree to be written to and from Urho3D's scene graph every
  141. * iteration, while calling ApplyConstraints(). Disabling constraints means
  142. * ApplyConstraints() is never called.
  143. */
  144. CONSTRAINTS = 0x20,
  145. /*!
  146. * Mostly exists because of the editor. When enabled, the solver
  147. * will be invoked automatically for you. If you need to do additional
  148. * calculations before being able to set the effector target data, you will
  149. * want to disable this and call Solve() manually.
  150. */
  151. AUTO_SOLVE = 0x40
  152. };
  153. /// Construct an IK root component.
  154. explicit IKSolver(Context* context);
  155. /// Default destructor.
  156. ~IKSolver() override;
  157. /// Registers this class to the context.
  158. static void RegisterObject(Context* context);
  159. /// Returns the active algorithm.
  160. /// @manualbind
  161. Algorithm GetAlgorithm() const;
  162. /*!
  163. * @manualbind
  164. * @brief Selects the solver algorithm. Default is FABRIK. Note that this
  165. * may not be the most efficient algorithm available. The specialized
  166. * solvers will be a lot faster.
  167. *
  168. * The currently supported solvers are listed below.
  169. * + **FABRIK**: This is a fairly new and highly efficient inverse
  170. * kinematic solving algorithm. It requires the least iterations to
  171. * reach its goal, it does not suffer from singularities (nearly no
  172. * violent snapping about), and it always converges.
  173. * + **2 Bone**: A specialized solver optimized for 2 bone problems (such
  174. * as a human leg)
  175. * + **1 Bone**: A specialized solver optimized for 1 bone problems (such
  176. * as a look-at target, e.g. eyes or a head)
  177. */
  178. void SetAlgorithm(Algorithm algorithm);
  179. /// Test if a certain feature is enabled (see IKSolver::Feature).
  180. /// @nobind
  181. bool GetFeature(Feature feature) const;
  182. /// Enable or disable a certain feature (see IKSolver::Feature).
  183. /// @nobind
  184. void SetFeature(Feature feature, bool enable);
  185. /// Returns the configured maximum number of iterations.
  186. /// @property
  187. unsigned GetMaximumIterations() const;
  188. /*!
  189. * @property
  190. * @brief Sets the maximum number of iterations the solver is allowed to
  191. * perform before applying the result.
  192. *
  193. * Depending on the algorithm, you may want higher or lower values.
  194. * FABRIK looks decent after only 10 iterations, whereas Jacobian based
  195. * methods often require more than a 100.
  196. *
  197. * The default value is 20.
  198. *
  199. * @note Most algorithms have a convergence criteria at which the solver
  200. * will stop iterating, so most of the time the maximum number of
  201. * iterations isn't even reached.
  202. *
  203. * @param[in] iterations Number of iterations. Must be greater than 0. Higher
  204. * values yield more accurate results, but at the cost of performance.
  205. */
  206. void SetMaximumIterations(unsigned iterations);
  207. /// Returns the configured tolerance.
  208. /// @property
  209. float GetTolerance() const;
  210. /*!
  211. * @property
  212. * @brief Sets the distance at which the effector is "close enough" to the
  213. * target node, at which point the algorithm will stop iterating.
  214. *
  215. * @param tolerance The distance to set. Smaller values yield more accurate
  216. * results, but at the cost of more iterations. Generally you'll want to
  217. * specify a number that is about 1/100th to 1/1000th of the total size of
  218. * the IK chain, e.g. if your human character has a leg that is 1 Urho3D
  219. * unit long, a good starting tolerance would be 0.01.
  220. */
  221. void SetTolerance(float tolerance);
  222. /*!
  223. * @brief Updates the solver's internal data structures, which is required
  224. * whenever the tree is modified in any way (e.g. adding or removing nodes,
  225. * adding or removing effectors, etc.).
  226. * @note This gets called automatically for you in Solve().
  227. */
  228. void RebuildChainTrees();
  229. /*!
  230. * @brief Unusual, but if you have a tree with translational motions such
  231. * that the distances between nodes changes (perhaps a slider?), you can
  232. * call this to recalculate the segment lengths after assigning new
  233. * positions to the nodes.
  234. * @note This function gets called by RebuildData() and by extension in
  235. * Solve().
  236. */
  237. void RecalculateSegmentLengths();
  238. /*!
  239. * @brief Skinned models require joint rotations to be calculated so
  240. * skinning works correctly. This is automatically enabled by default with
  241. * the feature flag JOINT_ROTATIONS.
  242. */
  243. void CalculateJointRotations();
  244. /*!
  245. * @brief Invokes the solver. The solution is applied back to the scene
  246. * graph automatically.
  247. * @note By default this is called automatically for you if the feature
  248. * flag AUTO_SOLVE is set. For more complex IK problems you can disable
  249. * that flag and call Solve() in response to E_SCENEDRAWABLEUPDATEFINISHED.
  250. * This is right after the animations have been applied.
  251. */
  252. void Solve();
  253. /*!
  254. * Copies the original pose into the scene graph. This will reset the pose
  255. * to whatever state it had when the IKSolver component was first created,
  256. * or, if the original pose was updated since then (for example if
  257. * Feature::UPDATE_ORIGINAL_POSE is set), will reset it to that state.
  258. */
  259. void ApplyOriginalPoseToScene();
  260. /*!
  261. * Copies the current scene graph data into the solvers original pose. You
  262. * generally won't need to call this, because it gets called for you
  263. * automatically if Feature::UPDATE_ORIGINAL_POSE is set.
  264. */
  265. void ApplySceneToOriginalPose();
  266. /*!
  267. * Copies the solvers current active pose into the scene graph. You
  268. * generally won't need to call this because it gets called for you
  269. * automatically in Solve(). This is used to apply the solution back to the
  270. * scene graph.
  271. */
  272. void ApplyActivePoseToScene();
  273. /*!
  274. * Copies the current scene graph data into the solvers active pose. You
  275. * generally won't need to call this because it gets called for you
  276. * automatically if Feature::UPDATE_ACTIVE_POSE is set.
  277. */
  278. void ApplySceneToActivePose();
  279. /*!
  280. * Copies the solvers original pose into the solvers active pose. This is
  281. * used in Solve() automatically if Feature::USE_ORIGINAL_POSE is set.
  282. */
  283. void ApplyOriginalPoseToActivePose();
  284. void DrawDebugGeometry(bool depthTest);
  285. void DrawDebugGeometry(DebugRenderer* debug, bool depthTest) override;
  286. private:
  287. friend class IKEffector;
  288. /// Indicates that the internal structures of the IK library need to be updated. See the documentation of ik_solver_rebuild_chain_trees() for more info on when this happens.
  289. void MarkChainsNeedUpdating();
  290. /// Indicates that the tree structure has changed in some way and needs updating (nodes added or removed, components added or removed).
  291. void MarkTreeNeedsRebuild();
  292. /// Returns false if calling Solve() would cause the IK library to abort. Urho3D's error handling philosophy is to log an error and continue, not crash.
  293. bool IsSolverTreeValid() const;
  294. /// Subscribe to drawable update finished event here.
  295. void OnSceneSet(Scene* scene) override;
  296. /// Destroys and creates the tree.
  297. void OnNodeSet(Node* node) override;
  298. /// Creates the ik library node and sets the current rotation/position and user data correctly.
  299. ik_node_t* CreateIKNodeFromUrhoNode(const Node* node);
  300. /// Destroys the solver's tree.
  301. void DestroyTree();
  302. /// Builds the solver's tree to match the scene graph's tree. If a tree already exists, it is first destroyed.
  303. void RebuildTree();
  304. /// Builds a chain of nodes up to the node of the specified effector component.
  305. bool BuildTreeToEffector(IKEffector* effector);
  306. /*!
  307. * Checks if the specified component is 1) attached to a node that is below
  308. * the one we are attached to and 2) isn't in the subtree of a child solver.
  309. * @note This will return false if the component is attached to our root
  310. * node, because in that case the solver can't do anything to it, it's in
  311. * the hands of a parent solver (if it exists).
  312. */
  313. bool ComponentIsInOurSubtree(Component* component) const;
  314. void HandleComponentAdded(StringHash eventType, VariantMap& eventData);
  315. void HandleComponentRemoved(StringHash eventType, VariantMap& eventData);
  316. void HandleNodeAdded(StringHash eventType, VariantMap& eventData);
  317. void HandleNodeRemoved(StringHash eventType, VariantMap& eventData);
  318. /// Invokes the IK solver.
  319. void HandleSceneDrawableUpdateFinished(StringHash eventType, VariantMap& eventData);
  320. // Need these wrapper functions flags of GetFeature/SetFeature can be correctly exposed to the editor and to AngelScript and lua
  321. public:
  322. /// @property{get_JOINT_ROTATIONS}
  323. bool GetJOINT_ROTATIONS() const;
  324. /// @property{get_TARGET_ROTATIONS}
  325. bool GetTARGET_ROTATIONS() const;
  326. /// @property{get_UPDATE_ORIGINAL_POSE}
  327. bool GetUPDATE_ORIGINAL_POSE() const;
  328. /// @property{get_UPDATE_ACTIVE_POSE(}
  329. bool GetUPDATE_ACTIVE_POSE() const;
  330. /// @property{get_USE_ORIGINAL_POSE}
  331. bool GetUSE_ORIGINAL_POSE() const;
  332. /// @property{get_CONSTRAINTS}
  333. bool GetCONSTRAINTS() const;
  334. /// @property{get_AUTO_SOLVE}
  335. bool GetAUTO_SOLVE() const;
  336. /// @property{set_JOINT_ROTATIONS}
  337. void SetJOINT_ROTATIONS(bool enable);
  338. /// @property{set_TARGET_ROTATIONS}
  339. void SetTARGET_ROTATIONS(bool enable);
  340. /// @property{set_UPDATE_ORIGINAL_POSE}
  341. void SetUPDATE_ORIGINAL_POSE(bool enable);
  342. /// @property{set_UPDATE_ACTIVE_POSE}
  343. void SetUPDATE_ACTIVE_POSE(bool enable);
  344. /// @property{set_USE_ORIGINAL_POSE}
  345. void SetUSE_ORIGINAL_POSE(bool enable);
  346. /// @property{set_CONSTRAINTS}
  347. void SetCONSTRAINTS(bool enable);
  348. /// @property{set_AUTO_SOLVE}
  349. void SetAUTO_SOLVE(bool enable);
  350. private:
  351. PODVector<IKEffector*> effectorList_;
  352. PODVector<IKConstraint*> constraintList_;
  353. ik_solver_t* solver_;
  354. Algorithm algorithm_;
  355. unsigned features_;
  356. bool chainTreesNeedUpdating_;
  357. bool treeNeedsRebuild;
  358. bool solverTreeValid_;
  359. };
  360. } // namespace Urho3D