scenefile

diff src/mesh.c @ 1:38489ad82bf4

foo
author John Tsiombikas <nuclear@mutantstargoat.com>
date Sat, 14 Jan 2012 08:10:50 +0200
parents 8c6d64af9505
children b30f83409769
line diff
     1.1 --- a/src/mesh.c	Fri Jan 13 09:34:16 2012 +0200
     1.2 +++ b/src/mesh.c	Sat Jan 14 08:10:50 2012 +0200
     1.3 @@ -2,23 +2,53 @@
     1.4  #include <stdlib.h>
     1.5  #include <string.h>
     1.6  #include <errno.h>
     1.7 +#include <stdarg.h>
     1.8 +#include <assert.h>
     1.9  #include "mesh.h"
    1.10 +#include "dynarr.h"
    1.11  
    1.12 -int mattr_init(struct mesh_attrib *ma)
    1.13 +
    1.14 +struct mesh_vertattr {
    1.15 +	char *name;
    1.16 +	void *data;
    1.17 +	int elem_sz;
    1.18 +};
    1.19 +
    1.20 +struct mesh_polyidx {
    1.21 +	int *data;
    1.22 +};
    1.23 +
    1.24 +struct mesh {
    1.25 +	char *name;
    1.26 +	int poly_nverts;	/* 3, 4, etc */
    1.27 +
    1.28 +	struct mesh_vertattr *attr;
    1.29 +	struct mesh_polyidx *polyidx;
    1.30 +};
    1.31 +
    1.32 +
    1.33 +/* --- vertex attributes --- */
    1.34 +
    1.35 +int vattr_init(struct mesh_vertattr *ma, int elem_sz)
    1.36  {
    1.37 -	memset(ma, 0, sizeof *ma);
    1.38 +	ma->name = 0;
    1.39 +	ma->elem_sz = elem_sz;
    1.40 +
    1.41 +	if(!(ma->data = dynarr_alloc(0, elem_sz))) {
    1.42 +		return -1;
    1.43 +	}
    1.44  	return 0;
    1.45  }
    1.46  
    1.47 -void mattr_destroy(struct mesh_attrib *ma)
    1.48 +void vattr_destroy(struct mesh_vertattr *ma)
    1.49  {
    1.50  	if(ma) {
    1.51  		free(ma->name);
    1.52 -		free(ma->data);
    1.53 +		dynarr_free(ma->data);
    1.54  	}
    1.55  }
    1.56  
    1.57 -int mattr_set_name(struct mesh_attrib *ma, const char *name)
    1.58 +int vattr_set_name(struct mesh_vertattr *ma, const char *name)
    1.59  {
    1.60  	char *tmp;
    1.61  
    1.62 @@ -32,50 +62,71 @@
    1.63  	return 0;
    1.64  }
    1.65  
    1.66 +const char *vattr_get_name(struct mesh_vertattr *ma)
    1.67 +{
    1.68 +	return ma->name ? ma->name : "<unnamed vattr>";
    1.69 +}
    1.70 +
    1.71  #define INITSZ	(16 * ma->elem_size)
    1.72 -int mattr_add_elem(struct mesh_attrib *ma, void *data)
    1.73 +int vattr_add_elem(struct mesh_vertattr *ma, void *elem)
    1.74  {
    1.75 -	int nsz = (ma->count + 1) * ma->elem_size;
    1.76 -
    1.77 -	if(nsz > ma->datasz) {
    1.78 -		void *tmp;
    1.79 -
    1.80 -		nsz = ma->datasz ? ma->datasz * 2 : INITSZ;
    1.81 -
    1.82 -		if(!(tmp = realloc(ma->data, nsz))) {
    1.83 -			return -1;
    1.84 -		}
    1.85 -		ma->data = tmp;
    1.86 -		ma->datasz = nsz;
    1.87 +	void *tmp = dynarr_push(ma->data, elem);
    1.88 +	if(!tmp) {
    1.89 +		return -1;
    1.90  	}
    1.91 -
    1.92 -	memcpy((char*)ma->data + ma->elem_size * ma->count++, data, ma->elem_size);
    1.93 +	ma->data = tmp;
    1.94  	return 0;
    1.95  }
    1.96  
    1.97 +
    1.98 +void *vattr_pointer(struct mesh_vertattr *ma)
    1.99 +{
   1.100 +	return ma->data;
   1.101 +}
   1.102 +
   1.103 +int vattr_count(struct mesh_vertattr *ma)
   1.104 +{
   1.105 +	return dynarr_size(ma->data);
   1.106 +}
   1.107 +
   1.108 +int vattr_elem_size(struct mesh_vertattr *ma)
   1.109 +{
   1.110 +	return ma->elem_sz;
   1.111 +}
   1.112 +
   1.113 +
   1.114 +
   1.115  /* -------- mesh -------- */
   1.116  
   1.117 -int mesh_init(struct mesh *m)
   1.118 +int mesh_init(struct mesh *m, int nverts)
   1.119  {
   1.120 -	memset(m, 0, sizeof *m);
   1.121 +	m->name = 0;
   1.122 +	m->poly_nverts = nverts;
   1.123 +
   1.124 +	if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) {
   1.125 +		return -1;
   1.126 +	}
   1.127 +
   1.128 +	if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) {
   1.129 +		dynarr_free(m->attr);
   1.130 +		return -1;
   1.131 +	}
   1.132  	return 0;
   1.133  }
   1.134  
   1.135  void mesh_destroy(struct mesh *m)
   1.136  {
   1.137 -	int i;
   1.138 +	int i, nattr = mesh_attr_count(m);
   1.139  
   1.140 -	free(m->name);
   1.141 +	for(i=0; i<nattr; i++) {
   1.142 +		vattr_destroy(m->attr + i);
   1.143 +	}
   1.144 +	dynarr_free(m->attr);
   1.145  
   1.146 -	for(i=0; i<m->num_attr; i++) {
   1.147 -		mattr_destroy(&m->attr[i]);
   1.148 +	for(i=0; i<nattr; i++) {
   1.149 +		dynarr_free(m->polyidx[i].data);
   1.150  	}
   1.151 -	free(m->attr);
   1.152 -
   1.153 -	for(i=0; i<m->num_attr; i++) {
   1.154 -		free(m->polyidx[i]);
   1.155 -	}
   1.156 -	free(m->polyidx);
   1.157 +	dynarr_free(m->polyidx);
   1.158  }
   1.159  
   1.160  int mesh_set_name(struct mesh *m, const char *name)
   1.161 @@ -92,34 +143,84 @@
   1.162  	return 0;
   1.163  }
   1.164  
   1.165 -int mesh_add_attrib(struct mesh *m, struct mesh_attrib *attr)
   1.166 +const char *mesh_get_name(struct mesh *m)
   1.167  {
   1.168 -	void *tmp;
   1.169 -	int idx = m->num_attr++;
   1.170 +	return m->name ? m->name : "<unnamed mesh>";
   1.171 +}
   1.172  
   1.173 -	if(!(tmp = realloc(m->attr, m->num_attr * sizeof *attr))) {
   1.174 +int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr)
   1.175 +{
   1.176 +	struct mesh_polyidx pidx;
   1.177 +	void *tmp = dynarr_push(m->attr, attr);
   1.178 +	if(!tmp) {
   1.179  		return -1;
   1.180  	}
   1.181  	m->attr = tmp;
   1.182 -	m->attr[idx] = *attr;
   1.183  
   1.184 -	if(!(tmp = realloc(m->polyidx, m->num_attr * sizeof *m->polyidx))) {
   1.185 -		m->num_attr--;
   1.186 +	if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) {
   1.187 +		assert(pidx.data);
   1.188  		return -1;
   1.189  	}
   1.190 -	m->polyidx[idx] = 0;
   1.191  
   1.192 +	tmp = dynarr_push(m->polyidx, &pidx);
   1.193 +	if(!tmp) {
   1.194 +		assert(tmp);
   1.195 +		return -1;
   1.196 +	}
   1.197 +	m->polyidx = tmp;
   1.198  	return 0;
   1.199  }
   1.200  
   1.201  int mesh_find_attrib(struct mesh *m, const char *name)
   1.202  {
   1.203 -	int i;
   1.204 +	int i, nattr = mesh_attr_count(m);
   1.205  
   1.206 -	for(i=0; i<m->num_attr; i++) {
   1.207 -		if(strcmp(m->attr[i].name, name) == 0) {
   1.208 +	for(i=0; i<nattr; i++) {
   1.209 +		if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) {
   1.210  			return i;
   1.211  		}
   1.212  	}
   1.213  	return -1;
   1.214  }
   1.215 +
   1.216 +int mesh_attr_count(struct mesh *m)
   1.217 +{
   1.218 +	return dynarr_size(m->attr);
   1.219 +}
   1.220 +
   1.221 +int mesh_poly_count(struct mesh *m)
   1.222 +{
   1.223 +	int i, nattr = mesh_attr_count(m);
   1.224 +
   1.225 +	for(i=0; i<nattr; i++) {
   1.226 +		int count = dynarr_empty(m->polyidx[i].data);
   1.227 +		if(count) {
   1.228 +			return count;
   1.229 +		}
   1.230 +	}
   1.231 +	return 0;
   1.232 +}
   1.233 +
   1.234 +int mesh_add_polyref(struct mesh *m, int attr_loc, ...)
   1.235 +{
   1.236 +	int i, nattr = mesh_attr_count(m);
   1.237 +	int *poly = alloca(m->poly_nverts * sizeof *poly);
   1.238 +	va_list ap;
   1.239 +	void *tmp;
   1.240 +
   1.241 +	if(attr_loc < 0 || attr_loc >= nattr) {
   1.242 +		return -1;
   1.243 +	}
   1.244 +
   1.245 +	va_start(ap, attr_loc);
   1.246 +	for(i=0; i<m->poly_nverts; i++) {
   1.247 +		poly[i] = va_arg(ap, int);
   1.248 +	}
   1.249 +	va_end(ap);
   1.250 +
   1.251 +	if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) {
   1.252 +		return -1;
   1.253 +	}
   1.254 +	m->polyidx[attr_loc].data = tmp;
   1.255 +	return 0;
   1.256 +}