1 #ifndef IK_SOLVER_H 2 #define IK_SOLVER_H 3 4 #include "ik/config.h" 5 #include "ik/chain_tree.h" 6 #include "ik/ordered_vector.h" 7 #include "ik/quat.h" 8 #include "ik/vec3.h" 9 10 C_HEADER_BEGIN 11 12 typedef void (*ik_solver_destruct_func)(ik_solver_t*); 13 typedef int (*ik_solver_post_chain_build_func)(ik_solver_t*); 14 typedef int (*ik_solver_solve_func)(ik_solver_t*); 15 16 typedef void (*ik_solver_iterate_node_cb_func)(ik_node_t*); 17 18 typedef enum solver_algorithm_e 19 { 20 SOLVER_ONE_BONE, 21 SOLVER_TWO_BONE, 22 SOLVER_FABRIK, 23 SOLVER_MSD 24 /* TODO Not implemented 25 SOLVER_JACOBIAN_INVERSE, 26 SOLVER_JACOBIAN_TRANSPOSE */ 27 } solver_algorithm_e; 28 29 typedef enum solver_flags_e 30 { 31 /*! 32 * @brief Causes the root node in the tree to be excluded from the list of 33 * nodes to solve for. It won't be affected by the solver, but it may still 34 * be passed through to the result callback function. 35 */ 36 SOLVER_EXCLUDE_ROOT = 0x01, 37 38 SOLVER_ENABLE_CONSTRAINTS = 0x02, 39 40 SOLVER_CALCULATE_TARGET_ROTATIONS = 0x04 41 } solver_flags_e; 42 43 /*! 44 * @brief This is a base for all solvers. 45 */ 46 #define SOLVER_DATA_HEAD \ 47 int32_t max_iterations; \ 48 float tolerance; \ 49 uint8_t flags; \ 50 \ 51 /* Derived structure callbacks */ \ 52 ik_solver_destruct_func destruct; \ 53 ik_solver_post_chain_build_func post_chain_build; \ 54 ik_solver_solve_func solve; \ 55 \ 56 ordered_vector_t effector_nodes_list; \ 57 ik_node_t* tree; \ 58 /* list of ik_chain_tree_t objects (allocated in-place) */ \ 59 chain_tree_t chain_tree; 60 61 struct ik_solver_t 62 { 63 SOLVER_DATA_HEAD 64 }; 65 66 /*! 67 * @brief Allocates a new solver object according to the specified algorithm. 68 * 69 * Once the solver is created, you can configure the solver to enable/disable 70 * various features depending on your needs. 71 * 72 * The following attributes can be changed at any point. 73 * + solver->apply_result 74 * This is the main mechanism with which to obtain the solved data. 75 * Assign a callback function here and it will be called for every node 76 * in the tree when a new target position/rotation has been calculated. 77 * You can use the node->user_data attribute to store external node 78 * specific data, which can be accessed again the in callback function. 79 * + solver->max_iterations 80 * Specifies the maximum number of iterations. The more iterations, the 81 * more exact the result will be. The default value for the FABRIK solver 82 * is 20, but you can get away with values as low as 5. 83 * + solver->tolerance 84 * This value can be changed at any point. Specifies the acceptable 85 * distance each effector needs to be to its target position. The solver 86 * will stop iterating if the effectors are within this distance. The 87 * default value is 1e-3. Recommended values are 100th of your world 88 * unit. 89 * + solver->flags 90 * Changes the behaviour of the solver. See the enum solver_flags_e for 91 * more information. 92 * 93 * The following attributes can be accessed (read from) but should not be 94 * modified. 95 * + solver->tree 96 * The tree to be solved. You may modify the nodes in the tree. 97 * @note If you add/remove nodes or if you add/remove effectors, you 98 * must call ik_solver_rebuild_data() so the internal solver structures 99 * are updated. Failing to do so may cause segfaults. If you're just 100 * updating positions/rotations or any of the other public data then 101 * there is no need to rebuild data. 102 * + solver->effector_nodes_list 103 * A vector containing pointers to nodes in the tree which have an 104 * effector attached to them. You may not modify this list, but you may 105 * iterate it. 106 * @param[in] algorithm The algorithm to use. Currently, only FABRIK is 107 * supported. 108 */ 109 IK_PUBLIC_API ik_solver_t* 110 ik_solver_create(solver_algorithm_e algorithm); 111 112 /*! 113 * @brief Destroys the solver and all nodes/effectors that are part of the 114 * solver. Any pointers to tree nodes are invalid after this function returns. 115 */ 116 IK_PUBLIC_API void 117 ik_solver_destroy(ik_solver_t* solver); 118 119 /*! 120 * @brief Sets the tree to solve. The solver takes ownership of the tree, so 121 * destroying the solver will destroy all nodes in the tree. Note that you will 122 * have to call ik_solver_rebuild_data() before being able to solve it. If the 123 * solver already has a tree, then said tree will be destroyed. 124 */ 125 IK_PUBLIC_API void 126 ik_solver_set_tree(ik_solver_t* solver, ik_node_t* root); 127 128 /*! 129 * @brief The solver releases any references to a previously set tree and 130 * returns the root node of said tree. Any proceeding calls that involve the 131 * tree (e.g. solve or rebuild) will have no effect until a new tree is set. 132 * @return If the solver has no tree then NULL is returned. 133 */ 134 IK_PUBLIC_API ik_node_t* 135 ik_solver_unlink_tree(ik_solver_t* solver); 136 137 /*! 138 * @brief The solver releases any references to a previously set tree and 139 * destroys it. 140 */ 141 IK_PUBLIC_API void 142 ik_solver_destroy_tree(ik_solver_t* solver); 143 144 /*! 145 * @brief Causes the set tree to be processed into more optimal data structures 146 * for solving. Must be called before ik_solver_solve(). 147 * @note Needs to be called whenever the tree changes in any way. I.e. if you 148 * remove nodes or add nodes, or if you remove effectors or add effectors, 149 * you must call this again before calling the solver. 150 * @return Returns non-zero if any of the chain trees are invalid for any 151 * reason. If this happens, check the log for error messages. 152 * @warning If this functions fails, the internal structures are in an 153 * undefined state. You cannot solve the tree in this state. 154 */ 155 IK_PUBLIC_API int 156 ik_solver_rebuild_chain_trees(ik_solver_t* solver); 157 158 /*! 159 * @brief Unusual, but if you have a tree with translational motions such that 160 * the distances between nodes changes (perhaps a slider?), you can call this 161 * to re-calculate the segment lengths after assigning new positions to the 162 * nodes. 163 * @note This function gets called by ik_solver_rebuild_data(). 164 */ 165 IK_PUBLIC_API void 166 ik_solver_recalculate_segment_lengths(ik_solver_t* solver); 167 168 /*! 169 * @brief Solves the IK problem. The node solutions will be provided via a 170 * callback function, which can be registered to the solver by assigning it to 171 * solver->apply_result. 172 */ 173 IK_PUBLIC_API int 174 ik_solver_solve(ik_solver_t* solver); 175 176 IK_PUBLIC_API void 177 ik_solver_calculate_joint_rotations(ik_solver_t* solver); 178 179 /*! 180 * @brief Iterates all nodes in the internal tree, breadth first, and passes 181 * each node to the specified callback function. 182 */ 183 IK_PUBLIC_API void 184 ik_solver_iterate_tree(ik_solver_t* solver, 185 ik_solver_iterate_node_cb_func callback); 186 187 /*! 188 * @brief Iterates just the nodes that are being affected by the solver. Useful 189 * for a more optimized write-back of the solution data. 190 */ 191 IK_PUBLIC_API void 192 ik_solver_iterate_chain_tree(ik_solver_t* solver, 193 ik_solver_iterate_node_cb_func callback); 194 195 /*! 196 * @brief Sets the solved positions and rotations equal to the original 197 * positions and rotations for every node in the tree. 198 */ 199 IK_PUBLIC_API void 200 ik_solver_reset_to_original_pose(ik_solver_t* solver); 201 202 C_HEADER_END 203 204 #endif /* IK_SOLVER_H */ 205