scenefile

view src/mesh.c @ 3:b30f83409769

foo
author John Tsiombikas <nuclear@mutantstargoat.com>
date Sat, 21 Jan 2012 04:14:24 +0200
parents 38489ad82bf4
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <stdarg.h>
6 #include <assert.h>
7 #include "mesh.h"
8 #include "dynarr.h"
11 struct mesh_vertattr {
12 char *name;
13 void *data;
14 int elem_sz;
15 };
17 struct mesh_polyidx {
18 int *data;
19 };
21 struct mesh {
22 char *name;
23 int poly_nverts; /* 3, 4, etc */
25 struct mesh_vertattr *attr;
26 struct mesh_polyidx *polyidx;
27 };
30 /* --- vertex attributes --- */
32 int vattr_init(struct mesh_vertattr *ma, int elem_sz)
33 {
34 ma->name = 0;
35 ma->elem_sz = elem_sz;
37 if(!(ma->data = dynarr_alloc(0, elem_sz))) {
38 return -1;
39 }
40 return 0;
41 }
43 void vattr_destroy(struct mesh_vertattr *ma)
44 {
45 if(ma) {
46 free(ma->name);
47 dynarr_free(ma->data);
48 }
49 }
51 int vattr_set_name(struct mesh_vertattr *ma, const char *name)
52 {
53 char *tmp;
55 if(!(tmp = malloc(strlen(name) + 1))) {
56 return -1;
57 }
58 strcpy(tmp, name);
60 free(ma->name);
61 ma->name = tmp;
62 return 0;
63 }
65 const char *vattr_get_name(struct mesh_vertattr *ma)
66 {
67 return ma->name ? ma->name : "<unnamed vattr>";
68 }
70 #define INITSZ (16 * ma->elem_size)
71 int vattr_add_elem(struct mesh_vertattr *ma, void *elem)
72 {
73 void *tmp = dynarr_push(ma->data, elem);
74 if(!tmp) {
75 return -1;
76 }
77 ma->data = tmp;
78 return 0;
79 }
82 void *vattr_pointer(struct mesh_vertattr *ma)
83 {
84 return ma->data;
85 }
87 int vattr_count(struct mesh_vertattr *ma)
88 {
89 return dynarr_size(ma->data);
90 }
92 int vattr_elem_size(struct mesh_vertattr *ma)
93 {
94 return ma->elem_sz;
95 }
97 void *vattr_elem(struct mesh_vertattr *ma, int elem)
98 {
99 int count = dynarr_size(ma->data);
100 if(elem >= count) {
101 return 0;
102 }
103 return (char*)ma->data + elem * ma->elem_sz;
104 }
107 /* -------- mesh -------- */
109 int mesh_init(struct mesh *m, int nverts)
110 {
111 m->name = 0;
112 m->poly_nverts = nverts;
114 if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) {
115 return -1;
116 }
118 if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) {
119 dynarr_free(m->attr);
120 return -1;
121 }
122 return 0;
123 }
125 void mesh_destroy(struct mesh *m)
126 {
127 int i, nattr = mesh_num_attribs(m);
129 for(i=0; i<nattr; i++) {
130 vattr_destroy(m->attr + i);
131 }
132 dynarr_free(m->attr);
134 for(i=0; i<nattr; i++) {
135 dynarr_free(m->polyidx[i].data);
136 }
137 dynarr_free(m->polyidx);
138 }
140 int mesh_set_name(struct mesh *m, const char *name)
141 {
142 char *tmp;
144 if(!(tmp = malloc(strlen(name) + 1))) {
145 return -1;
146 }
147 strcpy(tmp, name);
149 free(m->name);
150 m->name = tmp;
151 return 0;
152 }
154 const char *mesh_get_name(struct mesh *m)
155 {
156 return m->name ? m->name : "<unnamed mesh>";
157 }
159 int mesh_poly_type(struct mesh *m)
160 {
161 return m->poly_nverts;
162 }
164 int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr)
165 {
166 struct mesh_polyidx pidx;
167 void *tmp = dynarr_push(m->attr, attr);
168 if(!tmp) {
169 return -1;
170 }
171 m->attr = tmp;
173 if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) {
174 assert(pidx.data);
175 return -1;
176 }
178 tmp = dynarr_push(m->polyidx, &pidx);
179 if(!tmp) {
180 assert(tmp);
181 return -1;
182 }
183 m->polyidx = tmp;
184 return 0;
185 }
187 int mesh_num_attribs(struct mesh *m)
188 {
189 return dynarr_size(m->attr);
190 }
192 int mesh_find_attrib(struct mesh *m, const char *name)
193 {
194 int i, nattr = mesh_num_attribs(m);
196 for(i=0; i<nattr; i++) {
197 if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) {
198 return i;
199 }
200 }
201 return -1;
202 }
204 struct mesh_vertattr *mesh_attrib(struct mesh *m, int loc)
205 {
206 return loc >= 0 ? m->attr + loc : 0;
207 }
209 void *mesh_attrib_data(struct mesh *m, int loc)
210 {
211 return loc >= 0 ? m->attr[loc].data : 0;
212 }
214 int *mesh_poly_data(struct mesh *m, int loc)
215 {
216 return loc >= 0 ? m->polyidx[loc].data : 0;
217 }
220 int mesh_attrib_count(struct mesh *m, int loc)
221 {
222 return loc >= 0 ? vattr_count(m->attr + loc) : 0;
223 }
225 int mesh_poly_count(struct mesh *m)
226 {
227 int i, nattr = mesh_num_attribs(m);
229 for(i=0; i<nattr; i++) {
230 int count = dynarr_empty(m->polyidx[i].data);
231 if(count) {
232 return count;
233 }
234 }
235 return 0;
236 }
238 void *mesh_attrib_elem(struct mesh *m, int loc, int elem)
239 {
240 return loc >= 0 ? vattr_elem(m->attr + loc, elem) : 0;
241 }
243 int mesh_attrib_elem_size(struct mesh *m, int loc)
244 {
245 return loc >= 0 ? m->attr[loc].elem_sz : 0;
246 }
248 int mesh_add_polyref(struct mesh *m, int attr_loc, ...)
249 {
250 int i, nattr = mesh_num_attribs(m);
251 int *poly = alloca(m->poly_nverts * sizeof *poly);
252 va_list ap;
253 void *tmp;
255 if(attr_loc < 0 || attr_loc >= nattr) {
256 return -1;
257 }
259 va_start(ap, attr_loc);
260 for(i=0; i<m->poly_nverts; i++) {
261 poly[i] = va_arg(ap, int);
262 }
263 va_end(ap);
265 if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) {
266 return -1;
267 }
268 m->polyidx[attr_loc].data = tmp;
269 return 0;
270 }