diff options
Diffstat (limited to 'src/geometry/geometry.c')
-rw-r--r-- | src/geometry/geometry.c | 104 |
1 files changed, 93 insertions, 11 deletions
diff --git a/src/geometry/geometry.c b/src/geometry/geometry.c index ea04fd3..78fbaea 100644 --- a/src/geometry/geometry.c +++ b/src/geometry/geometry.c @@ -12,6 +12,14 @@ if (strcmp(src->type, expected) != 0) { \ return -1; \ } +/* helper macro for iterating over tag children of a particular type */ +#define FOR_CHILD_OF_TYPE(parent, child, type) \ +for ( \ + child = kai_tag_get_first_child_with_type(parent, type); \ + child != NULL; \ + child = kai_tag_get_next_sibling_with_type(child, type) \ +) + int kai_read_float_array(struct ka_float_array_t *dest, struct kai_tag_t *src) { @@ -219,8 +227,8 @@ int kai_read_vertices(struct ka_vertices_t *dest, struct kai_tag_t *src) /* count input children */ int count = 0; struct kai_tag_t *child; - for (child = src->children; child != NULL; child = child->next) { - if (strcmp(child->type, "input") == 0) { count += 1; } + FOR_CHILD_OF_TYPE(src, child, "input") { + count += 1; } dest->input_count = count; @@ -231,16 +239,14 @@ int kai_read_vertices(struct ka_vertices_t *dest, struct kai_tag_t *src) } int i=0; - for (child = src->children; child != NULL; child = child->next) { - if (strcmp(child->type, "input") == 0) { - int result = kai_read_input_unshared(dest->input + i, child); - if (result != 0) { - dest->input_count = i; - kai_release_vertices(*dest); - return -1; - } - i += 1; + FOR_CHILD_OF_TYPE(src, child, "input") { + int result = kai_read_input_unshared(dest->input + i, child); + if (result != 0) { + dest->input_count = i; + kai_release_vertices(*dest); + return -1; } + i += 1; } return 0; @@ -258,3 +264,79 @@ void kai_release_vertices(struct ka_vertices_t v) } +int kai_read_triangles(struct ka_triangles_t *dest, struct kai_tag_t *src) +{ + CHECK_TAG_TYPE("triangles"); + + long count = kai_tag_attr_to_long(src, "count", -1); + if (count == -1) { return -1; } + + dest->name = kai_tag_attr_to_dup(src, "name"); + dest->count = count; + dest->material = kai_tag_attr_to_dup(src, "material"); + + + /* zero these out so that any error-related calls to kai_release_triangles + * won't cause an invalid free + */ + dest->input_count = 0; + dest->input = NULL; + dest->p_count = 0; + dest->p = NULL; + + /* load the child inputs into the structure */ + int input_count = 0; + struct kai_tag_t *child; + FOR_CHILD_OF_TYPE(src, child, "input") { + input_count += 1; + } + + dest->input = kai_alloc(input_count * sizeof(struct ka_input_t), "triangles input array"); + if (dest->input == NULL) { + kai_release_triangles(*dest); + return -1; + } + + int i=0; + FOR_CHILD_OF_TYPE(src, child, "input") { + int result = kai_read_input_shared(dest->input + i, child); + if (result != 0) { + dest->input_count = i; + kai_release_triangles(*dest); + return -1; + } + i += 1; + } + dest->input_count = input_count; + + + /* load the child p tag */ + struct kai_tag_t *p = kai_tag_get_first_child_with_type(src, "p"); + if (p != NULL) { + dest->p_count = 3 * dest->count * dest->input_count; + dest->p = kai_alloc(dest->p_count * sizeof(unsigned int), "triangles primitive array"); + if (dest->p == NULL) { + dest->p_count = 0; + kai_release_triangles(*dest); + return -1; + } + kai_text_to_uints(dest->p, p->content, dest->p_count); + } + + return 0; +} + +void kai_release_triangles(struct ka_triangles_t t) +{ + free(t.name); + free(t.material); + + int i; + for (i=0; i<t.input_count; i++) { + kai_release_input(t.input[i]); + } + free(t.input); + free(t.p); +} + + |