node.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #ifndef IK_NODE_H
  2. #define IK_NODE_H
  3. #include "ik/config.h"
  4. #include "ik/bst_vector.h"
  5. #include "ik/vec3.h"
  6. #include "ik/quat.h"
  7. C_HEADER_BEGIN
  8. struct ik_effector_t;
  9. /*!
  10. * @brief Represents one node in the tree to be solved.
  11. */
  12. struct ik_node_t
  13. {
  14. /*!
  15. * @brief Allows the user of this library to store custom data per node
  16. * @note Can be set and retrieved directly without issue.
  17. *
  18. * This is especially useful in c++ applications which need to store the
  19. * "this" pointer to their own scene graph nodes. The user data can be
  20. * accessed in callback functions to make object calls again.
  21. *
  22. * For instance:
  23. * ```cpp
  24. * // A node in your scene graph
  25. * MyNode* node = GetMyNode();
  26. *
  27. * struct ik_solver_t* solver = ik_solver_create(SOLVER_FABRIK);
  28. * struct ik_node_t* ikNode = ik_node_create(node->GetID());
  29. * ikNode->user_data = node; // Store pointer to your own node object
  30. *
  31. * // ---- elsewhere ------
  32. * static void ApplyResultsCallback(ik_node_t* ikNode)
  33. * {
  34. * Node* node = (Node*)ikNode->user_data; // Extract your own node object again
  35. * node->SetPosition(ikNode->solved_position);
  36. * }
  37. * ```
  38. */
  39. void* user_data;
  40. /*!
  41. * @brief The initial global position (in world space).
  42. * @note Must be set by the user to get correct results. This value can
  43. * be set and retrieved at any time.
  44. * @note The default value is (0, 0, 0).
  45. */
  46. vec3_t position;
  47. /*!
  48. * @brief The initial global rotation (in world space).
  49. * @note Must be set by the user to get correct results if the solver has
  50. * angle computations enabled (SOLVER_CALCULATE_FINAL_ANGLES).
  51. * @note The default value is the identity quaternion.
  52. */
  53. quat_t rotation;
  54. /*!
  55. * @brief Global identifier for this node. The identifier must be unique
  56. * within the tree, but separate trees may re-use the same IDs again. The
  57. * ID can later be used to retrieve nodes from the tree again.
  58. */
  59. uint32_t guid;
  60. /*!
  61. * @brief After the solver is executed, the solved global (world) position
  62. * is stored here and can be retrieved.
  63. */
  64. vec3_t solved_position;
  65. /*!
  66. * @brief After the solver is executed, the solved global (world) rotation
  67. * is stored here and can be retrieved.
  68. */
  69. quat_t solved_rotation;
  70. /*!
  71. * @brief The end effector object.
  72. * @note This pointer should not be changed directly. You can however set
  73. * the target position/rotation of the effector by writing to
  74. * node->effector->target_position or node->effector->target_rotation.
  75. * @note May be NULL.
  76. */
  77. struct ik_effector_t* effector;
  78. /* Private data */
  79. ik_real segment_length;
  80. struct ik_node_t* parent;
  81. struct bstv_t children;
  82. };
  83. /*!
  84. * @brief Creates a new node and returns it. Each node requires a tree-unique
  85. * ID, which can be used later to search for nodes in the tree.
  86. */
  87. IK_PUBLIC_API struct ik_node_t*
  88. ik_node_create(uint32_t guid);
  89. /*!
  90. * @brief Constructs an already allocated node.
  91. */
  92. IK_PUBLIC_API void
  93. ik_node_construct(struct ik_node_t* node, uint32_t guid);
  94. /*!
  95. * @brief Destructs a node, destroying all children in the process, but does
  96. * not deallocate the node object itself.
  97. */
  98. IK_PUBLIC_API void
  99. ik_node_destruct(struct ik_node_t* node);
  100. /*!
  101. * @brief Destructs and frees the node, destroying all children in the process.
  102. * If the node was part of a tree, then it will be removed from its parents.
  103. * @note You will need to rebuild the solver's tree before solving.
  104. */
  105. IK_PUBLIC_API void
  106. ik_node_destroy(struct ik_node_t* node);
  107. /*!
  108. * @brief Attaches a node as a child to another node. The parent node gains
  109. * ownership of the child node and is responsible for deallocating it.
  110. * @note You will need to rebuild the solver's tree before solving.
  111. */
  112. IK_PUBLIC_API void
  113. ik_node_add_child(struct ik_node_t* node, struct ik_node_t* child);
  114. /*!
  115. * @brief Unlinks a node from the tree, without destroying anything. All
  116. * children of the unlinked node remain in tact and will no longer be
  117. * affiliated with the original tree.
  118. * @note You will need to rebuild the solver's tree before solving.
  119. */
  120. IK_PUBLIC_API void
  121. ik_node_unlink(struct ik_node_t* node);
  122. /*!
  123. * @brief Searches recursively for a node in a tree with the specified global
  124. * identifier.
  125. * @return Returns NULL if the node was not found, otherwise the node is
  126. * returned.
  127. */
  128. IK_PUBLIC_API struct ik_node_t*
  129. ik_node_find_child(struct ik_node_t* node, uint32_t guid);
  130. /*!
  131. * @brief Attaches an effector object to the node. The node gains ownership
  132. * of the effector and is responsible for its deallocation. If the node
  133. * already owns an effector, then it is first destroyed.
  134. * @note You will need to rebuild the solver's tree before solving.
  135. */
  136. IK_PUBLIC_API void
  137. ik_node_attach_effector(struct ik_node_t* node, struct ik_effector_t* effector);
  138. /*!
  139. * @brief Removes and destroys the node's effector, if it exists. The attribute
  140. * node->effector is set to NULL.
  141. * @note You will need to rebuild the solver's tree before solving.
  142. */
  143. IK_PUBLIC_API void
  144. ik_node_destroy_effector(struct ik_node_t* node);
  145. /*!
  146. * @brief Dumps all nodes recursively to DOT format. You can use graphviz (
  147. * or other compatible tools) to generate a graphic of the tree.
  148. */
  149. IK_PUBLIC_API void
  150. ik_node_dump_to_dot(struct ik_node_t* node, const char* file_name);
  151. C_HEADER_END
  152. #endif /* IK_NODE_H */