scenefile
changeset 1:38489ad82bf4
foo
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Sat, 14 Jan 2012 08:10:50 +0200 |
parents | 8c6d64af9505 |
children | c15992cedec9 |
files | src/dynarr.c src/dynarr.h src/mesh.c src/mesh.h |
diffstat | 4 files changed, 312 insertions(+), 67 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/dynarr.c Sat Jan 14 08:10:50 2012 +0200 1.3 @@ -0,0 +1,122 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include "dynarr.h" 1.8 + 1.9 +/* The array descriptor keeps auxilliary information needed to manipulate 1.10 + * the dynamic array. It's allocated adjacent to the array buffer. 1.11 + */ 1.12 +struct arrdesc { 1.13 + int nelem, szelem; 1.14 + int max_elem; 1.15 + int bufsz; /* not including the descriptor */ 1.16 +}; 1.17 + 1.18 +#define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc))) 1.19 + 1.20 +void *dynarr_alloc(int elem, int szelem) 1.21 +{ 1.22 + struct arrdesc *desc; 1.23 + 1.24 + if(!(desc = malloc(elem * szelem + sizeof *desc))) { 1.25 + return 0; 1.26 + } 1.27 + desc->nelem = desc->max_elem = elem; 1.28 + desc->szelem = szelem; 1.29 + desc->bufsz = elem * szelem; 1.30 + return (char*)desc + sizeof *desc; 1.31 +} 1.32 + 1.33 +void dynarr_free(void *da) 1.34 +{ 1.35 + if(da) { 1.36 + free(DESC(da)); 1.37 + } 1.38 +} 1.39 + 1.40 +void *dynarr_resize(void *da, int elem) 1.41 +{ 1.42 + int newsz; 1.43 + void *tmp; 1.44 + struct arrdesc *desc; 1.45 + 1.46 + if(!da) return 0; 1.47 + desc = DESC(da); 1.48 + 1.49 + newsz = desc->szelem * elem; 1.50 + 1.51 + if(!(tmp = realloc(desc, newsz + sizeof *desc))) { 1.52 + return 0; 1.53 + } 1.54 + desc = tmp; 1.55 + 1.56 + desc->nelem = desc->max_elem = elem; 1.57 + desc->bufsz = newsz; 1.58 + return (char*)desc + sizeof *desc; 1.59 +} 1.60 + 1.61 +int dynarr_empty(void *da) 1.62 +{ 1.63 + return DESC(da)->nelem ? 0 : 1; 1.64 +} 1.65 + 1.66 +int dynarr_size(void *da) 1.67 +{ 1.68 + return DESC(da)->nelem; 1.69 +} 1.70 + 1.71 + 1.72 +/* stack semantics */ 1.73 +void *dynarr_push(void *da, void *item) 1.74 +{ 1.75 + struct arrdesc *desc; 1.76 + int nelem; 1.77 + 1.78 + desc = DESC(da); 1.79 + nelem = desc->nelem; 1.80 + 1.81 + if(nelem >= desc->max_elem) { 1.82 + /* need to resize */ 1.83 + struct arrdesc *tmp; 1.84 + int newsz = desc->max_elem ? desc->max_elem * 2 : 1; 1.85 + 1.86 + if(!(tmp = dynarr_resize(da, newsz))) { 1.87 + fprintf(stderr, "failed to resize\n"); 1.88 + return da; 1.89 + } 1.90 + da = tmp; 1.91 + desc = DESC(da); 1.92 + desc->nelem = nelem; 1.93 + } 1.94 + 1.95 + memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem); 1.96 + return da; 1.97 +} 1.98 + 1.99 +void *dynarr_pop(void *da) 1.100 +{ 1.101 + struct arrdesc *desc; 1.102 + int nelem; 1.103 + 1.104 + desc = DESC(da); 1.105 + nelem = desc->nelem; 1.106 + 1.107 + if(!nelem) return da; 1.108 + 1.109 + if(nelem <= desc->max_elem / 3) { 1.110 + /* reclaim space */ 1.111 + struct arrdesc *tmp; 1.112 + int newsz = desc->max_elem / 2; 1.113 + 1.114 + if(!(tmp = dynarr_resize(da, newsz))) { 1.115 + fprintf(stderr, "failed to resize\n"); 1.116 + return da; 1.117 + } 1.118 + da = tmp; 1.119 + desc = DESC(da); 1.120 + desc->nelem = nelem; 1.121 + } 1.122 + desc->nelem--; 1.123 + 1.124 + return da; 1.125 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/dynarr.h Sat Jan 14 08:10:50 2012 +0200 2.3 @@ -0,0 +1,16 @@ 2.4 +#ifndef DYNARR_H_ 2.5 +#define DYNARR_H_ 2.6 + 2.7 +void *dynarr_alloc(int elem, int szelem); 2.8 +void dynarr_free(void *da); 2.9 +void *dynarr_resize(void *da, int elem); 2.10 + 2.11 +int dynarr_empty(void *da); 2.12 +int dynarr_size(void *da); 2.13 + 2.14 +/* stack semantics */ 2.15 +void *dynarr_push(void *da, void *item); 2.16 +void *dynarr_pop(void *da); 2.17 + 2.18 + 2.19 +#endif /* DYNARR_H_ */
3.1 --- a/src/mesh.c Fri Jan 13 09:34:16 2012 +0200 3.2 +++ b/src/mesh.c Sat Jan 14 08:10:50 2012 +0200 3.3 @@ -2,23 +2,53 @@ 3.4 #include <stdlib.h> 3.5 #include <string.h> 3.6 #include <errno.h> 3.7 +#include <stdarg.h> 3.8 +#include <assert.h> 3.9 #include "mesh.h" 3.10 +#include "dynarr.h" 3.11 3.12 -int mattr_init(struct mesh_attrib *ma) 3.13 + 3.14 +struct mesh_vertattr { 3.15 + char *name; 3.16 + void *data; 3.17 + int elem_sz; 3.18 +}; 3.19 + 3.20 +struct mesh_polyidx { 3.21 + int *data; 3.22 +}; 3.23 + 3.24 +struct mesh { 3.25 + char *name; 3.26 + int poly_nverts; /* 3, 4, etc */ 3.27 + 3.28 + struct mesh_vertattr *attr; 3.29 + struct mesh_polyidx *polyidx; 3.30 +}; 3.31 + 3.32 + 3.33 +/* --- vertex attributes --- */ 3.34 + 3.35 +int vattr_init(struct mesh_vertattr *ma, int elem_sz) 3.36 { 3.37 - memset(ma, 0, sizeof *ma); 3.38 + ma->name = 0; 3.39 + ma->elem_sz = elem_sz; 3.40 + 3.41 + if(!(ma->data = dynarr_alloc(0, elem_sz))) { 3.42 + return -1; 3.43 + } 3.44 return 0; 3.45 } 3.46 3.47 -void mattr_destroy(struct mesh_attrib *ma) 3.48 +void vattr_destroy(struct mesh_vertattr *ma) 3.49 { 3.50 if(ma) { 3.51 free(ma->name); 3.52 - free(ma->data); 3.53 + dynarr_free(ma->data); 3.54 } 3.55 } 3.56 3.57 -int mattr_set_name(struct mesh_attrib *ma, const char *name) 3.58 +int vattr_set_name(struct mesh_vertattr *ma, const char *name) 3.59 { 3.60 char *tmp; 3.61 3.62 @@ -32,50 +62,71 @@ 3.63 return 0; 3.64 } 3.65 3.66 +const char *vattr_get_name(struct mesh_vertattr *ma) 3.67 +{ 3.68 + return ma->name ? ma->name : "<unnamed vattr>"; 3.69 +} 3.70 + 3.71 #define INITSZ (16 * ma->elem_size) 3.72 -int mattr_add_elem(struct mesh_attrib *ma, void *data) 3.73 +int vattr_add_elem(struct mesh_vertattr *ma, void *elem) 3.74 { 3.75 - int nsz = (ma->count + 1) * ma->elem_size; 3.76 - 3.77 - if(nsz > ma->datasz) { 3.78 - void *tmp; 3.79 - 3.80 - nsz = ma->datasz ? ma->datasz * 2 : INITSZ; 3.81 - 3.82 - if(!(tmp = realloc(ma->data, nsz))) { 3.83 - return -1; 3.84 - } 3.85 - ma->data = tmp; 3.86 - ma->datasz = nsz; 3.87 + void *tmp = dynarr_push(ma->data, elem); 3.88 + if(!tmp) { 3.89 + return -1; 3.90 } 3.91 - 3.92 - memcpy((char*)ma->data + ma->elem_size * ma->count++, data, ma->elem_size); 3.93 + ma->data = tmp; 3.94 return 0; 3.95 } 3.96 3.97 + 3.98 +void *vattr_pointer(struct mesh_vertattr *ma) 3.99 +{ 3.100 + return ma->data; 3.101 +} 3.102 + 3.103 +int vattr_count(struct mesh_vertattr *ma) 3.104 +{ 3.105 + return dynarr_size(ma->data); 3.106 +} 3.107 + 3.108 +int vattr_elem_size(struct mesh_vertattr *ma) 3.109 +{ 3.110 + return ma->elem_sz; 3.111 +} 3.112 + 3.113 + 3.114 + 3.115 /* -------- mesh -------- */ 3.116 3.117 -int mesh_init(struct mesh *m) 3.118 +int mesh_init(struct mesh *m, int nverts) 3.119 { 3.120 - memset(m, 0, sizeof *m); 3.121 + m->name = 0; 3.122 + m->poly_nverts = nverts; 3.123 + 3.124 + if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) { 3.125 + return -1; 3.126 + } 3.127 + 3.128 + if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) { 3.129 + dynarr_free(m->attr); 3.130 + return -1; 3.131 + } 3.132 return 0; 3.133 } 3.134 3.135 void mesh_destroy(struct mesh *m) 3.136 { 3.137 - int i; 3.138 + int i, nattr = mesh_attr_count(m); 3.139 3.140 - free(m->name); 3.141 + for(i=0; i<nattr; i++) { 3.142 + vattr_destroy(m->attr + i); 3.143 + } 3.144 + dynarr_free(m->attr); 3.145 3.146 - for(i=0; i<m->num_attr; i++) { 3.147 - mattr_destroy(&m->attr[i]); 3.148 + for(i=0; i<nattr; i++) { 3.149 + dynarr_free(m->polyidx[i].data); 3.150 } 3.151 - free(m->attr); 3.152 - 3.153 - for(i=0; i<m->num_attr; i++) { 3.154 - free(m->polyidx[i]); 3.155 - } 3.156 - free(m->polyidx); 3.157 + dynarr_free(m->polyidx); 3.158 } 3.159 3.160 int mesh_set_name(struct mesh *m, const char *name) 3.161 @@ -92,34 +143,84 @@ 3.162 return 0; 3.163 } 3.164 3.165 -int mesh_add_attrib(struct mesh *m, struct mesh_attrib *attr) 3.166 +const char *mesh_get_name(struct mesh *m) 3.167 { 3.168 - void *tmp; 3.169 - int idx = m->num_attr++; 3.170 + return m->name ? m->name : "<unnamed mesh>"; 3.171 +} 3.172 3.173 - if(!(tmp = realloc(m->attr, m->num_attr * sizeof *attr))) { 3.174 +int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr) 3.175 +{ 3.176 + struct mesh_polyidx pidx; 3.177 + void *tmp = dynarr_push(m->attr, attr); 3.178 + if(!tmp) { 3.179 return -1; 3.180 } 3.181 m->attr = tmp; 3.182 - m->attr[idx] = *attr; 3.183 3.184 - if(!(tmp = realloc(m->polyidx, m->num_attr * sizeof *m->polyidx))) { 3.185 - m->num_attr--; 3.186 + if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) { 3.187 + assert(pidx.data); 3.188 return -1; 3.189 } 3.190 - m->polyidx[idx] = 0; 3.191 3.192 + tmp = dynarr_push(m->polyidx, &pidx); 3.193 + if(!tmp) { 3.194 + assert(tmp); 3.195 + return -1; 3.196 + } 3.197 + m->polyidx = tmp; 3.198 return 0; 3.199 } 3.200 3.201 int mesh_find_attrib(struct mesh *m, const char *name) 3.202 { 3.203 - int i; 3.204 + int i, nattr = mesh_attr_count(m); 3.205 3.206 - for(i=0; i<m->num_attr; i++) { 3.207 - if(strcmp(m->attr[i].name, name) == 0) { 3.208 + for(i=0; i<nattr; i++) { 3.209 + if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) { 3.210 return i; 3.211 } 3.212 } 3.213 return -1; 3.214 } 3.215 + 3.216 +int mesh_attr_count(struct mesh *m) 3.217 +{ 3.218 + return dynarr_size(m->attr); 3.219 +} 3.220 + 3.221 +int mesh_poly_count(struct mesh *m) 3.222 +{ 3.223 + int i, nattr = mesh_attr_count(m); 3.224 + 3.225 + for(i=0; i<nattr; i++) { 3.226 + int count = dynarr_empty(m->polyidx[i].data); 3.227 + if(count) { 3.228 + return count; 3.229 + } 3.230 + } 3.231 + return 0; 3.232 +} 3.233 + 3.234 +int mesh_add_polyref(struct mesh *m, int attr_loc, ...) 3.235 +{ 3.236 + int i, nattr = mesh_attr_count(m); 3.237 + int *poly = alloca(m->poly_nverts * sizeof *poly); 3.238 + va_list ap; 3.239 + void *tmp; 3.240 + 3.241 + if(attr_loc < 0 || attr_loc >= nattr) { 3.242 + return -1; 3.243 + } 3.244 + 3.245 + va_start(ap, attr_loc); 3.246 + for(i=0; i<m->poly_nverts; i++) { 3.247 + poly[i] = va_arg(ap, int); 3.248 + } 3.249 + va_end(ap); 3.250 + 3.251 + if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) { 3.252 + return -1; 3.253 + } 3.254 + m->polyidx[attr_loc].data = tmp; 3.255 + return 0; 3.256 +}
4.1 --- a/src/mesh.h Fri Jan 13 09:34:16 2012 +0200 4.2 +++ b/src/mesh.h Sat Jan 14 08:10:50 2012 +0200 4.3 @@ -1,42 +1,48 @@ 4.4 #ifndef MESH_H_ 4.5 #define MESH_H_ 4.6 4.7 -struct mesh_attrib { 4.8 - char *name; 4.9 - int count, elem_size; 4.10 - void *data; 4.11 - 4.12 - int datasz; 4.13 -}; 4.14 - 4.15 -struct mesh { 4.16 - char *name; 4.17 - int poly_nverts; /* 3, 4, etc */ 4.18 - 4.19 - struct mesh_attrib *attr; 4.20 - int num_attr; 4.21 - 4.22 - int **polyidx; 4.23 - int num_poly; 4.24 -}; 4.25 +struct mesh_vertattr; 4.26 +struct mesh_polyidx; 4.27 +struct mesh; 4.28 4.29 #ifdef __cplusplus 4.30 extern "C" { 4.31 #endif 4.32 4.33 -int mattr_init(struct mesh_attrib *ma); 4.34 -void mattr_destroy(struct mesh_attrib *ma); 4.35 +/* --- vertex attributes --- */ 4.36 4.37 -int mattr_set_name(struct mesh_attrib *ma, const char *name); 4.38 -int mattr_add_elem(struct mesh_attrib *ma, void *data); 4.39 +int vattr_init(struct mesh_vertattr *ma, int elem_sz); 4.40 +void vattr_destroy(struct mesh_vertattr *ma); 4.41 4.42 -int mesh_init(struct mesh *m); 4.43 +int vattr_set_name(struct mesh_vertattr *ma, const char *name); 4.44 +const char *vattr_get_name(struct mesh_vertattr *ma); 4.45 + 4.46 +int vattr_add_elem(struct mesh_vertattr *ma, void *elem); 4.47 + 4.48 +void *vattr_pointer(struct mesh_vertattr *ma); 4.49 +int vattr_count(struct mesh_vertattr *ma); 4.50 +int vattr_elem_size(struct mesh_vertattr *ma); 4.51 + 4.52 +/* --- mesh --- */ 4.53 + 4.54 +int mesh_init(struct mesh *m, int nverts); 4.55 void mesh_destroy(struct mesh *m); 4.56 4.57 int mesh_set_name(struct mesh *m, const char *name); 4.58 -int mesh_add_attrib(struct mesh *m, struct mesh_attrib *attr); 4.59 +const char *mesh_get_name(struct mesh *m); 4.60 + 4.61 +int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr); 4.62 int mesh_find_attrib(struct mesh *m, const char *name); 4.63 4.64 +int mesh_attr_count(struct mesh *m); 4.65 +int mesh_poly_count(struct mesh *m); 4.66 + 4.67 +/* the variable arguments correspond to the N indices of the N-gon 4.68 + * for this particular vertex attribute (attr_loc, retrieved by 4.69 + * mesh_find_attrib) 4.70 + */ 4.71 +int mesh_add_polyref(struct mesh *m, int attr_loc, ...); 4.72 + 4.73 #ifdef __cplusplus 4.74 } 4.75 #endif