goat3d

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