scenefile

view src/mesh.c @ 2:c15992cedec9

scene
author John Tsiombikas <nuclear@mutantstargoat.com>
date Sun, 15 Jan 2012 08:32:19 +0200
parents 8c6d64af9505
children b30f83409769
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 }
99 /* -------- mesh -------- */
101 int mesh_init(struct mesh *m, int nverts)
102 {
103 m->name = 0;
104 m->poly_nverts = nverts;
106 if(!(m->attr = dynarr_alloc(0, sizeof *m->attr))) {
107 return -1;
108 }
110 if(!(m->polyidx = dynarr_alloc(0, sizeof *m->polyidx))) {
111 dynarr_free(m->attr);
112 return -1;
113 }
114 return 0;
115 }
117 void mesh_destroy(struct mesh *m)
118 {
119 int i, nattr = mesh_attr_count(m);
121 for(i=0; i<nattr; i++) {
122 vattr_destroy(m->attr + i);
123 }
124 dynarr_free(m->attr);
126 for(i=0; i<nattr; i++) {
127 dynarr_free(m->polyidx[i].data);
128 }
129 dynarr_free(m->polyidx);
130 }
132 int mesh_set_name(struct mesh *m, const char *name)
133 {
134 char *tmp;
136 if(!(tmp = malloc(strlen(name) + 1))) {
137 return -1;
138 }
139 strcpy(tmp, name);
141 free(m->name);
142 m->name = tmp;
143 return 0;
144 }
146 const char *mesh_get_name(struct mesh *m)
147 {
148 return m->name ? m->name : "<unnamed mesh>";
149 }
151 int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr)
152 {
153 struct mesh_polyidx pidx;
154 void *tmp = dynarr_push(m->attr, attr);
155 if(!tmp) {
156 return -1;
157 }
158 m->attr = tmp;
160 if(!(pidx.data = dynarr_alloc(0, m->poly_nverts * sizeof *pidx.data))) {
161 assert(pidx.data);
162 return -1;
163 }
165 tmp = dynarr_push(m->polyidx, &pidx);
166 if(!tmp) {
167 assert(tmp);
168 return -1;
169 }
170 m->polyidx = tmp;
171 return 0;
172 }
174 int mesh_find_attrib(struct mesh *m, const char *name)
175 {
176 int i, nattr = mesh_attr_count(m);
178 for(i=0; i<nattr; i++) {
179 if(m->attr[i].name && strcmp(m->attr[i].name, name) == 0) {
180 return i;
181 }
182 }
183 return -1;
184 }
186 int mesh_attr_count(struct mesh *m)
187 {
188 return dynarr_size(m->attr);
189 }
191 int mesh_poly_count(struct mesh *m)
192 {
193 int i, nattr = mesh_attr_count(m);
195 for(i=0; i<nattr; i++) {
196 int count = dynarr_empty(m->polyidx[i].data);
197 if(count) {
198 return count;
199 }
200 }
201 return 0;
202 }
204 int mesh_add_polyref(struct mesh *m, int attr_loc, ...)
205 {
206 int i, nattr = mesh_attr_count(m);
207 int *poly = alloca(m->poly_nverts * sizeof *poly);
208 va_list ap;
209 void *tmp;
211 if(attr_loc < 0 || attr_loc >= nattr) {
212 return -1;
213 }
215 va_start(ap, attr_loc);
216 for(i=0; i<m->poly_nverts; i++) {
217 poly[i] = va_arg(ap, int);
218 }
219 va_end(ap);
221 if(!(tmp = dynarr_push(m->polyidx[attr_loc].data, poly))) {
222 return -1;
223 }
224 m->polyidx[attr_loc].data = tmp;
225 return 0;
226 }