goat3d

annotate generators/goatprim/main.c @ 52:cb5414f406eb

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