goat3d
diff generators/goatprim/main.c @ 17:1d85d7dd0038
goatprim done
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 27 Sep 2013 02:29:52 +0300 |
parents | cb6c1a945a11 |
children | bdfc8dd14965 |
line diff
1.1 --- a/generators/goatprim/main.c Thu Sep 26 14:16:09 2013 +0300 1.2 +++ b/generators/goatprim/main.c Fri Sep 27 02:29:52 2013 +0300 1.3 @@ -1,78 +1,306 @@ 1.4 #include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <math.h> 1.8 #include "goat3d.h" 1.9 1.10 -static struct goat3d_mesh *create_box(void); 1.11 +#define DEF_USUB 16 1.12 +#define DEF_VSUB 8 1.13 +#define DEF_SIZE 1.0 1.14 +#define DEF_OUTER 0.25 1.15 1.16 -int main(void) 1.17 +enum { BOX, SPHERE, TORUS }; 1.18 + 1.19 +void gen_box(struct goat3d_mesh *mesh, float size); 1.20 +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub); 1.21 +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax); 1.22 +void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub); 1.23 +void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer, 1.24 + int usub, int vsub, float umax, float vmin, float vmax); 1.25 + 1.26 + 1.27 +int main(int argc, char **argv) 1.28 { 1.29 + int i, prim = BOX; 1.30 + int usub = DEF_USUB; 1.31 + int vsub = DEF_VSUB; 1.32 + float size = DEF_SIZE; 1.33 + float outer = DEF_OUTER; 1.34 struct goat3d *goat; 1.35 struct goat3d_material *mtl; 1.36 struct goat3d_mesh *mesh; 1.37 + const char *fname = 0; 1.38 + 1.39 + for(i=1; i<argc; i++) { 1.40 + if(strcmp(argv[i], "-box") == 0) { 1.41 + prim = BOX; 1.42 + 1.43 + } else if(strcmp(argv[i], "-sphere") == 0) { 1.44 + prim = SPHERE; 1.45 + 1.46 + } else if(strcmp(argv[i], "-torus") == 0) { 1.47 + prim = TORUS; 1.48 + 1.49 + } else if(strcmp(argv[i], "-rad") == 0 || strcmp(argv[i], "-size") == 0 1.50 + || strcmp(argv[i], "-inner") == 0) { 1.51 + if((size = atof(argv[++i])) == 0.0) { 1.52 + fprintf(stderr, "invalid size\n"); 1.53 + return 1; 1.54 + } 1.55 + 1.56 + } else if(strcmp(argv[i], "-outer") == 0) { 1.57 + if((outer = atof(argv[++i])) == 0.0) { 1.58 + fprintf(stderr, "invalid outer radius\n"); 1.59 + return 1; 1.60 + } 1.61 + 1.62 + } else if(strcmp(argv[i], "-usub") == 0) { 1.63 + if(!(usub = atoi(argv[++i]))) { 1.64 + fprintf(stderr, "invalid usub\n"); 1.65 + return 1; 1.66 + } 1.67 + 1.68 + } else if(strcmp(argv[i], "-vsub") == 0) { 1.69 + if(!(vsub = atoi(argv[++i]))) { 1.70 + fprintf(stderr, "invalid vsub\n"); 1.71 + return 1; 1.72 + } 1.73 + 1.74 + } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) { 1.75 + printf("Usage: %s [filename] [options]\n", argv[0]); 1.76 + printf("Options:\n"); 1.77 + printf(" -box create box (default)\n"); 1.78 + printf(" -sphere create sphere\n"); 1.79 + printf(" -torus create torus\n"); 1.80 + printf(" -size <n>, -rad <n>, -inner <n> (default: %g)\n", DEF_SIZE); 1.81 + printf(" -outer <n> torus outer radius (default: %g)\n", DEF_OUTER); 1.82 + printf(" -usub <n> subdivisions along the horizontal direction (default: %d)\n", DEF_USUB); 1.83 + printf(" -vsub <n> subdivisions along the vertical direction (default: %d)\n", DEF_VSUB); 1.84 + printf(" -h, -help print usage information and exit\n"); 1.85 + return 0; 1.86 + 1.87 + } else { 1.88 + if(fname) { 1.89 + fprintf(stderr, "unexpected argument: %s\n", argv[i]); 1.90 + return 1; 1.91 + } 1.92 + fname = argv[i]; 1.93 + } 1.94 + } 1.95 + 1.96 + if(!fname) { 1.97 + fname = "out.xml"; 1.98 + } 1.99 1.100 goat = goat3d_create(); 1.101 + goat3d_set_name(goat, fname); 1.102 1.103 mtl = goat3d_create_mtl(); 1.104 goat3d_set_mtl_name(mtl, "mat"); 1.105 goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, 1, 0, 0, 1); 1.106 goat3d_add_mtl(goat, mtl); 1.107 1.108 - mesh = create_box(); 1.109 + mesh = goat3d_create_mesh(); 1.110 + 1.111 + switch(prim) { 1.112 + case BOX: 1.113 + gen_box(mesh, size); 1.114 + break; 1.115 + 1.116 + case SPHERE: 1.117 + gen_sphere(mesh, size, usub, vsub); 1.118 + break; 1.119 + 1.120 + case TORUS: 1.121 + gen_torus(mesh, size, outer, usub, vsub); 1.122 + break; 1.123 + 1.124 + default: 1.125 + return 1; 1.126 + } 1.127 + goat3d_set_mesh_mtl(mesh, mtl); 1.128 goat3d_add_mesh(goat, mesh); 1.129 1.130 goat3d_setopt(goat, GOAT3D_OPT_SAVEXML, 1); 1.131 - goat3d_save(goat, "foo.xml"); 1.132 + goat3d_save(goat, fname); 1.133 1.134 goat3d_free(goat); 1.135 return 0; 1.136 } 1.137 1.138 -static struct goat3d_mesh *create_box(void) 1.139 +void gen_box(struct goat3d_mesh *mesh, float size) 1.140 { 1.141 - struct goat3d_mesh *mesh = goat3d_create_mesh(); 1.142 + float hsz = size / 2.0; 1.143 1.144 goat3d_begin(mesh, GOAT3D_QUADS); 1.145 // +X 1.146 goat3d_normal3f(1, 0, 0); 1.147 - goat3d_vertex3f(-1, -1, 1); 1.148 - goat3d_vertex3f(-1, -1, -1); 1.149 - goat3d_vertex3f(-1, 1, -1); 1.150 - goat3d_vertex3f(-1, 1, 1); 1.151 + goat3d_texcoord2f(0, 0); 1.152 + goat3d_vertex3f(hsz, -hsz, hsz); 1.153 + goat3d_texcoord2f(1, 0); 1.154 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.155 + goat3d_texcoord2f(1, 1); 1.156 + goat3d_vertex3f(hsz, hsz, -hsz); 1.157 + goat3d_texcoord2f(0, 1); 1.158 + goat3d_vertex3f(hsz, hsz, hsz); 1.159 1.160 // -X 1.161 goat3d_normal3f(-1, 0, 0); 1.162 - goat3d_vertex3f(-1, -1, -1); 1.163 - goat3d_vertex3f(-1, -1, 1); 1.164 - goat3d_vertex3f(-1, 1, 1); 1.165 - goat3d_vertex3f(-1, 1, -1); 1.166 + goat3d_texcoord2f(0, 0); 1.167 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.168 + goat3d_texcoord2f(1, 0); 1.169 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.170 + goat3d_texcoord2f(1, 1); 1.171 + goat3d_vertex3f(-hsz, hsz, hsz); 1.172 + goat3d_texcoord2f(0, 1); 1.173 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.174 1.175 // +Y 1.176 goat3d_normal3f(0, 1, 0); 1.177 - goat3d_vertex3f(-1, 1, 1); 1.178 - goat3d_vertex3f(1, 1, 1); 1.179 - goat3d_vertex3f(1, 1, -1); 1.180 - goat3d_vertex3f(-1, 1, -1); 1.181 + goat3d_texcoord2f(0, 0); 1.182 + goat3d_vertex3f(-hsz, hsz, hsz); 1.183 + goat3d_texcoord2f(1, 0); 1.184 + goat3d_vertex3f(hsz, hsz, hsz); 1.185 + goat3d_texcoord2f(1, 1); 1.186 + goat3d_vertex3f(hsz, hsz, -hsz); 1.187 + goat3d_texcoord2f(0, 1); 1.188 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.189 1.190 // -Y 1.191 goat3d_normal3f(0, -1, 0); 1.192 - goat3d_vertex3f(-1, -1, -1); 1.193 - goat3d_vertex3f(1, -1, -1); 1.194 - goat3d_vertex3f(1, -1, 1); 1.195 - goat3d_vertex3f(-1, -1, 1); 1.196 + goat3d_texcoord2f(0, 0); 1.197 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.198 + goat3d_texcoord2f(1, 0); 1.199 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.200 + goat3d_texcoord2f(1, 1); 1.201 + goat3d_vertex3f(hsz, -hsz, hsz); 1.202 + goat3d_texcoord2f(0, 1); 1.203 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.204 1.205 // +Z 1.206 goat3d_normal3f(0, 0, 1); 1.207 - goat3d_vertex3f(-1, -1, 1); 1.208 - goat3d_vertex3f(1, -1, 1); 1.209 - goat3d_vertex3f(1, -1, 1); 1.210 - goat3d_vertex3f(-1, -1, 1); 1.211 + goat3d_texcoord2f(0, 0); 1.212 + goat3d_vertex3f(-hsz, -hsz, hsz); 1.213 + goat3d_texcoord2f(1, 0); 1.214 + goat3d_vertex3f(hsz, -hsz, hsz); 1.215 + goat3d_texcoord2f(1, 1); 1.216 + goat3d_vertex3f(hsz, hsz, hsz); 1.217 + goat3d_texcoord2f(0, 1); 1.218 + goat3d_vertex3f(-hsz, hsz, hsz); 1.219 1.220 // -Z 1.221 goat3d_normal3f(0, 0, -1); 1.222 - goat3d_vertex3f(-1, -1, 1); 1.223 - goat3d_vertex3f(1, -1, 1); 1.224 - goat3d_vertex3f(1, -1, -1); 1.225 - goat3d_vertex3f(-1, -1, -1); 1.226 + goat3d_texcoord2f(0, 0); 1.227 + goat3d_vertex3f(hsz, -hsz, -hsz); 1.228 + goat3d_texcoord2f(1, 0); 1.229 + goat3d_vertex3f(-hsz, -hsz, -hsz); 1.230 + goat3d_texcoord2f(1, 1); 1.231 + goat3d_vertex3f(-hsz, hsz, -hsz); 1.232 + goat3d_texcoord2f(0, 1); 1.233 + goat3d_vertex3f(hsz, hsz, -hsz); 1.234 goat3d_end(); 1.235 +} 1.236 1.237 - return mesh; 1.238 +void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub) 1.239 +{ 1.240 + gen_sphere_part(mesh, rad, usub, vsub, 1.0, 1.0); 1.241 } 1.242 + 1.243 +#define sphere_vertex(u, v) \ 1.244 + do { \ 1.245 + float x, y, z, theta, phi; \ 1.246 + float costheta, sinphi; \ 1.247 + theta = (u) * 2.0 * M_PI; \ 1.248 + phi = (v) * M_PI; \ 1.249 + costheta = cos(theta); \ 1.250 + sinphi = sin(phi); \ 1.251 + x = costheta * sinphi; \ 1.252 + y = cos(phi); \ 1.253 + z = sin(theta) * sinphi; \ 1.254 + goat3d_normal3f(x, y, z); \ 1.255 + goat3d_texcoord2f(u, v); \ 1.256 + goat3d_vertex3f(rad * x, rad * y, rad * z); \ 1.257 + } while(0) 1.258 + 1.259 +void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax) 1.260 +{ 1.261 + int i, j; 1.262 + float u, v, du, dv; 1.263 + 1.264 + if(usub < 3) usub = 3; 1.265 + if(vsub < 3) vsub = 3; 1.266 + 1.267 + du = umax / (float)usub; 1.268 + dv = vmax / (float)vsub; 1.269 + 1.270 + goat3d_begin(mesh, GOAT3D_QUADS); 1.271 + 1.272 + u = 0.0; 1.273 + for(i=0; i<usub; i++) { 1.274 + v = 0.0; 1.275 + for(j=0; j<vsub; j++) { 1.276 + sphere_vertex(u, v); 1.277 + sphere_vertex(u + du, v); 1.278 + sphere_vertex(u + du, v + dv); 1.279 + sphere_vertex(u, v + dv); 1.280 + v += dv; 1.281 + } 1.282 + u += du; 1.283 + } 1.284 + goat3d_end(); 1.285 +} 1.286 + 1.287 + 1.288 +void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub) 1.289 +{ 1.290 + gen_torus_part(mesh, inner, outer, usub, vsub, 1.0, 0.0, 1.0); 1.291 +} 1.292 + 1.293 +#define torus_vertex(u, v) \ 1.294 + do { \ 1.295 + float rx, ry, rz, cx, cy, cz, theta, phi; \ 1.296 + float costheta, sintheta, sinphi; \ 1.297 + theta = (u) * 2.0 * M_PI; \ 1.298 + phi = (v) * 2.0 * M_PI; \ 1.299 + costheta = cos(theta); \ 1.300 + sintheta = sin(theta); \ 1.301 + sinphi = sin(phi); \ 1.302 + cx = costheta * inner; \ 1.303 + cy = 0.0f; \ 1.304 + cz = sintheta * inner; \ 1.305 + rx = costheta * sinphi; \ 1.306 + ry = cos(phi); \ 1.307 + rz = sintheta * sinphi; \ 1.308 + goat3d_normal3f(rx, ry, rz); \ 1.309 + goat3d_texcoord2f(u, v); \ 1.310 + goat3d_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \ 1.311 + } while(0) 1.312 + 1.313 +void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer, 1.314 + int usub, int vsub, float umax, float vmin, float vmax) 1.315 +{ 1.316 + int i, j; 1.317 + float u, v, du, dv; 1.318 + 1.319 + if(usub < 3) usub = 3; 1.320 + if(vsub < 3) vsub = 3; 1.321 + 1.322 + du = umax / (float)usub; 1.323 + dv = (vmax - vmin) / (float)vsub; 1.324 + 1.325 + goat3d_begin(mesh, GOAT3D_QUADS); 1.326 + 1.327 + u = 0.0; 1.328 + for(i=0; i<usub; i++) { 1.329 + v = vmin; 1.330 + for(j=0; j<vsub; j++) { 1.331 + torus_vertex(u, v); 1.332 + torus_vertex(u + du, v); 1.333 + torus_vertex(u + du, v + dv); 1.334 + torus_vertex(u, v + dv); 1.335 + v += dv; 1.336 + } 1.337 + u += du; 1.338 + } 1.339 + goat3d_end(); 1.340 +}