nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@1: #include nuclear@1: #include nuclear@0: #include "mesh.h" nuclear@1: #include "dynarr.h" nuclear@0: nuclear@1: nuclear@1: struct mesh_vertattr { nuclear@1: char *name; nuclear@1: void *data; nuclear@1: int elem_sz; nuclear@1: }; nuclear@1: nuclear@1: struct mesh_polyidx { nuclear@1: int *data; nuclear@1: }; nuclear@1: nuclear@1: struct mesh { nuclear@1: char *name; nuclear@1: int poly_nverts; /* 3, 4, etc */ nuclear@1: nuclear@1: struct mesh_vertattr *attr; nuclear@1: struct mesh_polyidx *polyidx; nuclear@1: }; nuclear@1: nuclear@1: nuclear@1: /* --- vertex attributes --- */ nuclear@1: nuclear@1: int vattr_init(struct mesh_vertattr *ma, int elem_sz) nuclear@0: { nuclear@1: ma->name = 0; nuclear@1: ma->elem_sz = elem_sz; nuclear@1: nuclear@1: if(!(ma->data = dynarr_alloc(0, elem_sz))) { nuclear@1: return -1; nuclear@1: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@1: void vattr_destroy(struct mesh_vertattr *ma) nuclear@0: { nuclear@0: if(ma) { nuclear@0: free(ma->name); nuclear@1: dynarr_free(ma->data); nuclear@0: } nuclear@0: } nuclear@0: nuclear@1: int vattr_set_name(struct mesh_vertattr *ma, const char *name) nuclear@0: { nuclear@0: char *tmp; nuclear@0: nuclear@0: if(!(tmp = malloc(strlen(name) + 1))) { nuclear@0: return -1; nuclear@0: } nuclear@0: strcpy(tmp, name); nuclear@0: nuclear@0: free(ma->name); nuclear@0: ma->name = tmp; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@1: const char *vattr_get_name(struct mesh_vertattr *ma) nuclear@1: { nuclear@1: return ma->name ? ma->name : ""; nuclear@1: } nuclear@1: nuclear@0: #define INITSZ (16 * ma->elem_size) nuclear@1: int vattr_add_elem(struct mesh_vertattr *ma, void *elem) nuclear@0: { nuclear@1: void *tmp = dynarr_push(ma->data, elem); nuclear@1: if(!tmp) { nuclear@1: return -1; nuclear@0: } nuclear@1: ma->data = tmp; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@1: nuclear@1: void *vattr_pointer(struct mesh_vertattr *ma) nuclear@1: { nuclear@1: return ma->data; nuclear@1: } nuclear@1: nuclear@1: int vattr_count(struct mesh_vertattr *ma) nuclear@1: { nuclear@1: return dynarr_size(ma->data); nuclear@1: } nuclear@1: nuclear@1: int vattr_elem_size(struct mesh_vertattr *ma) nuclear@1: { nuclear@1: return ma->elem_sz; nuclear@1: } nuclear@1: nuclear@3: void *vattr_elem(struct mesh_vertattr *ma, int elem) nuclear@3: { nuclear@3: int count = dynarr_size(ma->data); nuclear@3: if(elem >= count) { nuclear@3: return 0; nuclear@3: } nuclear@3: return (char*)ma->data + elem * ma->elem_sz; nuclear@3: } nuclear@1: nuclear@1: nuclear@0: /* -------- mesh -------- */ nuclear@0: nuclear@1: int mesh_init(struct mesh *m, int nverts) nuclear@0: { nuclear@1: m->name = 0; nuclear@1: m->poly_nverts = nverts; nuclear@1: nuclear@1: if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) { nuclear@1: return -1; nuclear@1: } nuclear@1: nuclear@1: if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) { nuclear@1: dynarr_free(m->attr); nuclear@1: return -1; nuclear@1: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void mesh_destroy(struct mesh *m) nuclear@0: { nuclear@3: int i, nattr = mesh_num_attribs(m); nuclear@0: nuclear@1: for(i=0; iattr + i); nuclear@1: } nuclear@1: dynarr_free(m->attr); nuclear@0: nuclear@1: for(i=0; ipolyidx[i].data); nuclear@0: } nuclear@1: dynarr_free(m->polyidx); nuclear@0: } nuclear@0: nuclear@0: int mesh_set_name(struct mesh *m, const char *name) nuclear@0: { nuclear@0: char *tmp; nuclear@0: nuclear@0: if(!(tmp = malloc(strlen(name) + 1))) { nuclear@0: return -1; nuclear@0: } nuclear@0: strcpy(tmp, name); nuclear@0: nuclear@0: free(m->name); nuclear@0: m->name = tmp; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@1: const char *mesh_get_name(struct mesh *m) nuclear@0: { nuclear@1: return m->name ? m->name : ""; nuclear@1: } nuclear@0: nuclear@3: int mesh_poly_type(struct mesh *m) nuclear@3: { nuclear@3: return m->poly_nverts; nuclear@3: } nuclear@3: nuclear@1: int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr) nuclear@1: { nuclear@1: struct mesh_polyidx pidx; nuclear@1: void *tmp = dynarr_push(m->attr, attr); nuclear@1: if(!tmp) { nuclear@0: return -1; nuclear@0: } nuclear@0: m->attr = tmp; nuclear@0: nuclear@1: if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) { nuclear@1: assert(pidx.data); nuclear@0: return -1; nuclear@0: } nuclear@0: nuclear@1: tmp = dynarr_push(m->polyidx, &pidx); nuclear@1: if(!tmp) { nuclear@1: assert(tmp); nuclear@1: return -1; nuclear@1: } nuclear@1: m->polyidx = tmp; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@3: int mesh_num_attribs(struct mesh *m) nuclear@3: { nuclear@3: return dynarr_size(m->attr); nuclear@3: } nuclear@3: nuclear@0: int mesh_find_attrib(struct mesh *m, const char *name) nuclear@0: { nuclear@3: int i, nattr = mesh_num_attribs(m); nuclear@0: nuclear@1: for(i=0; iattr[i].name && strcmp(m->attr[i].name, name) == 0) { nuclear@0: return i; nuclear@0: } nuclear@0: } nuclear@0: return -1; nuclear@0: } nuclear@1: nuclear@3: struct mesh_vertattr *mesh_attrib(struct mesh *m, int loc) nuclear@1: { nuclear@3: return loc >= 0 ? m->attr + loc : 0; nuclear@3: } nuclear@3: nuclear@3: void *mesh_attrib_data(struct mesh *m, int loc) nuclear@3: { nuclear@3: return loc >= 0 ? m->attr[loc].data : 0; nuclear@3: } nuclear@3: nuclear@3: int *mesh_poly_data(struct mesh *m, int loc) nuclear@3: { nuclear@3: return loc >= 0 ? m->polyidx[loc].data : 0; nuclear@3: } nuclear@3: nuclear@3: nuclear@3: int mesh_attrib_count(struct mesh *m, int loc) nuclear@3: { nuclear@3: return loc >= 0 ? vattr_count(m->attr + loc) : 0; nuclear@1: } nuclear@1: nuclear@1: int mesh_poly_count(struct mesh *m) nuclear@1: { nuclear@3: int i, nattr = mesh_num_attribs(m); nuclear@1: nuclear@1: for(i=0; ipolyidx[i].data); nuclear@1: if(count) { nuclear@1: return count; nuclear@1: } nuclear@1: } nuclear@1: return 0; nuclear@1: } nuclear@1: nuclear@3: void *mesh_attrib_elem(struct mesh *m, int loc, int elem) nuclear@3: { nuclear@3: return loc >= 0 ? vattr_elem(m->attr + loc, elem) : 0; nuclear@3: } nuclear@3: nuclear@3: int mesh_attrib_elem_size(struct mesh *m, int loc) nuclear@3: { nuclear@3: return loc >= 0 ? m->attr[loc].elem_sz : 0; nuclear@3: } nuclear@3: nuclear@1: int mesh_add_polyref(struct mesh *m, int attr_loc, ...) nuclear@1: { nuclear@3: int i, nattr = mesh_num_attribs(m); nuclear@1: int *poly = alloca(m->poly_nverts * sizeof *poly); nuclear@1: va_list ap; nuclear@1: void *tmp; nuclear@1: nuclear@1: if(attr_loc < 0 || attr_loc >= nattr) { nuclear@1: return -1; nuclear@1: } nuclear@1: nuclear@1: va_start(ap, attr_loc); nuclear@1: for(i=0; ipoly_nverts; i++) { nuclear@1: poly[i] = va_arg(ap, int); nuclear@1: } nuclear@1: va_end(ap); nuclear@1: nuclear@1: if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) { nuclear@1: return -1; nuclear@1: } nuclear@1: m->polyidx[attr_loc].data = tmp; nuclear@1: return 0; nuclear@1: }