/* model/map.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "model/engine.h" #include "model/light.h" #include "model/map.h" #include "model/mapfile.h" #include "model/vertexarray.h" #include "sys/sys.h" namespace model { // function to test spawnflags inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag) { return ((spawnflags & flag) == flag); } Model * Map::load(std::string const &name) { // open the .map file MapFile mapfile; if (!mapfile.open(name)) { return 0; } Model *model = new Model(name); Light *light = 0; Engine *engine = 0; unsigned int u; while (mapfile.getline()) { if (mapfile.got_classname("worldspawn")) { } else if (mapfile.got_classname("light")) { // new light light = new Light(); model->add_light(light); } else if (mapfile.classname().compare("light") == 0 ) { // light attributes if (mapfile.got_key_vector3f("origin", light->light_location)) { light->light_location *= SCALE; continue; } else if (mapfile.got_key_color("_color", light->light_color)) { continue; } else if (mapfile.got_key_int("spawnflags", u)) { light->light_strobe = spawnflag_isset(u, 1); light->light_entity = spawnflag_isset(u, 2); } else if (mapfile.got_key_float("light", light->light_radius)) { light->light_radius /= 100.0f; } else if (mapfile.got_key_float("frequency", light->light_frequency)) { continue; } else if (mapfile.got_key_float("offset", light->light_offset)) { continue; } else if (mapfile.got_key_float("time", light->light_time)) { continue; } else if (mapfile.got_key_int("flare", light->light_flare)) { continue; } } else if (mapfile.got_classname("target_engine")) { // new engine engine = new Engine(); model->add_engine(engine); } else if (mapfile.classname().compare("target_engine") == 0 ) { // engine attributes if (mapfile.got_key_vector3f("origin", engine->engine_location)) { engine->engine_location *= SCALE; continue; } else if (mapfile.got_key_color("_color", engine->engine_color)) { continue; } else if (mapfile.got_key_float("radius", engine->engine_radius)) { engine->engine_radius /= 100.0f; continue; } else if (mapfile.got_key_int("flare", engine->engine_flare)) { continue; } } } mapfile.close(); if (VertexArray::instance() && ((mapfile.class_tris.size() + mapfile.class_etris.size()) > 0)) { math::Vector3f center = (mapfile.class_minbbox + mapfile.class_maxbbox) / 2; model->model_minbbox = mapfile.class_minbbox - center; model->model_maxbbox = mapfile.class_maxbbox - center; model->model_radius = model->model_maxbbox.length(); // structural triangles model->model_first_vertex = VertexArray::instance()->index()/3; for (std::list::iterator it = mapfile.class_tris.begin(); it != mapfile.class_tris.end(); it++) { Triangle *triangle = (*it); if (!triangle->detail()) { VertexArray::instance()->add_vertex(triangle->triangle_v0-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v1-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v2-center, triangle->normal(), triangle->color() ); model->model_vertex_count += 3; } } // detail triangles for (std::list::iterator it = mapfile.class_tris.begin(); it != mapfile.class_tris.end(); it++) { Triangle *triangle = (*it); if (triangle->detail()) { VertexArray::instance()->add_vertex(triangle->triangle_v0-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v1-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v2-center, triangle->normal(), triangle->color() ); model->model_vertex_countdetail += 3; } delete triangle; } mapfile.class_tris.clear(); // structural etriangles model->model_first_evertex = VertexArray::instance()->index()/3; for (std::list::iterator it = mapfile.class_etris.begin(); it != mapfile.class_etris.end(); it++) { Triangle *triangle = (*it); if (!triangle->detail()) { VertexArray::instance()->add_vertex(triangle->triangle_v0-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v1-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v2-center, triangle->normal(), triangle->color() ); model->model_evertex_count += 3; } } // detail etriangles for (std::list::iterator it = mapfile.class_etris.begin(); it != mapfile.class_etris.end(); it++) { Triangle *triangle = (*it); if (triangle->detail()) { VertexArray::instance()->add_vertex(triangle->triangle_v0-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v1-center, triangle->normal(), triangle->color() ); VertexArray::instance()->add_vertex(triangle->triangle_v2-center, triangle->normal(), triangle->color() ); model->model_evertex_countdetail += 3; } delete triangle; } mapfile.class_etris.clear(); // reposition light and engines for (std::list::iterator eit = model->model_engine.begin(); eit != model->model_engine.end(); eit++) { (*eit)->engine_location -= center; } for (std::list::iterator lit = model->model_light.begin(); lit != model->model_light.end(); lit++) { (*lit)->light_location -= center; } } con_print << " maps/" << model->name() << ".map " << mapfile.brushes << " brush " << model->tris() << " tris (" << model->details() << " detail)" << std::endl; return model; } }