#include #include #include #include #include #include #include #include "entity.h" #include "triangle.h" #include "sphere.h" #include "color.h" #include "disjoint_entities.h" #include "world_objects.h" #include "write_rgb.h" #include "tri_mesh.h" #include "entity_transform.h" #include "light.h" #include "load_scene.h" #include "texture_eval.h" #include "texture_sph.h" using std::ifstream; using std::map; using std::string; static map file_entities; static map file_lights; static map file_transforms; static map file_texture_eval; static map file_texture_image; typedef map::iterator ent_it; typedef map::iterator lit_it; typedef map::iterator trn_it; typedef map::iterator texe_it; typedef map::iterator texi_it; void load_scene(const char* filename, world_objects& world, scene_view* sv) { ifstream fin(filename); string line; while(getline(fin, line), !fin.eof()) { strstream ss; ss << line; string token; ss >> token; if(token == "L") load_light(ss); else if(token == "M") load_mesh(ss); else if(token == "S") load_sphere(ss); else if(token == "T") load_entity_trans(ss); else if(token == "TR") load_translate(ss); else if(token == "Z") load_trans(ss); else if(token == "D") load_disjoint(ss); else if(token == "W") load_world(ss, world); else if(token == "V") load_scene_view(ss, sv); else if(token == "SX") load_image_texture(ss); else if(token == "MX") load_3d_texture(ss); } } void load_light(strstream& ss) { string name; ss >> name; Light* L; lit_it it = file_lights.find(name); if(it == file_lights.end()) L = file_lights[name] = new Light; else L = it->second; double dx, dy, dz; string token; while(ss >> token) { if(token == "cs") { if(ss >> dx >> dy >> dz) L->cs.rgb = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(token == "cd") { if(ss >> dx >> dy >> dz) L->cd.rgb = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(token == "I") { if(ss >> dx) L->I = dx; else assert("Parse error!" && 0); } else if(token == "pt") { if(ss >> dx >> dy >> dz) L->pt = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else assert("Parse error!" && 0); } } int load_entity(strstream& ss, string type, Entity*E) { double dx, dy, dz; if(type == "cs") { if(ss >> dx >> dy >> dz) E->cs.rgb = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(type == "cd") { if(ss >> dx >> dy >> dz) E->cd.rgb = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(type == "ks") { if(ss >> dx) E->ks = dx; else assert("Parse error!" && 0); } else if(type == "kd") { if(ss >> dx) E->kd = dx; else assert("Parse error!" && 0); } else if(type == "n") { if(ss >> dx) E->n = dx; else assert("Parse error!" && 0); } else if(type == "ref") { if(ss >> dx) E->ref = dx; else assert("Parse error!" && 0); } else return 0; return 1; } void load_mesh(strstream& ss) { string name; ss >> name; tri_mesh* E; ent_it it = file_entities.find(name); if(it == file_entities.end()) file_entities[name] = E = new tri_mesh; else E = (tri_mesh*) it->second; int in; string token, st; while(ss >> token) { if(token == "f") { if(ss >> st) { assert(st[0] == '"' && st[st.size()-1] == '"'); string no_quote = st.substr(1, st.size()-2); E->load(no_quote.c_str()); } else assert("Parse error!" && 0); } else if(token == "phong") { if(ss >> in) E->phong = in != 0; else assert("Parse error!" && 0); } else if(token == "X") { if(ss >> st) { texe_it it = file_texture_eval.find(st); if(it != file_texture_eval.end()) E->SetTexture(it->second); } else assert("Parse error!" && 0); } else if(load_entity(ss, token, E)) {} else assert("Parse error!" && 0); } E->CalcNorms(); } void load_sphere(strstream& ss) { string name; ss >> name; Sphere* E; ent_it it = file_entities.find(name); if(it == file_entities.end()) file_entities[name] = E = new Sphere; else E = (Sphere*) it->second; double dx, dy, dz; string token, st; while(ss >> token) { if(token == "c") { if(ss >> dx >> dy >> dz) E->SetCenter(vector3d(dx, dy, dz)); else assert("Parse error!" && 0); } else if(token == "r") { if(ss >> dx) E->SetRadius(dx); else assert("Parse error!" && 0); } else if(token == "X") { if(ss >> st) { texi_it it = file_texture_image.find(st); if(it != file_texture_image.end()) E->SetTexture(it->second); } else assert("Parse error!" && 0); } else if(token == "Xx") { if(ss >> dx >> dy >> dz) { E->SetTextureX(vector3d(dx, dy, dz)); E->ComputeTextureY(); } else assert("Parse error!" && 0); } else if(token == "Xz") { if(ss >> dx >> dy >> dz) { E->SetTextureZ(vector3d(dx, dy, dz)); E->ComputeTextureY(); } else assert("Parse error!" && 0); } else if(load_entity(ss, token, E)) {} else assert("Parse error!" && 0); } } void load_entity_trans(strstream& ss) { string name; ss >> name; Entity_Transform* E; ent_it it = file_entities.find(name); trn_it trnit; if(it == file_entities.end()) file_entities[name] = E = new Entity_Transform; else E = (Entity_Transform*) it->second; string token, st; while(ss >> token) { if(token == "e") { if(ss >> st) { it = file_entities.find(st); if(it != file_entities.end()) E->E = it->second; else assert("Parse error!" && 0); } } else if(token == "z") { if(ss >> st) { trnit = file_transforms.find(st); if(trnit != file_transforms.end()) E->SetChildToParent(*trnit->second); else assert("Parse error!" && 0); } } else assert("Parse error!" && 0); } } void load_trans(strstream& ss) { string name; ss >> name; Transform* E; trn_it it = file_transforms.find(name); if(it == file_transforms.end()) E = file_transforms[name] = new Transform; else E = it->second; double dx, dy, dz, dr; string token; while(ss >> token) { if(token == "r") { if(ss >> dx >> dy >> dz >> dr) E->Rotation(vector3d(dx, dy, dz), dr); else assert("Parse error!" && 0); } else if(token == "s") { if(ss >> dx) E->Scale(dx); else assert("Parse error!" && 0); } else if(token == "tr") { if(ss >> dx >> dy >> dz) E->Translate(vector3d(dx, dy, dz)); else assert("Parse error!" && 0); } else assert("Parse error!" && 0); } } void load_disjoint(strstream& ss) { string name; ss >> name; DisjointEntities* E; ent_it it = file_entities.find(name); if(it == file_entities.end()) file_entities[name] = E = new DisjointEntities; else E = (DisjointEntities*) it->second; string token, st; while(ss >> token) { it = file_entities.find(token); if(it == file_entities.end()) continue; if(!E->A) E->A = it->second; else if(!E->B) E->B = it->second; else E->A = new DisjointEntities(E->A, it->second); } } void load_world(strstream& ss, world_objects& world) { string name; ss >> name; ent_it it; lit_it lit; if(name == "+") { string token; while(ss >> token) { it = file_entities.find(token); if(it == file_entities.end()) continue; world.Insert(it->second); } } else if(name == "+L") { string token; while(ss >> token) { lit = file_lights.find(token); if(lit == file_lights.end()) continue; world.lights.push_back(*lit->second); } } else assert("Parse error!" && 0); } void load_translate(strstream& ss) { string name; ss >> name; Entity_Translate* E; ent_it it = file_entities.find(name); if(it == file_entities.end()) file_entities[name] = E = new Entity_Translate; else E = (Entity_Translate*) it->second; double dx, dy, dz; string token, st; while(ss >> token) { if(token == "tr") { if(ss >> dx >> dy >> dz) E->SetChildToParent(vector3d(dx, dy, dz)); else assert("Parse error!" && 0); } else if(token == "e") { if(ss >> st) { it = file_entities.find(st); if(it != file_entities.end()) E->E = it->second; else assert("Parse error!" && 0); } } else if(load_entity(ss, token, E)) {} else assert("Parse error!" && 0); } } void load_scene_view(strstream& ss, scene_view* sv) { double dx, dy, dz; string token; int in; while(ss >> token) { if(token == "a") { if(ss >> dx >> dy >> dz) Ambient_Background.rgb = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(token == "c") { if(ss >> dx >> dy >> dz) sv->camera = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(token == "e") { if(ss >> dx >> dy >> dz) sv->view_pt = vector3d(dx, dy, dz); else assert("Parse error!" && 0); } else if(token == "sh") { if(ss >> in) sv->screen_h = in; else assert("Parse error!" && 0); } else if(token == "sw") { if(ss >> in) sv->screen_w = in; else assert("Parse error!" && 0); } else if(token == "sf") { if(ss >> in) sv->sample_factor = in; else assert("Parse error!" && 0); } else if(token == "ad") { if(ss >> in) sv->enable_adaptive_sample = in; else assert("Parse error!" && 0); } else assert("Parse error!" && 0); } } void load_image_texture(strstream& ss) { string name; ss >> name; texture_image*E; texi_it it = file_texture_image.find(name); if(it == file_texture_image.end()) file_texture_image[name] = E = new texture_image; else E = (texture_image*) it->second; string token, st; while(ss >> token) { if(token == "f") { if(ss >> st) { string no_quote = st.substr(1, st.size()-2); E->LoadImage(no_quote.c_str()); } else assert("Parse error!" && 0); } else assert("Parse error!" && 0); } } void load_3d_texture(strstream& ss) { string name; ss >> name; TextureEval* E; texe_it it = file_texture_eval.find(name); if(it == file_texture_eval.end()) file_texture_eval[name] = E = new TextureEval; else E = (TextureEval*) it->second; string op, d, s0, s1, s2; ss >> op >> d >> s0 >> s1 >> s2; switch(op[0]) { case '+': if(op == "+") {E->Insert(add_, d, s0, s1); break;} if(op == "++") {E->Insert(inc_, d, s0, s1); break;} break; case '-': if(op == "-") {E->Insert(sub_, d, s0, s1); break;} break; if(op == "--") {E->Insert(dec_, d, s0, s1); break;} break; case '*': if(op == "*") {E->Insert(mul_, d, s0, s1); break;} case '/': if(op == "/") {E->Insert(div_, d, s0, s1); break;} break; case '%': if(op == "%") {E->Insert(mod_, d, s0, s1); break;} break; case '~': if(op == "~") {E->Insert(neg_, d, s0); break;} case '^': if(op == "^") {E->Insert(pow_, d, s0, s1); break;} case '=': if(op == "==") {E->Insert(eq_, d, s0, s1); break;} break; case '!': if(op == "!=") {E->Insert(ne_, d, s0, s1); break;} break; case '>': if(op == ">") {E->Insert(gt_, d, s0, s1); break;} if(op == ">=") {E->Insert(ge_, d, s0, s1); break;} break; case '<': if(op == "<") {E->Insert(lt_, d, s0, s1); break;} if(op == "<=") {E->Insert(le_, d, s0, s1); break;} break; case '.': if(op == ".") {E->Insert(dot_, d, s0, s1); break;} break; case 'a': if(op == "atan2") {E->Insert(atan2_, d, s0, s1); break;} break; case 'c': if(op == "cos") {E->Insert(cos_, d, s0); break;} break; case 'e': if(op == "exp") {E->Insert(exp_, d, s0); break;} if(op == "endif") {E->EndIf(); break;} if(op == "endwhile") {E->EndWhile(); break;} break; case 'g': if(op == "getx") {E->Insert(getx_, d, s0); break;} if(op == "gety") {E->Insert(gety_, d, s0); break;} if(op == "getz") {E->Insert(getz_, d, s0); break;} break; case 'i': if(op == "if") {E->StartIf(s0); break;} break; case 'l': if(op == "log") {E->Insert(log_, d, s0); break;} break; case 'p': if(op == "pack") {E->Insert(pack_, d, s0, s1, s2); break;} break; case 's': if(op == "sin") {E->Insert(sin_, d, s0); break;} break; case 't': if(op == "tan") {E->Insert(tan_, d, s0); break;} break; case 'w': if(op == "pack") {E->StartWhile(s0); break;} break; case 'x': if(op == "x") {E->Insert(cross_, d, s0); break;} break; } }