sanim.h (7585B)
1 /* Copyright (C) 2018-2026 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2016-2018 CNRS 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifndef SANIM_H 18 #define SANIM_H 19 20 #include <rsys/rsys.h> 21 #include <rsys/dynamic_array.h> 22 23 /* Library symbol management */ 24 #if defined(SANIM_SHARED_BUILD) /* Build shared library */ 25 #define SANIM_API extern EXPORT_SYM 26 #elif defined(SANIM_STATIC) /* Use/build static library */ 27 #define SANIM_API extern LOCAL_SYM 28 #else /* Use shared library */ 29 #define SANIM_API extern IMPORT_SYM 30 #endif 31 32 /* Helper macro that asserts if the invocation of the Solstice Anim function 33 * `Func' returns an error. One should use this macro on Solstice Anim function 34 * calls for which no explicit error checking is performed */ 35 #ifndef NDEBUG 36 #define SANIM(Func) ASSERT(sanim_ ## Func == RES_OK) 37 #else 38 #define SANIM(Func) sanim_ ## Func 39 #endif 40 41 /* Syntactic sugar used to inform the Solstice Anim library that it can use 42 * as many threads as CPU cores */ 43 #define SANIM_NTHREADS_DEFAULT (~0u) 44 45 /* Forward declaration of external types */ 46 struct logger; 47 struct mem_allocator; 48 struct node_data; 49 50 /* sanim_node type for building own node types */ 51 struct sanim_node { 52 struct node_data* data; 53 }; 54 #define SANIM_NODE_NULL__ { NULL } 55 static const struct sanim_node SANIM_NODE_NULL = SANIM_NODE_NULL__; 56 57 /* types to describe pivots */ 58 enum sanim_pivot_type { 59 PIVOT_SINGLE_AXIS, 60 PIVOT_TWO_AXIS, 61 62 PIVOT_TYPES_COUNT__ 63 }; 64 65 /* pivot with X rotation axis */ 66 struct sanim_pivot_1 { 67 double ref_point[3]; /* in post-pivot local space */ 68 double ref_normal[3]; /* normal without rotation; used to compute output dir */ 69 }; 70 #define SANIM_PIVOT1_DEFAULT__ { {0,0,0}, {0,0,1} } 71 static const struct sanim_pivot_1 SANIM_PIVOT1_DEFAULT = SANIM_PIVOT1_DEFAULT__; 72 73 /* pivot with Z then X rotation axis */ 74 struct sanim_pivot_2 { 75 double spacing; /* distance between Z and X rotation axis */ 76 double ref_point[3]; /* in post-pivot local space */ 77 /* ref_normal is <0,1,0> */ 78 }; 79 #define SANIM_PIVOT2_DEFAULT__ { 0, {0,0,0} } 80 static const struct sanim_pivot_2 SANIM_PIVOT2_DEFAULT = SANIM_PIVOT2_DEFAULT__; 81 82 struct sanim_pivot { 83 enum sanim_pivot_type type; 84 union { 85 struct sanim_pivot_1 pivot1; 86 struct sanim_pivot_2 pivot2; 87 } data; 88 }; 89 #define SANIM_PIVOT_NULL__ { PIVOT_TYPES_COUNT__, {SANIM_PIVOT1_DEFAULT__} } 90 static const struct sanim_pivot SANIM_PIVOT_NULL = SANIM_PIVOT_NULL__; 91 92 /* types to describe tracking policies */ 93 enum sanim_tracking_policy { 94 TRACKING_SUN, /* orient the device to face the sun */ 95 TRACKING_POINT, /* direct the output flux towards a point */ 96 TRACKING_NODE_TARGET, /* direct the output flux towards a ponctual animated target */ 97 TRACKING_OUT_DIR, /* direct the output flux towards a given dir */ 98 99 TRACKING_POLICIES_COUNT 100 }; 101 102 struct sanim_policy_point { 103 /* target can be in local space (ie in the same system than the pivot) 104 * or in world space */ 105 double target[3]; 106 char target_is_local; 107 }; 108 #define SANIM_POINT_POLICY_DEFAULT__ { {0,0,0}, 0 } 109 static const struct sanim_policy_point SANIM_POINT_POLICY_DEFAULT = 110 SANIM_POINT_POLICY_DEFAULT__; 111 112 struct sanim_policy_node_target { 113 const void* tracked_node; 114 }; 115 #define SANIM_NODE_TARGET_POLICY_NULL__ { NULL } 116 static const struct sanim_policy_node_target SANIM_NODE_TARGET_POLICY_NULL = 117 SANIM_NODE_TARGET_POLICY_NULL__; 118 119 struct sanim_policy_out_dir { 120 double u[3]; /* in world space */ 121 }; 122 #define SANIM_OUT_DIR_POLICY_DEFAULT__ { {0,0,0} } 123 static const struct sanim_policy_out_dir SANIM_OUT_DIR_POLICY_DEFAULT = 124 SANIM_OUT_DIR_POLICY_DEFAULT__; 125 126 127 struct sanim_tracking { 128 enum sanim_tracking_policy policy; 129 union { 130 struct sanim_policy_point point; 131 struct sanim_policy_node_target node_target; 132 struct sanim_policy_out_dir out_dir; 133 } data; 134 }; 135 #define SANIM_TRACKING_NULL__ \ 136 { TRACKING_POLICIES_COUNT, {SANIM_POINT_POLICY_DEFAULT__} } 137 static const struct sanim_tracking SANIM_TRACKING_NULL = SANIM_TRACKING_NULL__; 138 139 BEGIN_DECLS 140 141 /******************************************************************************* 142 * Node API. 143 ******************************************************************************/ 144 SANIM_API res_T 145 sanim_node_initialize 146 (struct mem_allocator* allocator, 147 struct sanim_node* node); 148 149 SANIM_API res_T 150 sanim_node_initialize_pivot 151 (struct mem_allocator* allocator, 152 const struct sanim_pivot* pivot, 153 const struct sanim_tracking* tracking, 154 struct sanim_node* node); 155 156 /* simple copy, no recursion 157 * copy rotations, translation and possible pivot information */ 158 SANIM_API res_T 159 sanim_node_copy_initialize 160 (struct mem_allocator* allocator, 161 const struct sanim_node* src, 162 struct sanim_node* dst); 163 164 SANIM_API res_T 165 sanim_node_is_initialized 166 (const struct sanim_node* node, 167 int* initialized); 168 169 SANIM_API res_T 170 sanim_node_solve_pivot 171 (struct sanim_node* node, 172 const double in_dir[3]); 173 174 /* Visit the (sub)tree starting at `node'. Solve pivots if any (an ancestor 175 * pivot would not be solved/updated) and if `in_dir' is not NULL. Call 176 * `visitor' on every node of the tree with its updated transform Visit stops 177 * if a call to visitor return is not RES_OK */ 178 SANIM_API res_T 179 sanim_node_visit_tree 180 (struct sanim_node* node, 181 const double in_dir[3], /* May be NULL <=> do not solve pivot */ 182 void* data, 183 res_T (*visitor) 184 (const struct sanim_node* n, const double transform[12], void* data)); 185 186 /* Visit the (sub)tree starting at node and call cmp on the nodes 187 * Stop if found is set to non-zero or if a call to cmp return is not RES_OK */ 188 SANIM_API res_T 189 sanim_node_search_tree 190 (const struct sanim_node* node, 191 void* data, 192 res_T(*cmp)(const struct sanim_node* n, void* data, int* found), 193 int* found); 194 195 SANIM_API res_T 196 sanim_node_track_me 197 (const struct sanim_node* node, 198 struct sanim_tracking* tracking); 199 200 SANIM_API res_T 201 sanim_node_release 202 (struct sanim_node* node); 203 204 SANIM_API res_T 205 sanim_node_add_child 206 (struct sanim_node* father, 207 struct sanim_node* child); 208 209 SANIM_API res_T 210 sanim_node_set_translation 211 (struct sanim_node* node, 212 const double translation[3]); 213 214 SANIM_API res_T 215 sanim_node_get_translation 216 (const struct sanim_node* node, 217 double translation[3]); 218 219 SANIM_API res_T 220 sanim_node_set_rotations 221 (struct sanim_node* node, 222 const double rotations[3]); /* XYZ convention */ 223 224 SANIM_API res_T 225 sanim_node_get_rotations 226 (const struct sanim_node* node, 227 double rotations[3]); 228 229 SANIM_API res_T 230 sanim_node_get_transform 231 (const struct sanim_node* node, 232 double transform[12]); /* 3x4 column major matrix */ 233 234 SANIM_API res_T 235 sanim_node_get_father 236 (const struct sanim_node* node, 237 const struct sanim_node** father); 238 239 SANIM_API res_T 240 sanim_node_get_children_count 241 (const struct sanim_node* node, 242 size_t* count); 243 244 SANIM_API res_T 245 sanim_node_get_child 246 (const struct sanim_node* node, 247 const size_t idx, 248 struct sanim_node** child); 249 250 SANIM_API res_T 251 sanim_node_is_pivot 252 (const struct sanim_node* node, 253 int* pivot); 254 255 END_DECLS 256 257 #endif /* SANIM_H */