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