gpuray_glsl
diff src/scene_load.cc @ 0:f234630e38ff
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 09 Nov 2014 13:03:36 +0200 |
parents | |
children | 2ed3da7dc0bc |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/scene_load.cc Sun Nov 09 13:03:36 2014 +0200 1.3 @@ -0,0 +1,681 @@ 1.4 +#include <stdio.h> 1.5 +#include <math.h> 1.6 +#include <map> 1.7 +#include "scene.h" 1.8 +#include "sphere.h" 1.9 +#include "plane.h" 1.10 +#include "box.h" 1.11 +#include "light.h" 1.12 +#include "camera.h" 1.13 +#include "texture.h" 1.14 + 1.15 +static bool parse_material(char **argv, Material *mtl, std::string *name); 1.16 +static Object *parse_sphere(char **argv, const std::map<std::string, Material> &materials); 1.17 +static Object *parse_plane(char **argv, const std::map<std::string, Material> &materials); 1.18 +static Object *parse_box(char **argv, const std::map<std::string, Material> &materials); 1.19 +static Light *parse_light(char **argv); 1.20 +static Camera *parse_camera(char **argv); 1.21 +static bool parse_env(char **argv, Scene *scn); 1.22 +static bool parse_xform(char **argv, Scene *scn); 1.23 +static bool parse_vec(char **argv, Vector3 *vptr); 1.24 + 1.25 +static char *strip_space(char *s); 1.26 +static char **split_args(char *args); 1.27 + 1.28 +bool load_scene_file(Scene *scn, const char *fname) 1.29 +{ 1.30 + FILE *fp; 1.31 + if(!(fp = fopen(fname, "rb"))) { 1.32 + fprintf(stderr, "%s: failed to open scene file: %s: %s\n", __FUNCTION__, fname, strerror(errno)); 1.33 + return false; 1.34 + } 1.35 + 1.36 + char buf[512]; 1.37 + std::map<std::string, Material> materials; 1.38 + 1.39 + int lineno = 0; 1.40 + while(fgets(buf, sizeof buf, fp)) { 1.41 + char *line = strip_space(buf); 1.42 + 1.43 + lineno++; 1.44 + 1.45 + if(!*line || *line == '\n' || *line == '#') { 1.46 + continue; 1.47 + } 1.48 + 1.49 + if(strstr(line, "material") == line) { 1.50 + Material mtl; 1.51 + std::string name; 1.52 + 1.53 + char *args = strip_space(line + strlen("material")); 1.54 + if(!parse_material(split_args(args), &mtl, &name)) { 1.55 + goto err; 1.56 + } 1.57 + materials[name] = mtl; 1.58 + 1.59 + } else if(strstr(line, "sphere") == line) { 1.60 + char *args = strip_space(line + strlen("sphere")); 1.61 + Object *obj = parse_sphere(split_args(args), materials); 1.62 + if(!obj) { 1.63 + goto err; 1.64 + } 1.65 + scn->add_object(obj); 1.66 + 1.67 + } else if(strstr(line, "plane") == line) { 1.68 + char *args = strip_space(line + strlen("plane")); 1.69 + Object *obj = parse_plane(split_args(args), materials); 1.70 + if(!obj) { 1.71 + goto err; 1.72 + } 1.73 + scn->add_object(obj); 1.74 + 1.75 + } else if(strstr(line, "box") == line) { 1.76 + char *args = strip_space(line + strlen("box")); 1.77 + Object *obj = parse_box(split_args(args), materials); 1.78 + if(!obj) { 1.79 + goto err; 1.80 + } 1.81 + scn->add_object(obj); 1.82 + 1.83 + } else if(strstr(line, "light") == line) { 1.84 + char *args = strip_space(line + strlen("light")); 1.85 + Light *lt = parse_light(split_args(args)); 1.86 + if(!lt) { 1.87 + goto err; 1.88 + } 1.89 + scn->add_light(lt); 1.90 + 1.91 + } else if(strstr(line, "camera") == line) { 1.92 + char *args = strip_space(line + strlen("camera")); 1.93 + Camera *cam = parse_camera(split_args(args)); 1.94 + if(!cam) { 1.95 + goto err; 1.96 + } 1.97 + scn->set_camera(cam); 1.98 + 1.99 + } else if(strstr(line, "environment") == line) { 1.100 + char *args = strip_space(line + strlen("environment")); 1.101 + if(!parse_env(split_args(args), scn)) { 1.102 + goto err; 1.103 + } 1.104 + 1.105 + } else if(strstr(line, "xform") == line) { 1.106 + char *args = strip_space(line + strlen("xform")); 1.107 + if(!parse_xform(split_args(args), scn)) { 1.108 + goto err; 1.109 + } 1.110 + 1.111 + } else { 1.112 + fprintf(stderr, "%s error %s:%d: unknown command: %s\n", __FUNCTION__, fname, lineno, line); 1.113 + goto err; 1.114 + } 1.115 + 1.116 + } 1.117 + 1.118 + fclose(fp); 1.119 + return true; 1.120 + 1.121 +err: 1.122 + fclose(fp); 1.123 + return false; 1.124 +} 1.125 + 1.126 +bool save_scene_file(const Scene *scn, const char *fname) 1.127 +{ 1.128 + FILE *fp; 1.129 + if(!(fp = fopen(fname, "wb"))) { 1.130 + fprintf(stderr, "%s: failed to save scene file: %s: %s\n", __FUNCTION__, fname, strerror(errno)); 1.131 + return false; 1.132 + } 1.133 + 1.134 + for(int i=0; i<scn->get_object_count(); i++) { 1.135 + // first write the material 1.136 + const Object *obj = scn->get_object(i); 1.137 + const Material *mat = &obj->material; 1.138 + 1.139 + char name[128]; 1.140 + sprintf(name, "mat%d", i); 1.141 + 1.142 + fprintf(fp, "material -name %s", name); 1.143 + fprintf(fp, " -diffuse %.3f %.3f %.3f", mat->diffuse.x, mat->diffuse.y, mat->diffuse.z); 1.144 + fprintf(fp, " -specular %.3f %.3f %.3f", mat->specular.x, mat->specular.y, mat->specular.z); 1.145 + fprintf(fp, " -shininess %.3f", mat->shininess); 1.146 + fprintf(fp, " -emission %.3f %.3f %.3f", mat->emission.x, mat->emission.y, mat->emission.z); 1.147 + fprintf(fp, " -reflect %.3f", mat->reflectivity); 1.148 + fprintf(fp, " -trans %.3f", mat->transparency); 1.149 + fprintf(fp, " -ior %.3f", mat->ior); 1.150 + if(mat->tex) { 1.151 + fprintf(fp, " -texture %s", mat->tex->get_name()); 1.152 + } 1.153 + fputc('\n', fp); 1.154 + 1.155 + // then write the object 1.156 + const Sphere *sph; 1.157 + const Plane *plane; 1.158 + const Box *box; 1.159 + if((sph = dynamic_cast<const Sphere*>(obj))) { 1.160 + fprintf(fp, "sphere -material %s", name); 1.161 + fprintf(fp, " -center %.3f %.3f %.3f", sph->pos.x, sph->pos.y, sph->pos.z); 1.162 + fprintf(fp, " -radius %.3f\n", sph->radius); 1.163 + } else if((plane = dynamic_cast<const Plane*>(obj))) { 1.164 + fprintf(fp, "plane -material %s", name); 1.165 + fprintf(fp, " -normal %.3f %.3f %.3f", plane->normal.x, plane->normal.y, plane->normal.z); 1.166 + fprintf(fp, " -distance %.3f\n", plane->dist); 1.167 + } else if((box = dynamic_cast<const Box*>(obj))) { 1.168 + fprintf(fp, "box -material %s", name); 1.169 + fprintf(fp, " -min %.3f %.3f %.3f", box->min.x, box->min.y, box->min.z); 1.170 + fprintf(fp, " -max %.3f %.3f %.3f\n", box->max.x, box->max.y, box->max.z); 1.171 + } 1.172 + } 1.173 + 1.174 + for(int i=0; i<scn->get_light_count(); i++) { 1.175 + const Light *lt = scn->get_light(i); 1.176 + 1.177 + fprintf(fp, "light -position %.3f %.3f %.3f", lt->pos.x, lt->pos.y, lt->pos.z); 1.178 + fprintf(fp, " -color %.3f %.3f %.3f\n", lt->color.x, lt->color.y, lt->color.z); 1.179 + } 1.180 + 1.181 + const TargetCamera *tcam = dynamic_cast<const TargetCamera*>(scn->get_camera()); 1.182 + if(tcam) { 1.183 + Vector3 pos = tcam->get_position(); 1.184 + fprintf(fp, "camera -position %.3f %.3f %.3f", pos.x, pos.y, pos.z); 1.185 + Vector3 targ = tcam->get_target(); 1.186 + fprintf(fp, " -target %.3f %.3f %.3f", targ.x, targ.y, targ.z); 1.187 + fprintf(fp, " -fov %.3f\n", tcam->get_fov()); 1.188 + } 1.189 + 1.190 + 1.191 + fclose(fp); 1.192 + return true; 1.193 +} 1.194 + 1.195 +#define ARGERR(n) \ 1.196 + do { fprintf(stderr, "failed to parse %s argument\n", (n)); return false; } while(0) 1.197 + 1.198 +static bool parse_material(char **argv, Material *mtl, std::string *name) 1.199 +{ 1.200 + char *endp; 1.201 + 1.202 + for(int i=0; argv[i]; i++) { 1.203 + if(strcmp(argv[i], "-name") == 0) { 1.204 + *name = argv[++i]; 1.205 + } else if(strcmp(argv[i], "-diffuse") == 0) { 1.206 + if(!parse_vec(argv + i + 1, &mtl->diffuse)) { 1.207 + ARGERR("diffuse"); 1.208 + } 1.209 + argv += 3; 1.210 + 1.211 + } else if(strcmp(argv[i], "-specular") == 0) { 1.212 + if(!parse_vec(argv + i + 1, &mtl->specular)) { 1.213 + ARGERR("specular"); 1.214 + } 1.215 + argv += 3; 1.216 + 1.217 + } else if(strcmp(argv[i], "-emission") == 0) { 1.218 + if(!parse_vec(argv + i + 1, &mtl->emission)) { 1.219 + ARGERR("emission"); 1.220 + } 1.221 + argv += 3; 1.222 + 1.223 + } else if(strcmp(argv[i], "-shininess") == 0) { 1.224 + mtl->shininess = strtod(argv[++i], &endp); 1.225 + if(endp == argv[i]) { 1.226 + ARGERR("shininess"); 1.227 + } 1.228 + 1.229 + } else if(strcmp(argv[i], "-reflect") == 0) { 1.230 + mtl->reflectivity = strtod(argv[++i], &endp); 1.231 + if(endp == argv[i]) { 1.232 + ARGERR("reflect"); 1.233 + } 1.234 + 1.235 + } else if(strcmp(argv[i], "-trans") == 0) { 1.236 + mtl->transparency = strtod(argv[++i], &endp); 1.237 + if(endp == argv[i]) { 1.238 + ARGERR("trans"); 1.239 + } 1.240 + 1.241 + } else if(strcmp(argv[i], "-ior") == 0) { 1.242 + mtl->ior = strtod(argv[++i], &endp); 1.243 + if(endp == argv[i]) { 1.244 + ARGERR("ior"); 1.245 + } 1.246 + 1.247 + } else if(strcmp(argv[i], "-texture") == 0) { 1.248 + if(!(mtl->tex = load_texture(argv[++i]))) { 1.249 + return false; 1.250 + } 1.251 + 1.252 + } else { 1.253 + fprintf(stderr, "invalid material option: %s\n", argv[i]); 1.254 + return false; 1.255 + } 1.256 + } 1.257 + return true; 1.258 +} 1.259 + 1.260 +static Object *parse_sphere(char **argv, const std::map<std::string, Material> &materials) 1.261 +{ 1.262 + char *endp; 1.263 + Sphere *sph = new Sphere; 1.264 + 1.265 + for(int i=0; argv[i]; i++) { 1.266 + if(strcmp(argv[i], "-name") == 0) { 1.267 + sph->set_name(argv[++i]); 1.268 + 1.269 + } else if(strcmp(argv[i], "-center") == 0) { 1.270 + if(!parse_vec(argv + i + 1, &sph->pos)) { 1.271 + fprintf(stderr, "failed to parse sphere center vector\n"); 1.272 + return 0; 1.273 + } 1.274 + argv += 3; 1.275 + 1.276 + } else if(strcmp(argv[i], "-radius") == 0) { 1.277 + sph->radius = strtod(argv[++i], &endp); 1.278 + if(endp == argv[i]) { 1.279 + fprintf(stderr, "failed to parse sphere radius\n"); 1.280 + return 0; 1.281 + } 1.282 + 1.283 + } else if(strcmp(argv[i], "-material") == 0) { 1.284 + auto it = materials.find(argv[++i]); 1.285 + if(it == materials.end()) { 1.286 + fprintf(stderr, "material %s not found\n", argv[i]); 1.287 + return 0; 1.288 + } 1.289 + 1.290 + sph->material = it->second; 1.291 + } else { 1.292 + fprintf(stderr, "invalid sphere option: %s\n", argv[i]); 1.293 + return 0; 1.294 + } 1.295 + } 1.296 + 1.297 + return sph; 1.298 +} 1.299 + 1.300 +static Object *parse_plane(char **argv, const std::map<std::string, Material> &materials) 1.301 +{ 1.302 + char *endp; 1.303 + Plane *plane = new Plane; 1.304 + 1.305 + for(int i=0; argv[i]; i++) { 1.306 + if(strcmp(argv[i], "-name") == 0) { 1.307 + plane->set_name(argv[++i]); 1.308 + 1.309 + } else if(strcmp(argv[i], "-normal") == 0) { 1.310 + if(!parse_vec(argv + i + 1, &plane->normal)) { 1.311 + fprintf(stderr, "failed to parse plane normal\n"); 1.312 + return 0; 1.313 + } 1.314 + plane->normal.normalize(); 1.315 + argv += 3; 1.316 + 1.317 + } else if(strcmp(argv[i], "-distance") == 0) { 1.318 + plane->dist = strtod(argv[++i], &endp); 1.319 + if(endp == argv[i]) { 1.320 + fprintf(stderr, "failed to parse plane distance\n"); 1.321 + return 0; 1.322 + } 1.323 + 1.324 + } else if(strcmp(argv[i], "-material") == 0) { 1.325 + auto it = materials.find(argv[++i]); 1.326 + if(it == materials.end()) { 1.327 + fprintf(stderr, "material %s not found\n", argv[i]); 1.328 + return 0; 1.329 + } 1.330 + 1.331 + plane->material = it->second; 1.332 + } else { 1.333 + fprintf(stderr, "invalid plane option: %s\n", argv[i]); 1.334 + return 0; 1.335 + } 1.336 + } 1.337 + 1.338 + return plane; 1.339 +} 1.340 + 1.341 +static Object *parse_box(char **argv, const std::map<std::string, Material> &materials) 1.342 +{ 1.343 + Box *box = new Box; 1.344 + 1.345 + for(int i=0; argv[i]; i++) { 1.346 + if(strcmp(argv[i], "-name") == 0) { 1.347 + box->set_name(argv[++i]); 1.348 + 1.349 + } else if(strcmp(argv[i], "-min") == 0) { 1.350 + if(!parse_vec(argv + i + 1, &box->min)) { 1.351 + fprintf(stderr, "failed to parse box min\n"); 1.352 + return 0; 1.353 + } 1.354 + argv += 3; 1.355 + 1.356 + } else if(strcmp(argv[i], "-max") == 0) { 1.357 + if(!parse_vec(argv + i + 1, &box->max)) { 1.358 + fprintf(stderr, "failed to parse box max\n"); 1.359 + return 0; 1.360 + } 1.361 + argv += 3; 1.362 + 1.363 + } else if(strcmp(argv[i], "-material") == 0) { 1.364 + auto it = materials.find(argv[++i]); 1.365 + if(it == materials.end()) { 1.366 + fprintf(stderr, "material %s not found\n", argv[i]); 1.367 + return 0; 1.368 + } 1.369 + 1.370 + box->material = it->second; 1.371 + } else { 1.372 + fprintf(stderr, "invalid box option: %s\n", argv[i]); 1.373 + return 0; 1.374 + } 1.375 + } 1.376 + 1.377 + return box; 1.378 +} 1.379 + 1.380 +static Light *parse_light(char **argv) 1.381 +{ 1.382 + Light *lt = new Light; 1.383 + 1.384 + for(int i=0; argv[i]; i++) { 1.385 + if(strcmp(argv[i], "-position") == 0) { 1.386 + if(!parse_vec(argv + i + 1, <->pos)) { 1.387 + fprintf(stderr, "failed to parse light position\n"); 1.388 + return 0; 1.389 + } 1.390 + argv += 3; 1.391 + 1.392 + } else if(strcmp(argv[i], "-color") == 0) { 1.393 + if(!parse_vec(argv + i + 1, <->color)) { 1.394 + fprintf(stderr, "failed to parse light color\n"); 1.395 + return 0; 1.396 + } 1.397 + argv += 3; 1.398 + 1.399 + } else { 1.400 + fprintf(stderr, "invalid light option: %s\n", argv[i]); 1.401 + return 0; 1.402 + } 1.403 + } 1.404 + 1.405 + return lt; 1.406 +} 1.407 + 1.408 +static Camera *parse_camera(char **argv) 1.409 +{ 1.410 + char *endp; 1.411 + TargetCamera *cam = new TargetCamera; 1.412 + 1.413 + for(int i=0; argv[i]; i++) { 1.414 + if(strcmp(argv[i], "-position") == 0) { 1.415 + Vector3 pos; 1.416 + if(!parse_vec(argv + i + 1, &pos)) { 1.417 + fprintf(stderr, "failed to parse camera position\n"); 1.418 + return 0; 1.419 + } 1.420 + argv += 3; 1.421 + cam->set_position(pos); 1.422 + 1.423 + } else if(strcmp(argv[i], "-target") == 0) { 1.424 + Vector3 targ; 1.425 + if(!parse_vec(argv + i + 1, &targ)) { 1.426 + fprintf(stderr, "failed to parse camera target\n"); 1.427 + return 0; 1.428 + } 1.429 + argv += 3; 1.430 + cam->set_target(targ); 1.431 + 1.432 + } else if(strcmp(argv[i], "-fov") == 0) { 1.433 + float fov = strtod(argv[++i], &endp); 1.434 + if(endp == argv[i]) { 1.435 + fprintf(stderr, "failed to parse camera fov\n"); 1.436 + return 0; 1.437 + } 1.438 + cam->set_fov(M_PI * fov / 180.0); 1.439 + 1.440 + } else { 1.441 + fprintf(stderr, "invalid camera option: %s\n", argv[i]); 1.442 + return 0; 1.443 + } 1.444 + } 1.445 + 1.446 + return cam; 1.447 +} 1.448 + 1.449 +static bool parse_env(char **argv, Scene *scn) 1.450 +{ 1.451 + char *endp; 1.452 + 1.453 + TextureCube *env_tex = 0; 1.454 + TextureCube *conv_tex = 0; 1.455 + 1.456 + float fog_start = -1; 1.457 + float fog_end = -1; 1.458 + 1.459 + for(int i=0; argv[i]; i++) { 1.460 + if(strcmp(argv[i], "-color") == 0) { 1.461 + Color bgcolor; 1.462 + if(!parse_vec(argv + i + 1, &bgcolor)) { 1.463 + fprintf(stderr, "failed to parse environment color\n"); 1.464 + return false; 1.465 + } 1.466 + i += 3; 1.467 + scn->set_background_color(bgcolor); 1.468 + 1.469 + } else if(strcmp(argv[i], "-fog-start") == 0) { 1.470 + fog_start = strtod(argv[++i], &endp); 1.471 + if(endp == argv[i]) { 1.472 + fprintf(stderr, "failed to parse environment fog start\n"); 1.473 + return false; 1.474 + } 1.475 + 1.476 + } else if(strcmp(argv[i], "-fog-end") == 0) { 1.477 + fog_end = strtod(argv[++i], &endp); 1.478 + if(endp == argv[i]) { 1.479 + fprintf(stderr, "failed to parse environment fog end\n"); 1.480 + return false; 1.481 + } 1.482 + 1.483 + } else if(strcmp(argv[i], "-texture") == 0 || strcmp(argv[i], "-texture-conv") == 0) { 1.484 + Texture *tex = load_texture(argv[++i]); 1.485 + if(!tex || !dynamic_cast<TextureCube*>(tex)) { 1.486 + fprintf(stderr, "failed to load environment cubemap: %s\n", argv[i]); 1.487 + delete tex; 1.488 + return false; 1.489 + } 1.490 + 1.491 + if(strstr(argv[i - 1], "-conv")) { 1.492 + conv_tex = (TextureCube*)tex; 1.493 + } else { 1.494 + env_tex = (TextureCube*)tex; 1.495 + } 1.496 + 1.497 + } else { 1.498 + fprintf(stderr, "invalid environment option: %s\n", argv[i]); 1.499 + return false; 1.500 + } 1.501 + } 1.502 + 1.503 + if(env_tex || conv_tex) { 1.504 + scn->set_environment_map(env_tex, conv_tex); 1.505 + } 1.506 + 1.507 + if(fog_start > 0.0 && fog_end > 0.0) { 1.508 + scn->set_fog(fog_start, fog_end); 1.509 + } 1.510 + 1.511 + return true; 1.512 +} 1.513 + 1.514 +static bool parse_xform(char **argv, Scene *scn) 1.515 +{ 1.516 + char *endp, *name = 0; 1.517 + Vector3 pos, rot_axis, scale; 1.518 + float rot_angle = 0; 1.519 + long tm = 0; 1.520 + Extrap extrap = EXTRAP_REPEAT; 1.521 + 1.522 + bool have_pos = false; 1.523 + bool have_rot_axis = false; 1.524 + bool have_rot_angle = false; 1.525 + bool have_scale = false; 1.526 + bool have_extrap = false; 1.527 + 1.528 + for(int i=0; argv[i]; i++) { 1.529 + if(strcmp(argv[i], "-name") == 0) { 1.530 + name = argv[++i]; 1.531 + 1.532 + } else if(strcmp(argv[i], "-pos") == 0) { 1.533 + if(!parse_vec(argv + i + 1, &pos)) { 1.534 + fprintf(stderr, "failed to parse xform position\n"); 1.535 + return false; 1.536 + } 1.537 + have_pos = true; 1.538 + i += 3; 1.539 + 1.540 + } else if(strcmp(argv[i], "-rot-axis") == 0) { 1.541 + if(!parse_vec(argv + i + 1, &rot_axis)) { 1.542 + fprintf(stderr, "failed to parse xform rotation axis\n"); 1.543 + return false; 1.544 + } 1.545 + have_rot_axis = true; 1.546 + i += 3; 1.547 + 1.548 + } else if(strcmp(argv[i], "-rot-angle") == 0) { 1.549 + rot_angle = strtod(argv[++i], &endp); 1.550 + if(endp == argv[i]) { 1.551 + fprintf(stderr, "failed to parse xform rotation angle\n"); 1.552 + return false; 1.553 + } 1.554 + rot_angle = M_PI * rot_angle / 180.0; 1.555 + have_rot_angle = true; 1.556 + 1.557 + } else if(strcmp(argv[i], "-scale") == 0) { 1.558 + if(!parse_vec(argv + i + 1, &scale)) { 1.559 + fprintf(stderr, "failed to parse xform scale\n"); 1.560 + return false; 1.561 + } 1.562 + have_scale = true; 1.563 + i += 3; 1.564 + 1.565 + } else if(strcmp(argv[i], "-time") == 0) { 1.566 + float tm_sec = strtod(argv[++i], &endp); 1.567 + if(endp == argv[i]) { 1.568 + fprintf(stderr, "failed to parse xform time\n"); 1.569 + return false; 1.570 + } 1.571 + tm = (long)(tm_sec * 1000.0f); 1.572 + 1.573 + } else if(strcmp(argv[i], "-extrapolation") == 0) { 1.574 + if(strcmp(argv[++i], "extend") == 0) { 1.575 + extrap = EXTRAP_EXTEND; 1.576 + } else if(strcmp(argv[i], "clamp") == 0) { 1.577 + extrap = EXTRAP_CLAMP; 1.578 + } else if(strcmp(argv[i], "repeat") == 0) { 1.579 + extrap = EXTRAP_REPEAT; 1.580 + } else if(strcmp(argv[i], "pingpong") == 0) { 1.581 + extrap = EXTRAP_PINGPONG; 1.582 + } else { 1.583 + fprintf(stderr, "failed to parse xform extrapolation, invalid mode: %s\n", argv[i]); 1.584 + return false; 1.585 + } 1.586 + have_extrap = true; 1.587 + 1.588 + } else { 1.589 + fprintf(stderr, "invalid xform option: %s\n", argv[i]); 1.590 + return false; 1.591 + } 1.592 + } 1.593 + 1.594 + if(!name) { 1.595 + fprintf(stderr, "invalid xform command, missing -name option\n"); 1.596 + return false; 1.597 + } 1.598 + if(have_rot_angle != have_rot_axis) { 1.599 + fprintf(stderr, "invalid xform command, must have both -rot-angle and -rot-axis or neither\n"); 1.600 + return false; 1.601 + } 1.602 + 1.603 + Object *obj = 0; 1.604 + 1.605 + int nobj = scn->get_object_count(); 1.606 + for(int i=0; i<nobj; i++) { 1.607 + Object *tmp = scn->get_object(i); 1.608 + if(strcmp(tmp->get_name(), name) == 0) { 1.609 + obj = tmp; 1.610 + break; 1.611 + } 1.612 + } 1.613 + 1.614 + if(!obj) { 1.615 + fprintf(stderr, "invalid xform, refers to nonexistent object: %s\n", name); 1.616 + return false; 1.617 + } 1.618 + 1.619 + if(have_pos) { 1.620 + obj->set_position(pos, tm); 1.621 + } 1.622 + if(have_rot_angle) { 1.623 + obj->set_rotation(Quaternion(rot_axis, rot_angle), tm); 1.624 + } 1.625 + if(have_scale) { 1.626 + obj->set_scaling(scale, tm); 1.627 + } 1.628 + 1.629 + if(have_extrap) { 1.630 + obj->set_extrapolator(extrap); 1.631 + } 1.632 + return true; 1.633 +} 1.634 + 1.635 +static bool parse_vec(char **argv, Vector3 *vptr) 1.636 +{ 1.637 + char *endp; 1.638 + 1.639 + vptr->x = strtod(argv[0], &endp); 1.640 + if(endp == argv[0]) 1.641 + return false; 1.642 + vptr->y = strtod(argv[1], &endp); 1.643 + if(endp == argv[1]) 1.644 + return false; 1.645 + vptr->z = strtod(argv[2], &endp); 1.646 + if(endp == argv[2]) 1.647 + return false; 1.648 + 1.649 + return true; 1.650 +} 1.651 + 1.652 + 1.653 +static char *strip_space(char *s) 1.654 +{ 1.655 + while(*s && isspace(*s)) s++; 1.656 + 1.657 + if(!*s) 1.658 + return s; 1.659 + 1.660 + char *endp = s + strlen(s) - 1; 1.661 + while(isspace(*endp)) endp--; 1.662 + endp[1] = 0; 1.663 + 1.664 + if((endp = strrchr(s, '#'))) { 1.665 + *endp = 0; 1.666 + } 1.667 + 1.668 + return s; 1.669 +} 1.670 + 1.671 +static char **split_args(char *args) 1.672 +{ 1.673 + static std::vector<char*> argv; 1.674 + char *tok = 0; 1.675 + 1.676 + argv.clear(); 1.677 + 1.678 + while((tok = strtok(tok ? 0 : args, " \t\v\n\r"))) { 1.679 + argv.push_back(tok); 1.680 + } 1.681 + argv.push_back(0); 1.682 + 1.683 + return &argv[0]; 1.684 +}