scenefile

annotate src/mesh.c @ 3:b30f83409769

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