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