gpuray_glsl

annotate src/scene_load.cc @ 3:297dbc5080c4

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