gpuray_glsl

annotate src/scene_load.cc @ 4:2ed3da7dc0bc

broken
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 10 Nov 2014 01:26:00 +0200
parents f234630e38ff
children
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <math.h>
nuclear@0 3 #include <map>
nuclear@0 4 #include "scene.h"
nuclear@0 5 #include "sphere.h"
nuclear@0 6 #include "plane.h"
nuclear@0 7 #include "box.h"
nuclear@4 8 #include "cone.h"
nuclear@0 9 #include "light.h"
nuclear@0 10 #include "camera.h"
nuclear@0 11 #include "texture.h"
nuclear@0 12
nuclear@0 13 static bool parse_material(char **argv, Material *mtl, std::string *name);
nuclear@0 14 static Object *parse_sphere(char **argv, const std::map<std::string, Material> &materials);
nuclear@0 15 static Object *parse_plane(char **argv, const std::map<std::string, Material> &materials);
nuclear@0 16 static Object *parse_box(char **argv, const std::map<std::string, Material> &materials);
nuclear@4 17 static Object *parse_cone(char **argv, const std::map<std::string, Material> &materials);
nuclear@0 18 static Light *parse_light(char **argv);
nuclear@0 19 static Camera *parse_camera(char **argv);
nuclear@0 20 static bool parse_env(char **argv, Scene *scn);
nuclear@0 21 static bool parse_xform(char **argv, Scene *scn);
nuclear@0 22 static bool parse_vec(char **argv, Vector3 *vptr);
nuclear@0 23
nuclear@0 24 static char *strip_space(char *s);
nuclear@0 25 static char **split_args(char *args);
nuclear@0 26
nuclear@0 27 bool load_scene_file(Scene *scn, const char *fname)
nuclear@0 28 {
nuclear@0 29 FILE *fp;
nuclear@0 30 if(!(fp = fopen(fname, "rb"))) {
nuclear@0 31 fprintf(stderr, "%s: failed to open scene file: %s: %s\n", __FUNCTION__, fname, strerror(errno));
nuclear@0 32 return false;
nuclear@0 33 }
nuclear@0 34
nuclear@0 35 char buf[512];
nuclear@0 36 std::map<std::string, Material> materials;
nuclear@0 37
nuclear@0 38 int lineno = 0;
nuclear@0 39 while(fgets(buf, sizeof buf, fp)) {
nuclear@0 40 char *line = strip_space(buf);
nuclear@0 41
nuclear@0 42 lineno++;
nuclear@0 43
nuclear@0 44 if(!*line || *line == '\n' || *line == '#') {
nuclear@0 45 continue;
nuclear@0 46 }
nuclear@0 47
nuclear@0 48 if(strstr(line, "material") == line) {
nuclear@0 49 Material mtl;
nuclear@0 50 std::string name;
nuclear@0 51
nuclear@0 52 char *args = strip_space(line + strlen("material"));
nuclear@0 53 if(!parse_material(split_args(args), &mtl, &name)) {
nuclear@0 54 goto err;
nuclear@0 55 }
nuclear@0 56 materials[name] = mtl;
nuclear@0 57
nuclear@0 58 } else if(strstr(line, "sphere") == line) {
nuclear@0 59 char *args = strip_space(line + strlen("sphere"));
nuclear@0 60 Object *obj = parse_sphere(split_args(args), materials);
nuclear@0 61 if(!obj) {
nuclear@0 62 goto err;
nuclear@0 63 }
nuclear@0 64 scn->add_object(obj);
nuclear@0 65
nuclear@0 66 } else if(strstr(line, "plane") == line) {
nuclear@0 67 char *args = strip_space(line + strlen("plane"));
nuclear@0 68 Object *obj = parse_plane(split_args(args), materials);
nuclear@0 69 if(!obj) {
nuclear@0 70 goto err;
nuclear@0 71 }
nuclear@0 72 scn->add_object(obj);
nuclear@0 73
nuclear@0 74 } else if(strstr(line, "box") == line) {
nuclear@0 75 char *args = strip_space(line + strlen("box"));
nuclear@0 76 Object *obj = parse_box(split_args(args), materials);
nuclear@0 77 if(!obj) {
nuclear@0 78 goto err;
nuclear@0 79 }
nuclear@0 80 scn->add_object(obj);
nuclear@0 81
nuclear@4 82 } else if(strstr(line, "cone") == line) {
nuclear@4 83 char *args = strip_space(line + strlen("cone"));
nuclear@4 84 Object *obj = parse_cone(split_args(args), materials);
nuclear@4 85 if(!obj) {
nuclear@4 86 goto err;
nuclear@4 87 }
nuclear@4 88 scn->add_object(obj);
nuclear@4 89
nuclear@0 90 } else if(strstr(line, "light") == line) {
nuclear@0 91 char *args = strip_space(line + strlen("light"));
nuclear@0 92 Light *lt = parse_light(split_args(args));
nuclear@0 93 if(!lt) {
nuclear@0 94 goto err;
nuclear@0 95 }
nuclear@0 96 scn->add_light(lt);
nuclear@0 97
nuclear@0 98 } else if(strstr(line, "camera") == line) {
nuclear@0 99 char *args = strip_space(line + strlen("camera"));
nuclear@0 100 Camera *cam = parse_camera(split_args(args));
nuclear@0 101 if(!cam) {
nuclear@0 102 goto err;
nuclear@0 103 }
nuclear@0 104 scn->set_camera(cam);
nuclear@0 105
nuclear@0 106 } else if(strstr(line, "environment") == line) {
nuclear@0 107 char *args = strip_space(line + strlen("environment"));
nuclear@0 108 if(!parse_env(split_args(args), scn)) {
nuclear@0 109 goto err;
nuclear@0 110 }
nuclear@0 111
nuclear@0 112 } else if(strstr(line, "xform") == line) {
nuclear@0 113 char *args = strip_space(line + strlen("xform"));
nuclear@0 114 if(!parse_xform(split_args(args), scn)) {
nuclear@0 115 goto err;
nuclear@0 116 }
nuclear@0 117
nuclear@0 118 } else {
nuclear@0 119 fprintf(stderr, "%s error %s:%d: unknown command: %s\n", __FUNCTION__, fname, lineno, line);
nuclear@0 120 goto err;
nuclear@0 121 }
nuclear@0 122
nuclear@0 123 }
nuclear@0 124
nuclear@0 125 fclose(fp);
nuclear@0 126 return true;
nuclear@0 127
nuclear@0 128 err:
nuclear@0 129 fclose(fp);
nuclear@0 130 return false;
nuclear@0 131 }
nuclear@0 132
nuclear@0 133 bool save_scene_file(const Scene *scn, const char *fname)
nuclear@0 134 {
nuclear@0 135 FILE *fp;
nuclear@0 136 if(!(fp = fopen(fname, "wb"))) {
nuclear@0 137 fprintf(stderr, "%s: failed to save scene file: %s: %s\n", __FUNCTION__, fname, strerror(errno));
nuclear@0 138 return false;
nuclear@0 139 }
nuclear@0 140
nuclear@0 141 for(int i=0; i<scn->get_object_count(); i++) {
nuclear@0 142 // first write the material
nuclear@0 143 const Object *obj = scn->get_object(i);
nuclear@0 144 const Material *mat = &obj->material;
nuclear@0 145
nuclear@0 146 char name[128];
nuclear@0 147 sprintf(name, "mat%d", i);
nuclear@0 148
nuclear@0 149 fprintf(fp, "material -name %s", name);
nuclear@0 150 fprintf(fp, " -diffuse %.3f %.3f %.3f", mat->diffuse.x, mat->diffuse.y, mat->diffuse.z);
nuclear@0 151 fprintf(fp, " -specular %.3f %.3f %.3f", mat->specular.x, mat->specular.y, mat->specular.z);
nuclear@0 152 fprintf(fp, " -shininess %.3f", mat->shininess);
nuclear@0 153 fprintf(fp, " -emission %.3f %.3f %.3f", mat->emission.x, mat->emission.y, mat->emission.z);
nuclear@0 154 fprintf(fp, " -reflect %.3f", mat->reflectivity);
nuclear@0 155 fprintf(fp, " -trans %.3f", mat->transparency);
nuclear@0 156 fprintf(fp, " -ior %.3f", mat->ior);
nuclear@0 157 if(mat->tex) {
nuclear@0 158 fprintf(fp, " -texture %s", mat->tex->get_name());
nuclear@0 159 }
nuclear@0 160 fputc('\n', fp);
nuclear@0 161
nuclear@0 162 // then write the object
nuclear@0 163 const Sphere *sph;
nuclear@0 164 const Plane *plane;
nuclear@0 165 const Box *box;
nuclear@4 166 const Cone *cone;
nuclear@0 167 if((sph = dynamic_cast<const Sphere*>(obj))) {
nuclear@0 168 fprintf(fp, "sphere -material %s", name);
nuclear@0 169 fprintf(fp, " -center %.3f %.3f %.3f", sph->pos.x, sph->pos.y, sph->pos.z);
nuclear@0 170 fprintf(fp, " -radius %.3f\n", sph->radius);
nuclear@0 171 } else if((plane = dynamic_cast<const Plane*>(obj))) {
nuclear@0 172 fprintf(fp, "plane -material %s", name);
nuclear@0 173 fprintf(fp, " -normal %.3f %.3f %.3f", plane->normal.x, plane->normal.y, plane->normal.z);
nuclear@0 174 fprintf(fp, " -distance %.3f\n", plane->dist);
nuclear@0 175 } else if((box = dynamic_cast<const Box*>(obj))) {
nuclear@0 176 fprintf(fp, "box -material %s", name);
nuclear@0 177 fprintf(fp, " -min %.3f %.3f %.3f", box->min.x, box->min.y, box->min.z);
nuclear@0 178 fprintf(fp, " -max %.3f %.3f %.3f\n", box->max.x, box->max.y, box->max.z);
nuclear@4 179 } else if((cone = dynamic_cast<const Cone*>(obj))) {
nuclear@4 180 fprintf(fp, "cone -material %s", name);
nuclear@4 181 fprintf(fp, " -angle %g", RAD_TO_DEG(cone->angle));
nuclear@4 182 fprintf(fp, " -start %g -end %g\n", cone->ymin, cone->ymax);
nuclear@0 183 }
nuclear@0 184 }
nuclear@0 185
nuclear@0 186 for(int i=0; i<scn->get_light_count(); i++) {
nuclear@0 187 const Light *lt = scn->get_light(i);
nuclear@0 188
nuclear@0 189 fprintf(fp, "light -position %.3f %.3f %.3f", lt->pos.x, lt->pos.y, lt->pos.z);
nuclear@0 190 fprintf(fp, " -color %.3f %.3f %.3f\n", lt->color.x, lt->color.y, lt->color.z);
nuclear@0 191 }
nuclear@0 192
nuclear@0 193 const TargetCamera *tcam = dynamic_cast<const TargetCamera*>(scn->get_camera());
nuclear@0 194 if(tcam) {
nuclear@0 195 Vector3 pos = tcam->get_position();
nuclear@0 196 fprintf(fp, "camera -position %.3f %.3f %.3f", pos.x, pos.y, pos.z);
nuclear@0 197 Vector3 targ = tcam->get_target();
nuclear@0 198 fprintf(fp, " -target %.3f %.3f %.3f", targ.x, targ.y, targ.z);
nuclear@0 199 fprintf(fp, " -fov %.3f\n", tcam->get_fov());
nuclear@0 200 }
nuclear@0 201
nuclear@0 202
nuclear@0 203 fclose(fp);
nuclear@0 204 return true;
nuclear@0 205 }
nuclear@0 206
nuclear@0 207 #define ARGERR(n) \
nuclear@0 208 do { fprintf(stderr, "failed to parse %s argument\n", (n)); return false; } while(0)
nuclear@0 209
nuclear@0 210 static bool parse_material(char **argv, Material *mtl, std::string *name)
nuclear@0 211 {
nuclear@0 212 char *endp;
nuclear@0 213
nuclear@0 214 for(int i=0; argv[i]; i++) {
nuclear@0 215 if(strcmp(argv[i], "-name") == 0) {
nuclear@0 216 *name = argv[++i];
nuclear@0 217 } else if(strcmp(argv[i], "-diffuse") == 0) {
nuclear@0 218 if(!parse_vec(argv + i + 1, &mtl->diffuse)) {
nuclear@0 219 ARGERR("diffuse");
nuclear@0 220 }
nuclear@0 221 argv += 3;
nuclear@0 222
nuclear@0 223 } else if(strcmp(argv[i], "-specular") == 0) {
nuclear@0 224 if(!parse_vec(argv + i + 1, &mtl->specular)) {
nuclear@0 225 ARGERR("specular");
nuclear@0 226 }
nuclear@0 227 argv += 3;
nuclear@0 228
nuclear@0 229 } else if(strcmp(argv[i], "-emission") == 0) {
nuclear@0 230 if(!parse_vec(argv + i + 1, &mtl->emission)) {
nuclear@0 231 ARGERR("emission");
nuclear@0 232 }
nuclear@0 233 argv += 3;
nuclear@0 234
nuclear@0 235 } else if(strcmp(argv[i], "-shininess") == 0) {
nuclear@0 236 mtl->shininess = strtod(argv[++i], &endp);
nuclear@0 237 if(endp == argv[i]) {
nuclear@0 238 ARGERR("shininess");
nuclear@0 239 }
nuclear@0 240
nuclear@0 241 } else if(strcmp(argv[i], "-reflect") == 0) {
nuclear@0 242 mtl->reflectivity = strtod(argv[++i], &endp);
nuclear@0 243 if(endp == argv[i]) {
nuclear@0 244 ARGERR("reflect");
nuclear@0 245 }
nuclear@0 246
nuclear@0 247 } else if(strcmp(argv[i], "-trans") == 0) {
nuclear@0 248 mtl->transparency = strtod(argv[++i], &endp);
nuclear@0 249 if(endp == argv[i]) {
nuclear@0 250 ARGERR("trans");
nuclear@0 251 }
nuclear@0 252
nuclear@0 253 } else if(strcmp(argv[i], "-ior") == 0) {
nuclear@0 254 mtl->ior = strtod(argv[++i], &endp);
nuclear@0 255 if(endp == argv[i]) {
nuclear@0 256 ARGERR("ior");
nuclear@0 257 }
nuclear@0 258
nuclear@0 259 } else if(strcmp(argv[i], "-texture") == 0) {
nuclear@0 260 if(!(mtl->tex = load_texture(argv[++i]))) {
nuclear@0 261 return false;
nuclear@0 262 }
nuclear@0 263
nuclear@0 264 } else {
nuclear@0 265 fprintf(stderr, "invalid material option: %s\n", argv[i]);
nuclear@0 266 return false;
nuclear@0 267 }
nuclear@0 268 }
nuclear@0 269 return true;
nuclear@0 270 }
nuclear@0 271
nuclear@0 272 static Object *parse_sphere(char **argv, const std::map<std::string, Material> &materials)
nuclear@0 273 {
nuclear@0 274 char *endp;
nuclear@0 275 Sphere *sph = new Sphere;
nuclear@0 276
nuclear@0 277 for(int i=0; argv[i]; i++) {
nuclear@0 278 if(strcmp(argv[i], "-name") == 0) {
nuclear@0 279 sph->set_name(argv[++i]);
nuclear@0 280
nuclear@0 281 } else if(strcmp(argv[i], "-center") == 0) {
nuclear@0 282 if(!parse_vec(argv + i + 1, &sph->pos)) {
nuclear@0 283 fprintf(stderr, "failed to parse sphere center vector\n");
nuclear@0 284 return 0;
nuclear@0 285 }
nuclear@0 286 argv += 3;
nuclear@0 287
nuclear@0 288 } else if(strcmp(argv[i], "-radius") == 0) {
nuclear@0 289 sph->radius = strtod(argv[++i], &endp);
nuclear@0 290 if(endp == argv[i]) {
nuclear@0 291 fprintf(stderr, "failed to parse sphere radius\n");
nuclear@0 292 return 0;
nuclear@0 293 }
nuclear@0 294
nuclear@0 295 } else if(strcmp(argv[i], "-material") == 0) {
nuclear@0 296 auto it = materials.find(argv[++i]);
nuclear@0 297 if(it == materials.end()) {
nuclear@0 298 fprintf(stderr, "material %s not found\n", argv[i]);
nuclear@0 299 return 0;
nuclear@0 300 }
nuclear@0 301
nuclear@0 302 sph->material = it->second;
nuclear@0 303 } else {
nuclear@0 304 fprintf(stderr, "invalid sphere option: %s\n", argv[i]);
nuclear@0 305 return 0;
nuclear@0 306 }
nuclear@0 307 }
nuclear@0 308
nuclear@0 309 return sph;
nuclear@0 310 }
nuclear@0 311
nuclear@0 312 static Object *parse_plane(char **argv, const std::map<std::string, Material> &materials)
nuclear@0 313 {
nuclear@0 314 char *endp;
nuclear@0 315 Plane *plane = new Plane;
nuclear@0 316
nuclear@0 317 for(int i=0; argv[i]; i++) {
nuclear@0 318 if(strcmp(argv[i], "-name") == 0) {
nuclear@0 319 plane->set_name(argv[++i]);
nuclear@0 320
nuclear@0 321 } else if(strcmp(argv[i], "-normal") == 0) {
nuclear@0 322 if(!parse_vec(argv + i + 1, &plane->normal)) {
nuclear@0 323 fprintf(stderr, "failed to parse plane normal\n");
nuclear@0 324 return 0;
nuclear@0 325 }
nuclear@0 326 plane->normal.normalize();
nuclear@0 327 argv += 3;
nuclear@0 328
nuclear@0 329 } else if(strcmp(argv[i], "-distance") == 0) {
nuclear@0 330 plane->dist = strtod(argv[++i], &endp);
nuclear@0 331 if(endp == argv[i]) {
nuclear@0 332 fprintf(stderr, "failed to parse plane distance\n");
nuclear@0 333 return 0;
nuclear@0 334 }
nuclear@0 335
nuclear@0 336 } else if(strcmp(argv[i], "-material") == 0) {
nuclear@0 337 auto it = materials.find(argv[++i]);
nuclear@0 338 if(it == materials.end()) {
nuclear@0 339 fprintf(stderr, "material %s not found\n", argv[i]);
nuclear@0 340 return 0;
nuclear@0 341 }
nuclear@0 342
nuclear@0 343 plane->material = it->second;
nuclear@0 344 } else {
nuclear@0 345 fprintf(stderr, "invalid plane option: %s\n", argv[i]);
nuclear@0 346 return 0;
nuclear@0 347 }
nuclear@0 348 }
nuclear@0 349
nuclear@0 350 return plane;
nuclear@0 351 }
nuclear@0 352
nuclear@0 353 static Object *parse_box(char **argv, const std::map<std::string, Material> &materials)
nuclear@0 354 {
nuclear@0 355 Box *box = new Box;
nuclear@0 356
nuclear@0 357 for(int i=0; argv[i]; i++) {
nuclear@0 358 if(strcmp(argv[i], "-name") == 0) {
nuclear@0 359 box->set_name(argv[++i]);
nuclear@0 360
nuclear@0 361 } else if(strcmp(argv[i], "-min") == 0) {
nuclear@0 362 if(!parse_vec(argv + i + 1, &box->min)) {
nuclear@0 363 fprintf(stderr, "failed to parse box min\n");
nuclear@0 364 return 0;
nuclear@0 365 }
nuclear@0 366 argv += 3;
nuclear@0 367
nuclear@0 368 } else if(strcmp(argv[i], "-max") == 0) {
nuclear@0 369 if(!parse_vec(argv + i + 1, &box->max)) {
nuclear@0 370 fprintf(stderr, "failed to parse box max\n");
nuclear@0 371 return 0;
nuclear@0 372 }
nuclear@0 373 argv += 3;
nuclear@0 374
nuclear@0 375 } else if(strcmp(argv[i], "-material") == 0) {
nuclear@0 376 auto it = materials.find(argv[++i]);
nuclear@0 377 if(it == materials.end()) {
nuclear@0 378 fprintf(stderr, "material %s not found\n", argv[i]);
nuclear@0 379 return 0;
nuclear@0 380 }
nuclear@0 381
nuclear@0 382 box->material = it->second;
nuclear@0 383 } else {
nuclear@0 384 fprintf(stderr, "invalid box option: %s\n", argv[i]);
nuclear@0 385 return 0;
nuclear@0 386 }
nuclear@0 387 }
nuclear@0 388
nuclear@0 389 return box;
nuclear@0 390 }
nuclear@0 391
nuclear@4 392 static Object *parse_cone(char **argv, const std::map<std::string, Material> &materials)
nuclear@4 393 {
nuclear@4 394 char *endp;
nuclear@4 395 Cone *cone = new Cone;
nuclear@4 396
nuclear@4 397 for(int i=0; argv[i]; i++) {
nuclear@4 398 if(strcmp(argv[i], "-name") == 0) {
nuclear@4 399 cone->set_name(argv[++i]);
nuclear@4 400
nuclear@4 401 } else if(strcmp(argv[i], "-angle") == 0) {
nuclear@4 402 cone->angle = DEG_TO_RAD(strtod(argv[++i], &endp));
nuclear@4 403 if(endp == argv[i]) {
nuclear@4 404 fprintf(stderr, "failed to parse cone angle\n");
nuclear@4 405 return 0;
nuclear@4 406 }
nuclear@4 407
nuclear@4 408 } else if(strcmp(argv[i], "-start") == 0) {
nuclear@4 409 cone->ymin = strtod(argv[++i], &endp);
nuclear@4 410 if(endp == argv[i]) {
nuclear@4 411 fprintf(stderr, "failed to parse cone start\n");
nuclear@4 412 return 0;
nuclear@4 413 }
nuclear@4 414
nuclear@4 415 } else if(strcmp(argv[i], "-end") == 0) {
nuclear@4 416 cone->ymax = strtod(argv[++i], &endp);
nuclear@4 417 if(endp == argv[i]) {
nuclear@4 418 fprintf(stderr, "failed to parse cone end\n");
nuclear@4 419 return 0;
nuclear@4 420 }
nuclear@4 421
nuclear@4 422 } else if(strcmp(argv[i], "-material") == 0) {
nuclear@4 423 auto it = materials.find(argv[++i]);
nuclear@4 424 if(it == materials.end()) {
nuclear@4 425 fprintf(stderr, "material %s not found\n", argv[i]);
nuclear@4 426 return 0;
nuclear@4 427 }
nuclear@4 428
nuclear@4 429 cone->material = it->second;
nuclear@4 430 } else {
nuclear@4 431 fprintf(stderr, "invalid box option: %s\n", argv[i]);
nuclear@4 432 return 0;
nuclear@4 433 }
nuclear@4 434 }
nuclear@4 435
nuclear@4 436 return cone;
nuclear@4 437 }
nuclear@4 438
nuclear@0 439 static Light *parse_light(char **argv)
nuclear@0 440 {
nuclear@0 441 Light *lt = new Light;
nuclear@0 442
nuclear@0 443 for(int i=0; argv[i]; i++) {
nuclear@0 444 if(strcmp(argv[i], "-position") == 0) {
nuclear@0 445 if(!parse_vec(argv + i + 1, &lt->pos)) {
nuclear@0 446 fprintf(stderr, "failed to parse light position\n");
nuclear@0 447 return 0;
nuclear@0 448 }
nuclear@0 449 argv += 3;
nuclear@0 450
nuclear@0 451 } else if(strcmp(argv[i], "-color") == 0) {
nuclear@0 452 if(!parse_vec(argv + i + 1, &lt->color)) {
nuclear@0 453 fprintf(stderr, "failed to parse light color\n");
nuclear@0 454 return 0;
nuclear@0 455 }
nuclear@0 456 argv += 3;
nuclear@0 457
nuclear@0 458 } else {
nuclear@0 459 fprintf(stderr, "invalid light option: %s\n", argv[i]);
nuclear@0 460 return 0;
nuclear@0 461 }
nuclear@0 462 }
nuclear@0 463
nuclear@0 464 return lt;
nuclear@0 465 }
nuclear@0 466
nuclear@0 467 static Camera *parse_camera(char **argv)
nuclear@0 468 {
nuclear@0 469 char *endp;
nuclear@0 470 TargetCamera *cam = new TargetCamera;
nuclear@0 471
nuclear@0 472 for(int i=0; argv[i]; i++) {
nuclear@0 473 if(strcmp(argv[i], "-position") == 0) {
nuclear@0 474 Vector3 pos;
nuclear@0 475 if(!parse_vec(argv + i + 1, &pos)) {
nuclear@0 476 fprintf(stderr, "failed to parse camera position\n");
nuclear@0 477 return 0;
nuclear@0 478 }
nuclear@0 479 argv += 3;
nuclear@0 480 cam->set_position(pos);
nuclear@0 481
nuclear@0 482 } else if(strcmp(argv[i], "-target") == 0) {
nuclear@0 483 Vector3 targ;
nuclear@0 484 if(!parse_vec(argv + i + 1, &targ)) {
nuclear@0 485 fprintf(stderr, "failed to parse camera target\n");
nuclear@0 486 return 0;
nuclear@0 487 }
nuclear@0 488 argv += 3;
nuclear@0 489 cam->set_target(targ);
nuclear@0 490
nuclear@0 491 } else if(strcmp(argv[i], "-fov") == 0) {
nuclear@0 492 float fov = strtod(argv[++i], &endp);
nuclear@0 493 if(endp == argv[i]) {
nuclear@0 494 fprintf(stderr, "failed to parse camera fov\n");
nuclear@0 495 return 0;
nuclear@0 496 }
nuclear@0 497 cam->set_fov(M_PI * fov / 180.0);
nuclear@0 498
nuclear@0 499 } else {
nuclear@0 500 fprintf(stderr, "invalid camera option: %s\n", argv[i]);
nuclear@0 501 return 0;
nuclear@0 502 }
nuclear@0 503 }
nuclear@0 504
nuclear@0 505 return cam;
nuclear@0 506 }
nuclear@0 507
nuclear@0 508 static bool parse_env(char **argv, Scene *scn)
nuclear@0 509 {
nuclear@0 510 char *endp;
nuclear@0 511
nuclear@0 512 TextureCube *env_tex = 0;
nuclear@0 513 TextureCube *conv_tex = 0;
nuclear@0 514
nuclear@0 515 float fog_start = -1;
nuclear@0 516 float fog_end = -1;
nuclear@0 517
nuclear@0 518 for(int i=0; argv[i]; i++) {
nuclear@0 519 if(strcmp(argv[i], "-color") == 0) {
nuclear@0 520 Color bgcolor;
nuclear@0 521 if(!parse_vec(argv + i + 1, &bgcolor)) {
nuclear@0 522 fprintf(stderr, "failed to parse environment color\n");
nuclear@0 523 return false;
nuclear@0 524 }
nuclear@0 525 i += 3;
nuclear@0 526 scn->set_background_color(bgcolor);
nuclear@0 527
nuclear@0 528 } else if(strcmp(argv[i], "-fog-start") == 0) {
nuclear@0 529 fog_start = strtod(argv[++i], &endp);
nuclear@0 530 if(endp == argv[i]) {
nuclear@0 531 fprintf(stderr, "failed to parse environment fog start\n");
nuclear@0 532 return false;
nuclear@0 533 }
nuclear@0 534
nuclear@0 535 } else if(strcmp(argv[i], "-fog-end") == 0) {
nuclear@0 536 fog_end = strtod(argv[++i], &endp);
nuclear@0 537 if(endp == argv[i]) {
nuclear@0 538 fprintf(stderr, "failed to parse environment fog end\n");
nuclear@0 539 return false;
nuclear@0 540 }
nuclear@0 541
nuclear@0 542 } else if(strcmp(argv[i], "-texture") == 0 || strcmp(argv[i], "-texture-conv") == 0) {
nuclear@0 543 Texture *tex = load_texture(argv[++i]);
nuclear@0 544 if(!tex || !dynamic_cast<TextureCube*>(tex)) {
nuclear@0 545 fprintf(stderr, "failed to load environment cubemap: %s\n", argv[i]);
nuclear@0 546 delete tex;
nuclear@0 547 return false;
nuclear@0 548 }
nuclear@0 549
nuclear@0 550 if(strstr(argv[i - 1], "-conv")) {
nuclear@0 551 conv_tex = (TextureCube*)tex;
nuclear@0 552 } else {
nuclear@0 553 env_tex = (TextureCube*)tex;
nuclear@0 554 }
nuclear@0 555
nuclear@0 556 } else {
nuclear@0 557 fprintf(stderr, "invalid environment option: %s\n", argv[i]);
nuclear@0 558 return false;
nuclear@0 559 }
nuclear@0 560 }
nuclear@0 561
nuclear@0 562 if(env_tex || conv_tex) {
nuclear@0 563 scn->set_environment_map(env_tex, conv_tex);
nuclear@0 564 }
nuclear@0 565
nuclear@0 566 if(fog_start > 0.0 && fog_end > 0.0) {
nuclear@0 567 scn->set_fog(fog_start, fog_end);
nuclear@0 568 }
nuclear@0 569
nuclear@0 570 return true;
nuclear@0 571 }
nuclear@0 572
nuclear@0 573 static bool parse_xform(char **argv, Scene *scn)
nuclear@0 574 {
nuclear@0 575 char *endp, *name = 0;
nuclear@0 576 Vector3 pos, rot_axis, scale;
nuclear@0 577 float rot_angle = 0;
nuclear@0 578 long tm = 0;
nuclear@0 579 Extrap extrap = EXTRAP_REPEAT;
nuclear@0 580
nuclear@0 581 bool have_pos = false;
nuclear@0 582 bool have_rot_axis = false;
nuclear@0 583 bool have_rot_angle = false;
nuclear@0 584 bool have_scale = false;
nuclear@0 585 bool have_extrap = false;
nuclear@0 586
nuclear@0 587 for(int i=0; argv[i]; i++) {
nuclear@0 588 if(strcmp(argv[i], "-name") == 0) {
nuclear@0 589 name = argv[++i];
nuclear@0 590
nuclear@0 591 } else if(strcmp(argv[i], "-pos") == 0) {
nuclear@0 592 if(!parse_vec(argv + i + 1, &pos)) {
nuclear@0 593 fprintf(stderr, "failed to parse xform position\n");
nuclear@0 594 return false;
nuclear@0 595 }
nuclear@0 596 have_pos = true;
nuclear@0 597 i += 3;
nuclear@0 598
nuclear@0 599 } else if(strcmp(argv[i], "-rot-axis") == 0) {
nuclear@0 600 if(!parse_vec(argv + i + 1, &rot_axis)) {
nuclear@0 601 fprintf(stderr, "failed to parse xform rotation axis\n");
nuclear@0 602 return false;
nuclear@0 603 }
nuclear@0 604 have_rot_axis = true;
nuclear@0 605 i += 3;
nuclear@0 606
nuclear@0 607 } else if(strcmp(argv[i], "-rot-angle") == 0) {
nuclear@0 608 rot_angle = strtod(argv[++i], &endp);
nuclear@0 609 if(endp == argv[i]) {
nuclear@0 610 fprintf(stderr, "failed to parse xform rotation angle\n");
nuclear@0 611 return false;
nuclear@0 612 }
nuclear@0 613 rot_angle = M_PI * rot_angle / 180.0;
nuclear@0 614 have_rot_angle = true;
nuclear@0 615
nuclear@0 616 } else if(strcmp(argv[i], "-scale") == 0) {
nuclear@0 617 if(!parse_vec(argv + i + 1, &scale)) {
nuclear@0 618 fprintf(stderr, "failed to parse xform scale\n");
nuclear@0 619 return false;
nuclear@0 620 }
nuclear@0 621 have_scale = true;
nuclear@0 622 i += 3;
nuclear@0 623
nuclear@0 624 } else if(strcmp(argv[i], "-time") == 0) {
nuclear@0 625 float tm_sec = strtod(argv[++i], &endp);
nuclear@0 626 if(endp == argv[i]) {
nuclear@0 627 fprintf(stderr, "failed to parse xform time\n");
nuclear@0 628 return false;
nuclear@0 629 }
nuclear@0 630 tm = (long)(tm_sec * 1000.0f);
nuclear@0 631
nuclear@0 632 } else if(strcmp(argv[i], "-extrapolation") == 0) {
nuclear@0 633 if(strcmp(argv[++i], "extend") == 0) {
nuclear@0 634 extrap = EXTRAP_EXTEND;
nuclear@0 635 } else if(strcmp(argv[i], "clamp") == 0) {
nuclear@0 636 extrap = EXTRAP_CLAMP;
nuclear@0 637 } else if(strcmp(argv[i], "repeat") == 0) {
nuclear@0 638 extrap = EXTRAP_REPEAT;
nuclear@0 639 } else if(strcmp(argv[i], "pingpong") == 0) {
nuclear@0 640 extrap = EXTRAP_PINGPONG;
nuclear@0 641 } else {
nuclear@0 642 fprintf(stderr, "failed to parse xform extrapolation, invalid mode: %s\n", argv[i]);
nuclear@0 643 return false;
nuclear@0 644 }
nuclear@0 645 have_extrap = true;
nuclear@0 646
nuclear@0 647 } else {
nuclear@0 648 fprintf(stderr, "invalid xform option: %s\n", argv[i]);
nuclear@0 649 return false;
nuclear@0 650 }
nuclear@0 651 }
nuclear@0 652
nuclear@0 653 if(!name) {
nuclear@0 654 fprintf(stderr, "invalid xform command, missing -name option\n");
nuclear@0 655 return false;
nuclear@0 656 }
nuclear@0 657 if(have_rot_angle != have_rot_axis) {
nuclear@0 658 fprintf(stderr, "invalid xform command, must have both -rot-angle and -rot-axis or neither\n");
nuclear@0 659 return false;
nuclear@0 660 }
nuclear@0 661
nuclear@0 662 Object *obj = 0;
nuclear@0 663
nuclear@0 664 int nobj = scn->get_object_count();
nuclear@0 665 for(int i=0; i<nobj; i++) {
nuclear@0 666 Object *tmp = scn->get_object(i);
nuclear@0 667 if(strcmp(tmp->get_name(), name) == 0) {
nuclear@0 668 obj = tmp;
nuclear@0 669 break;
nuclear@0 670 }
nuclear@0 671 }
nuclear@0 672
nuclear@0 673 if(!obj) {
nuclear@0 674 fprintf(stderr, "invalid xform, refers to nonexistent object: %s\n", name);
nuclear@0 675 return false;
nuclear@0 676 }
nuclear@0 677
nuclear@0 678 if(have_pos) {
nuclear@0 679 obj->set_position(pos, tm);
nuclear@0 680 }
nuclear@0 681 if(have_rot_angle) {
nuclear@0 682 obj->set_rotation(Quaternion(rot_axis, rot_angle), tm);
nuclear@0 683 }
nuclear@0 684 if(have_scale) {
nuclear@0 685 obj->set_scaling(scale, tm);
nuclear@0 686 }
nuclear@0 687
nuclear@0 688 if(have_extrap) {
nuclear@0 689 obj->set_extrapolator(extrap);
nuclear@0 690 }
nuclear@0 691 return true;
nuclear@0 692 }
nuclear@0 693
nuclear@0 694 static bool parse_vec(char **argv, Vector3 *vptr)
nuclear@0 695 {
nuclear@0 696 char *endp;
nuclear@0 697
nuclear@0 698 vptr->x = strtod(argv[0], &endp);
nuclear@0 699 if(endp == argv[0])
nuclear@0 700 return false;
nuclear@0 701 vptr->y = strtod(argv[1], &endp);
nuclear@0 702 if(endp == argv[1])
nuclear@0 703 return false;
nuclear@0 704 vptr->z = strtod(argv[2], &endp);
nuclear@0 705 if(endp == argv[2])
nuclear@0 706 return false;
nuclear@0 707
nuclear@0 708 return true;
nuclear@0 709 }
nuclear@0 710
nuclear@0 711
nuclear@0 712 static char *strip_space(char *s)
nuclear@0 713 {
nuclear@0 714 while(*s && isspace(*s)) s++;
nuclear@0 715
nuclear@0 716 if(!*s)
nuclear@0 717 return s;
nuclear@0 718
nuclear@0 719 char *endp = s + strlen(s) - 1;
nuclear@0 720 while(isspace(*endp)) endp--;
nuclear@0 721 endp[1] = 0;
nuclear@0 722
nuclear@0 723 if((endp = strrchr(s, '#'))) {
nuclear@0 724 *endp = 0;
nuclear@0 725 }
nuclear@0 726
nuclear@0 727 return s;
nuclear@0 728 }
nuclear@0 729
nuclear@0 730 static char **split_args(char *args)
nuclear@0 731 {
nuclear@0 732 static std::vector<char*> argv;
nuclear@0 733 char *tok = 0;
nuclear@0 734
nuclear@0 735 argv.clear();
nuclear@0 736
nuclear@0 737 while((tok = strtok(tok ? 0 : args, " \t\v\n\r"))) {
nuclear@0 738 argv.push_back(tok);
nuclear@0 739 }
nuclear@0 740 argv.push_back(0);
nuclear@0 741
nuclear@0 742 return &argv[0];
nuclear@0 743 }