solstice_node.c (6895B)
1 /* Copyright (C) 2018-2026 |Meso|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 #include "solstice_c.h" 18 #include <solstice/ssol.h> 19 20 /******************************************************************************* 21 * Helper functions 22 ******************************************************************************/ 23 static res_T 24 node_create 25 (struct mem_allocator* allocator, 26 const enum solstice_node_type type, 27 struct solstice_node** out_node) 28 { 29 struct solstice_node* node = NULL; 30 res_T res = RES_OK; 31 ASSERT(allocator && out_node && type < SOLSTICE_NODE_TYPES_COUNT__); 32 33 node = MEM_CALLOC(allocator, 1, sizeof(struct solstice_node)); 34 if(!node) { 35 fprintf(stderr, "Could not allocate a Solstice node.\n"); 36 res = RES_MEM_ERR; 37 goto error; 38 } 39 40 ref_init(&node->ref); 41 str_init(allocator, &node->name); 42 node->type = type; 43 node->anim = SANIM_NODE_NULL; 44 node->allocator = allocator; 45 46 exit: 47 if(out_node) *out_node = node; 48 return res; 49 error: 50 if(node) { 51 solstice_node_ref_put(node); 52 node = NULL; 53 } 54 goto exit; 55 } 56 57 static void 58 node_release(ref_T* ref) 59 { 60 struct solstice_node* node; 61 int is_init; 62 ASSERT(ref); 63 64 node = CONTAINER_OF(ref, struct solstice_node, ref); 65 if(node->instance) SSOL(instance_ref_put(node->instance)); 66 str_release(&node->name); 67 68 SANIM(node_is_initialized(&node->anim, &is_init)); 69 if(is_init) { 70 size_t i, n; 71 SANIM(node_get_children_count(&node->anim, &n)); 72 FOR_EACH(i, 0, n) { 73 struct sanim_node* child_anim; 74 struct solstice_node* child; 75 SANIM(node_get_child(&node->anim, i, &child_anim)); 76 child = CONTAINER_OF(child_anim, struct solstice_node, anim); 77 solstice_node_ref_put(child); 78 } 79 SANIM(node_release(&node->anim)); 80 } 81 MEM_RM(node->allocator, node); 82 } 83 84 /******************************************************************************* 85 * Exported functions 86 ******************************************************************************/ 87 res_T 88 solstice_node_geometry_create 89 (struct mem_allocator* allocator, 90 struct ssol_instance* instance, 91 struct solstice_node** out_node) 92 { 93 struct solstice_node* node = NULL; 94 res_T res = RES_OK; 95 ASSERT(allocator && instance && out_node); 96 97 res = node_create(allocator, SOLSTICE_NODE_GEOMETRY, &node); 98 if(res != RES_OK) goto error; 99 100 res = sanim_node_initialize(allocator, &node->anim); 101 if(res != RES_OK) { 102 fprintf(stderr, 103 "Could not initialize the anim field of a Solstice geometry node.\n"); 104 goto error; 105 } 106 107 SSOL(instance_ref_get(instance)); 108 node->instance = instance; 109 110 exit: 111 *out_node = node; 112 return res; 113 error: 114 if(node) { 115 solstice_node_ref_put(node); 116 node = NULL; 117 } 118 goto exit; 119 } 120 121 res_T 122 solstice_node_empty_create 123 (struct mem_allocator* allocator, 124 struct solstice_node** out_node) 125 { 126 struct solstice_node* node = NULL; 127 res_T res = RES_OK; 128 ASSERT(allocator && out_node); 129 130 res = node_create(allocator, SOLSTICE_NODE_EMPTY, &node); 131 if(res != RES_OK) goto error; 132 133 res = sanim_node_initialize(allocator, &node->anim); 134 if(res != RES_OK) { 135 fprintf(stderr, 136 "Could not initialize the anim field of a Solstice empty node.\n"); 137 goto error; 138 } 139 140 exit: 141 *out_node = node; 142 return res; 143 error: 144 if(node) { 145 solstice_node_ref_put(node); 146 node = NULL; 147 } 148 goto exit; 149 } 150 151 res_T 152 solstice_node_pivot_create 153 (struct mem_allocator* allocator, 154 const struct sanim_pivot* pivot, 155 const struct sanim_tracking* tracking, 156 struct solstice_node** out_node) 157 { 158 struct solstice_node* node = NULL; 159 res_T res = RES_OK; 160 ASSERT(allocator && pivot && tracking && out_node); 161 162 res = node_create(allocator, SOLSTICE_NODE_PIVOT, &node); 163 if(res != RES_OK) goto error; 164 165 res = sanim_node_initialize_pivot(allocator, pivot, tracking, &node->anim); 166 if(res != RES_OK) { 167 fprintf(stderr, 168 "Could not initialize the anim field of a Solstice pivot node.\n"); 169 goto error; 170 } 171 172 exit: 173 *out_node = node; 174 return res; 175 error: 176 if(node) { 177 solstice_node_ref_put(node); 178 node = NULL; 179 } 180 goto exit; 181 } 182 183 res_T 184 solstice_node_target_create 185 (struct mem_allocator* allocator, 186 struct solstice_node** out_node) 187 { 188 struct solstice_node* node = NULL; 189 res_T res = RES_OK; 190 ASSERT(allocator && out_node); 191 192 res = node_create(allocator, SOLSTICE_NODE_TARGET, &node); 193 if(res != RES_OK) goto error; 194 195 res = sanim_node_initialize(allocator, &node->anim); 196 if(res != RES_OK) { 197 fprintf(stderr, 198 "Could not initialize the anim field of a Solstice target node.\n"); 199 goto error; 200 } 201 202 exit: 203 *out_node = node; 204 return res; 205 error: 206 if(node) { 207 solstice_node_ref_put(node); 208 node = NULL; 209 } 210 goto exit; 211 } 212 213 void 214 solstice_node_ref_get(struct solstice_node* node) 215 { 216 ASSERT(node); 217 ref_get(&node->ref); 218 } 219 220 void 221 solstice_node_ref_put(struct solstice_node* node) 222 { 223 ASSERT(node); 224 ref_put(&node->ref, node_release); 225 } 226 227 res_T 228 solstice_node_set_name(struct solstice_node* node, const char* name) 229 { 230 ASSERT(node); 231 return str_set(&node->name, name); 232 } 233 234 const char* 235 solstice_node_get_name(const struct solstice_node* node) 236 { 237 ASSERT(node); 238 return str_cget(&node->name); 239 } 240 241 res_T 242 solstice_node_geometry_set_primary 243 (struct solstice_node* node, const int is_primary) 244 { 245 ASSERT(node && (!is_primary || node->type == SOLSTICE_NODE_GEOMETRY)); 246 return ssol_instance_sample(node->instance, is_primary); 247 } 248 249 res_T 250 solstice_node_geometry_set_receiver 251 (struct solstice_node* node, const int mask, const int per_primitive) 252 { 253 ASSERT(node && node->type == SOLSTICE_NODE_GEOMETRY); 254 return ssol_instance_set_receiver(node->instance, mask, per_primitive); 255 } 256 257 void 258 solstice_node_target_get_tracking 259 (const struct solstice_node* node, 260 struct sanim_tracking* tracking) 261 { 262 ASSERT(node && tracking && node->type == SOLSTICE_NODE_TARGET); 263 SANIM(node_track_me(&node->anim, tracking)); 264 } 265 266 res_T 267 solstice_node_add_child(struct solstice_node* node, struct solstice_node* child) 268 { 269 res_T res = RES_OK; 270 ASSERT(node && child && node->type != SOLSTICE_NODE_TARGET); 271 res = sanim_node_add_child(&node->anim, &child->anim); 272 if(res != RES_OK) { 273 fprintf(stderr, "Could not add a child node.\n"); 274 return res; 275 } 276 solstice_node_ref_get(child); 277 return RES_OK; 278 } 279