goat3d

view generators/goatprim/main.c @ 64:99715321ad6d

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Apr 2014 08:53:42 +0300
parents 1d85d7dd0038
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <math.h>
5 #include "goat3d.h"
7 #define DEF_USUB 16
8 #define DEF_VSUB 8
9 #define DEF_SIZE 1.0
10 #define DEF_OUTER 0.25
11 #define DEF_DIFFUSE_R 0.6
12 #define DEF_DIFFUSE_G 0.6
13 #define DEF_DIFFUSE_B 0.6
14 #define DEF_SPECULAR_R 0.8
15 #define DEF_SPECULAR_G 0.8
16 #define DEF_SPECULAR_B 0.8
17 #define DEF_SHININESS 60.0
19 enum { BOX, SPHERE, TORUS };
21 void gen_box(struct goat3d_mesh *mesh, float size);
22 void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub);
23 void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax);
24 void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub);
25 void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer,
26 int usub, int vsub, float umax, float vmin, float vmax);
29 int main(int argc, char **argv)
30 {
31 int i, prim = BOX;
32 int usub = DEF_USUB;
33 int vsub = DEF_VSUB;
34 float size = DEF_SIZE;
35 float outer = DEF_OUTER;
36 float diffuse[] = {DEF_DIFFUSE_R, DEF_DIFFUSE_G, DEF_DIFFUSE_B, 1.0};
37 float specular[] = {DEF_SPECULAR_R, DEF_SPECULAR_G, DEF_SPECULAR_B, 1.0};
38 float shininess = DEF_SHININESS;
39 struct goat3d *goat;
40 struct goat3d_material *mtl;
41 struct goat3d_mesh *mesh;
42 const char *fname = 0;
44 for(i=1; i<argc; i++) {
45 if(strcmp(argv[i], "-box") == 0) {
46 prim = BOX;
48 } else if(strcmp(argv[i], "-sphere") == 0) {
49 prim = SPHERE;
51 } else if(strcmp(argv[i], "-torus") == 0) {
52 prim = TORUS;
54 } else if(strcmp(argv[i], "-rad") == 0 || strcmp(argv[i], "-size") == 0
55 || strcmp(argv[i], "-inner") == 0) {
56 if((size = atof(argv[++i])) == 0.0) {
57 fprintf(stderr, "invalid size\n");
58 return 1;
59 }
61 } else if(strcmp(argv[i], "-outer") == 0) {
62 if((outer = atof(argv[++i])) == 0.0) {
63 fprintf(stderr, "invalid outer radius\n");
64 return 1;
65 }
67 } else if(strcmp(argv[i], "-usub") == 0) {
68 if(!(usub = atoi(argv[++i]))) {
69 fprintf(stderr, "invalid usub\n");
70 return 1;
71 }
73 } else if(strcmp(argv[i], "-vsub") == 0) {
74 if(!(vsub = atoi(argv[++i]))) {
75 fprintf(stderr, "invalid vsub\n");
76 return 1;
77 }
79 } else if(strcmp(argv[i], "-diffuse") == 0) {
80 if(!argv[i + 1] || !argv[i + 2] || !argv[i + 3]) {
81 fprintf(stderr, "-diffuse must be followed by 3 numbers (r, g, b)\n");
82 return 1;
83 }
84 diffuse[0] = atof(argv[++i]);
85 diffuse[1] = atof(argv[++i]);
86 diffuse[2] = atof(argv[++i]);
88 } else if(strcmp(argv[i], "-specular") == 0) {
89 if(!argv[i + 1] || !argv[i + 2] || !argv[i + 3]) {
90 fprintf(stderr, "-specular must be followed by 3 numbers (r, g, b)\n");
91 return 1;
92 }
93 specular[0] = atof(argv[++i]);
94 specular[1] = atof(argv[++i]);
95 specular[2] = atof(argv[++i]);
97 } else if(strcmp(argv[i], "-shininess") == 0) {
98 if(!argv[i + 1]) {
99 fprintf(stderr, "-shininess must be followed by a number\n");
100 return 1;
101 }
102 shininess = atof(argv[++i]);
104 } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
105 printf("Usage: %s [filename] [options]\n", argv[0]);
106 printf("Options:\n");
107 printf(" -box create box (default)\n");
108 printf(" -sphere create sphere\n");
109 printf(" -torus create torus\n");
110 printf(" -size <n>, -rad <n>, -inner <n> (default: %g)\n", DEF_SIZE);
111 printf(" -outer <n> torus outer radius (default: %g)\n", DEF_OUTER);
112 printf(" -usub <n> subdivisions along the horizontal direction (default: %d)\n", DEF_USUB);
113 printf(" -vsub <n> subdivisions along the vertical direction (default: %d)\n", DEF_VSUB);
114 printf(" -diffuse <r> <g> <b> material diffuse color (default: %g %g %g)\n", DEF_DIFFUSE_R, DEF_DIFFUSE_G, DEF_DIFFUSE_B);
115 printf(" -specular <r> <g> <b> material specular color (default: %g %g %g)\n", DEF_SPECULAR_R, DEF_SPECULAR_G, DEF_SPECULAR_B);
116 printf(" -shininess <n> material shininess (default: %g)\n", DEF_SHININESS);
117 printf(" -h, -help print usage information and exit\n");
118 return 0;
120 } else {
121 if(fname) {
122 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
123 return 1;
124 }
125 fname = argv[i];
126 }
127 }
129 if(!fname) {
130 fname = "out.xml";
131 }
133 goat = goat3d_create();
134 goat3d_set_name(goat, fname);
136 mtl = goat3d_create_mtl();
137 goat3d_set_mtl_name(mtl, "mat");
138 goat3d_set_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE, diffuse);
139 goat3d_set_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR, specular);
140 goat3d_set_mtl_attrib1f(mtl, GOAT3D_MAT_ATTR_SHININESS, shininess);
141 goat3d_add_mtl(goat, mtl);
143 mesh = goat3d_create_mesh();
145 switch(prim) {
146 case BOX:
147 gen_box(mesh, size);
148 break;
150 case SPHERE:
151 gen_sphere(mesh, size, usub, vsub);
152 break;
154 case TORUS:
155 gen_torus(mesh, size, outer, usub, vsub);
156 break;
158 default:
159 return 1;
160 }
161 goat3d_set_mesh_mtl(mesh, mtl);
162 goat3d_add_mesh(goat, mesh);
164 goat3d_setopt(goat, GOAT3D_OPT_SAVEXML, 1);
165 goat3d_save(goat, fname);
167 goat3d_free(goat);
168 return 0;
169 }
171 void gen_box(struct goat3d_mesh *mesh, float size)
172 {
173 float hsz = size / 2.0;
175 goat3d_begin(mesh, GOAT3D_QUADS);
176 // +X
177 goat3d_normal3f(1, 0, 0);
178 goat3d_texcoord2f(0, 0);
179 goat3d_vertex3f(hsz, -hsz, hsz);
180 goat3d_texcoord2f(1, 0);
181 goat3d_vertex3f(hsz, -hsz, -hsz);
182 goat3d_texcoord2f(1, 1);
183 goat3d_vertex3f(hsz, hsz, -hsz);
184 goat3d_texcoord2f(0, 1);
185 goat3d_vertex3f(hsz, hsz, hsz);
187 // -X
188 goat3d_normal3f(-1, 0, 0);
189 goat3d_texcoord2f(0, 0);
190 goat3d_vertex3f(-hsz, -hsz, -hsz);
191 goat3d_texcoord2f(1, 0);
192 goat3d_vertex3f(-hsz, -hsz, hsz);
193 goat3d_texcoord2f(1, 1);
194 goat3d_vertex3f(-hsz, hsz, hsz);
195 goat3d_texcoord2f(0, 1);
196 goat3d_vertex3f(-hsz, hsz, -hsz);
198 // +Y
199 goat3d_normal3f(0, 1, 0);
200 goat3d_texcoord2f(0, 0);
201 goat3d_vertex3f(-hsz, hsz, hsz);
202 goat3d_texcoord2f(1, 0);
203 goat3d_vertex3f(hsz, hsz, hsz);
204 goat3d_texcoord2f(1, 1);
205 goat3d_vertex3f(hsz, hsz, -hsz);
206 goat3d_texcoord2f(0, 1);
207 goat3d_vertex3f(-hsz, hsz, -hsz);
209 // -Y
210 goat3d_normal3f(0, -1, 0);
211 goat3d_texcoord2f(0, 0);
212 goat3d_vertex3f(-hsz, -hsz, -hsz);
213 goat3d_texcoord2f(1, 0);
214 goat3d_vertex3f(hsz, -hsz, -hsz);
215 goat3d_texcoord2f(1, 1);
216 goat3d_vertex3f(hsz, -hsz, hsz);
217 goat3d_texcoord2f(0, 1);
218 goat3d_vertex3f(-hsz, -hsz, hsz);
220 // +Z
221 goat3d_normal3f(0, 0, 1);
222 goat3d_texcoord2f(0, 0);
223 goat3d_vertex3f(-hsz, -hsz, hsz);
224 goat3d_texcoord2f(1, 0);
225 goat3d_vertex3f(hsz, -hsz, hsz);
226 goat3d_texcoord2f(1, 1);
227 goat3d_vertex3f(hsz, hsz, hsz);
228 goat3d_texcoord2f(0, 1);
229 goat3d_vertex3f(-hsz, hsz, hsz);
231 // -Z
232 goat3d_normal3f(0, 0, -1);
233 goat3d_texcoord2f(0, 0);
234 goat3d_vertex3f(hsz, -hsz, -hsz);
235 goat3d_texcoord2f(1, 0);
236 goat3d_vertex3f(-hsz, -hsz, -hsz);
237 goat3d_texcoord2f(1, 1);
238 goat3d_vertex3f(-hsz, hsz, -hsz);
239 goat3d_texcoord2f(0, 1);
240 goat3d_vertex3f(hsz, hsz, -hsz);
241 goat3d_end();
242 }
244 void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub)
245 {
246 gen_sphere_part(mesh, rad, usub, vsub, 1.0, 1.0);
247 }
249 #define sphere_vertex(u, v) \
250 do { \
251 float x, y, z, theta, phi; \
252 float costheta, sinphi; \
253 theta = (u) * 2.0 * M_PI; \
254 phi = (v) * M_PI; \
255 costheta = cos(theta); \
256 sinphi = sin(phi); \
257 x = costheta * sinphi; \
258 y = cos(phi); \
259 z = sin(theta) * sinphi; \
260 goat3d_normal3f(x, y, z); \
261 goat3d_texcoord2f(u, v); \
262 goat3d_vertex3f(rad * x, rad * y, rad * z); \
263 } while(0)
265 void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax)
266 {
267 int i, j;
268 float u, v, du, dv;
270 if(usub < 3) usub = 3;
271 if(vsub < 3) vsub = 3;
273 du = umax / (float)usub;
274 dv = vmax / (float)vsub;
276 goat3d_begin(mesh, GOAT3D_QUADS);
278 u = 0.0;
279 for(i=0; i<usub; i++) {
280 v = 0.0;
281 for(j=0; j<vsub; j++) {
282 sphere_vertex(u, v);
283 sphere_vertex(u + du, v);
284 sphere_vertex(u + du, v + dv);
285 sphere_vertex(u, v + dv);
286 v += dv;
287 }
288 u += du;
289 }
290 goat3d_end();
291 }
294 void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub)
295 {
296 gen_torus_part(mesh, inner, outer, usub, vsub, 1.0, 0.0, 1.0);
297 }
299 #define torus_vertex(u, v) \
300 do { \
301 float rx, ry, rz, cx, cy, cz, theta, phi; \
302 float costheta, sintheta, sinphi; \
303 theta = (u) * 2.0 * M_PI; \
304 phi = (v) * 2.0 * M_PI; \
305 costheta = cos(theta); \
306 sintheta = sin(theta); \
307 sinphi = sin(phi); \
308 cx = costheta * inner; \
309 cy = 0.0f; \
310 cz = sintheta * inner; \
311 rx = costheta * sinphi; \
312 ry = cos(phi); \
313 rz = sintheta * sinphi; \
314 goat3d_normal3f(rx, ry, rz); \
315 goat3d_texcoord2f(u, v); \
316 goat3d_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \
317 } while(0)
319 void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer,
320 int usub, int vsub, float umax, float vmin, float vmax)
321 {
322 int i, j;
323 float u, v, du, dv;
325 if(usub < 3) usub = 3;
326 if(vsub < 3) vsub = 3;
328 du = umax / (float)usub;
329 dv = (vmax - vmin) / (float)vsub;
331 goat3d_begin(mesh, GOAT3D_QUADS);
333 u = 0.0;
334 for(i=0; i<usub; i++) {
335 v = vmin;
336 for(j=0; j<vsub; j++) {
337 torus_vertex(u, v);
338 torus_vertex(u + du, v);
339 torus_vertex(u + du, v + dv);
340 torus_vertex(u, v + dv);
341 v += dv;
342 }
343 u += du;
344 }
345 goat3d_end();
346 }