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 +}