goat3d

view 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 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
12 enum { BOX, SPHERE, TORUS };
14 void gen_box(struct goat3d_mesh *mesh, float size);
15 void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub);
16 void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax);
17 void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub);
18 void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer,
19 int usub, int vsub, float umax, float vmin, float vmax);
22 int main(int argc, char **argv)
23 {
24 int i, prim = BOX;
25 int usub = DEF_USUB;
26 int vsub = DEF_VSUB;
27 float size = DEF_SIZE;
28 float outer = DEF_OUTER;
29 struct goat3d *goat;
30 struct goat3d_material *mtl;
31 struct goat3d_mesh *mesh;
32 const char *fname = 0;
34 for(i=1; i<argc; i++) {
35 if(strcmp(argv[i], "-box") == 0) {
36 prim = BOX;
38 } else if(strcmp(argv[i], "-sphere") == 0) {
39 prim = SPHERE;
41 } else if(strcmp(argv[i], "-torus") == 0) {
42 prim = TORUS;
44 } else if(strcmp(argv[i], "-rad") == 0 || strcmp(argv[i], "-size") == 0
45 || strcmp(argv[i], "-inner") == 0) {
46 if((size = atof(argv[++i])) == 0.0) {
47 fprintf(stderr, "invalid size\n");
48 return 1;
49 }
51 } else if(strcmp(argv[i], "-outer") == 0) {
52 if((outer = atof(argv[++i])) == 0.0) {
53 fprintf(stderr, "invalid outer radius\n");
54 return 1;
55 }
57 } else if(strcmp(argv[i], "-usub") == 0) {
58 if(!(usub = atoi(argv[++i]))) {
59 fprintf(stderr, "invalid usub\n");
60 return 1;
61 }
63 } else if(strcmp(argv[i], "-vsub") == 0) {
64 if(!(vsub = atoi(argv[++i]))) {
65 fprintf(stderr, "invalid vsub\n");
66 return 1;
67 }
69 } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
70 printf("Usage: %s [filename] [options]\n", argv[0]);
71 printf("Options:\n");
72 printf(" -box create box (default)\n");
73 printf(" -sphere create sphere\n");
74 printf(" -torus create torus\n");
75 printf(" -size <n>, -rad <n>, -inner <n> (default: %g)\n", DEF_SIZE);
76 printf(" -outer <n> torus outer radius (default: %g)\n", DEF_OUTER);
77 printf(" -usub <n> subdivisions along the horizontal direction (default: %d)\n", DEF_USUB);
78 printf(" -vsub <n> subdivisions along the vertical direction (default: %d)\n", DEF_VSUB);
79 printf(" -h, -help print usage information and exit\n");
80 return 0;
82 } else {
83 if(fname) {
84 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
85 return 1;
86 }
87 fname = argv[i];
88 }
89 }
91 if(!fname) {
92 fname = "out.xml";
93 }
95 goat = goat3d_create();
96 goat3d_set_name(goat, fname);
98 mtl = goat3d_create_mtl();
99 goat3d_set_mtl_name(mtl, "mat");
100 goat3d_set_mtl_attrib4f(mtl, GOAT3D_MAT_ATTR_DIFFUSE, 1, 0, 0, 1);
101 goat3d_add_mtl(goat, mtl);
103 mesh = goat3d_create_mesh();
105 switch(prim) {
106 case BOX:
107 gen_box(mesh, size);
108 break;
110 case SPHERE:
111 gen_sphere(mesh, size, usub, vsub);
112 break;
114 case TORUS:
115 gen_torus(mesh, size, outer, usub, vsub);
116 break;
118 default:
119 return 1;
120 }
121 goat3d_set_mesh_mtl(mesh, mtl);
122 goat3d_add_mesh(goat, mesh);
124 goat3d_setopt(goat, GOAT3D_OPT_SAVEXML, 1);
125 goat3d_save(goat, fname);
127 goat3d_free(goat);
128 return 0;
129 }
131 void gen_box(struct goat3d_mesh *mesh, float size)
132 {
133 float hsz = size / 2.0;
135 goat3d_begin(mesh, GOAT3D_QUADS);
136 // +X
137 goat3d_normal3f(1, 0, 0);
138 goat3d_texcoord2f(0, 0);
139 goat3d_vertex3f(hsz, -hsz, hsz);
140 goat3d_texcoord2f(1, 0);
141 goat3d_vertex3f(hsz, -hsz, -hsz);
142 goat3d_texcoord2f(1, 1);
143 goat3d_vertex3f(hsz, hsz, -hsz);
144 goat3d_texcoord2f(0, 1);
145 goat3d_vertex3f(hsz, hsz, hsz);
147 // -X
148 goat3d_normal3f(-1, 0, 0);
149 goat3d_texcoord2f(0, 0);
150 goat3d_vertex3f(-hsz, -hsz, -hsz);
151 goat3d_texcoord2f(1, 0);
152 goat3d_vertex3f(-hsz, -hsz, hsz);
153 goat3d_texcoord2f(1, 1);
154 goat3d_vertex3f(-hsz, hsz, hsz);
155 goat3d_texcoord2f(0, 1);
156 goat3d_vertex3f(-hsz, hsz, -hsz);
158 // +Y
159 goat3d_normal3f(0, 1, 0);
160 goat3d_texcoord2f(0, 0);
161 goat3d_vertex3f(-hsz, hsz, hsz);
162 goat3d_texcoord2f(1, 0);
163 goat3d_vertex3f(hsz, hsz, hsz);
164 goat3d_texcoord2f(1, 1);
165 goat3d_vertex3f(hsz, hsz, -hsz);
166 goat3d_texcoord2f(0, 1);
167 goat3d_vertex3f(-hsz, hsz, -hsz);
169 // -Y
170 goat3d_normal3f(0, -1, 0);
171 goat3d_texcoord2f(0, 0);
172 goat3d_vertex3f(-hsz, -hsz, -hsz);
173 goat3d_texcoord2f(1, 0);
174 goat3d_vertex3f(hsz, -hsz, -hsz);
175 goat3d_texcoord2f(1, 1);
176 goat3d_vertex3f(hsz, -hsz, hsz);
177 goat3d_texcoord2f(0, 1);
178 goat3d_vertex3f(-hsz, -hsz, hsz);
180 // +Z
181 goat3d_normal3f(0, 0, 1);
182 goat3d_texcoord2f(0, 0);
183 goat3d_vertex3f(-hsz, -hsz, hsz);
184 goat3d_texcoord2f(1, 0);
185 goat3d_vertex3f(hsz, -hsz, hsz);
186 goat3d_texcoord2f(1, 1);
187 goat3d_vertex3f(hsz, hsz, hsz);
188 goat3d_texcoord2f(0, 1);
189 goat3d_vertex3f(-hsz, hsz, hsz);
191 // -Z
192 goat3d_normal3f(0, 0, -1);
193 goat3d_texcoord2f(0, 0);
194 goat3d_vertex3f(hsz, -hsz, -hsz);
195 goat3d_texcoord2f(1, 0);
196 goat3d_vertex3f(-hsz, -hsz, -hsz);
197 goat3d_texcoord2f(1, 1);
198 goat3d_vertex3f(-hsz, hsz, -hsz);
199 goat3d_texcoord2f(0, 1);
200 goat3d_vertex3f(hsz, hsz, -hsz);
201 goat3d_end();
202 }
204 void gen_sphere(struct goat3d_mesh *mesh, float rad, int usub, int vsub)
205 {
206 gen_sphere_part(mesh, rad, usub, vsub, 1.0, 1.0);
207 }
209 #define sphere_vertex(u, v) \
210 do { \
211 float x, y, z, theta, phi; \
212 float costheta, sinphi; \
213 theta = (u) * 2.0 * M_PI; \
214 phi = (v) * M_PI; \
215 costheta = cos(theta); \
216 sinphi = sin(phi); \
217 x = costheta * sinphi; \
218 y = cos(phi); \
219 z = sin(theta) * sinphi; \
220 goat3d_normal3f(x, y, z); \
221 goat3d_texcoord2f(u, v); \
222 goat3d_vertex3f(rad * x, rad * y, rad * z); \
223 } while(0)
225 void gen_sphere_part(struct goat3d_mesh *mesh, float rad, int usub, int vsub, float umax, float vmax)
226 {
227 int i, j;
228 float u, v, du, dv;
230 if(usub < 3) usub = 3;
231 if(vsub < 3) vsub = 3;
233 du = umax / (float)usub;
234 dv = vmax / (float)vsub;
236 goat3d_begin(mesh, GOAT3D_QUADS);
238 u = 0.0;
239 for(i=0; i<usub; i++) {
240 v = 0.0;
241 for(j=0; j<vsub; j++) {
242 sphere_vertex(u, v);
243 sphere_vertex(u + du, v);
244 sphere_vertex(u + du, v + dv);
245 sphere_vertex(u, v + dv);
246 v += dv;
247 }
248 u += du;
249 }
250 goat3d_end();
251 }
254 void gen_torus(struct goat3d_mesh *mesh, float inner, float outer, int usub, int vsub)
255 {
256 gen_torus_part(mesh, inner, outer, usub, vsub, 1.0, 0.0, 1.0);
257 }
259 #define torus_vertex(u, v) \
260 do { \
261 float rx, ry, rz, cx, cy, cz, theta, phi; \
262 float costheta, sintheta, sinphi; \
263 theta = (u) * 2.0 * M_PI; \
264 phi = (v) * 2.0 * M_PI; \
265 costheta = cos(theta); \
266 sintheta = sin(theta); \
267 sinphi = sin(phi); \
268 cx = costheta * inner; \
269 cy = 0.0f; \
270 cz = sintheta * inner; \
271 rx = costheta * sinphi; \
272 ry = cos(phi); \
273 rz = sintheta * sinphi; \
274 goat3d_normal3f(rx, ry, rz); \
275 goat3d_texcoord2f(u, v); \
276 goat3d_vertex3f(outer * rx + cx, outer * ry + cy, outer * rz + cz); \
277 } while(0)
279 void gen_torus_part(struct goat3d_mesh *mesh, float inner, float outer,
280 int usub, int vsub, float umax, float vmin, float vmax)
281 {
282 int i, j;
283 float u, v, du, dv;
285 if(usub < 3) usub = 3;
286 if(vsub < 3) vsub = 3;
288 du = umax / (float)usub;
289 dv = (vmax - vmin) / (float)vsub;
291 goat3d_begin(mesh, GOAT3D_QUADS);
293 u = 0.0;
294 for(i=0; i<usub; i++) {
295 v = vmin;
296 for(j=0; j<vsub; j++) {
297 torus_vertex(u, v);
298 torus_vertex(u + du, v);
299 torus_vertex(u + du, v + dv);
300 torus_vertex(u, v + dv);
301 v += dv;
302 }
303 u += du;
304 }
305 goat3d_end();
306 }