diff options
author | Stijn Buys <ingar@osirion.org> | 2009-08-12 12:03:18 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2009-08-12 12:03:18 +0000 |
commit | 183f0f0b905715f0d89b38174fdfd44641c1a79c (patch) | |
tree | 6cae553ac6284044002fb668c7991da27291825d /src/model/map.cc | |
parent | 8bf8afe68ca15c61b0dea1f5c1ef5fc7186dca0f (diff) |
src/model filenames cleanup, parse .map texture coordinates, early loading of material textures
Diffstat (limited to 'src/model/map.cc')
-rw-r--r-- | src/model/map.cc | 1212 |
1 files changed, 0 insertions, 1212 deletions
diff --git a/src/model/map.cc b/src/model/map.cc deleted file mode 100644 index 5d699e6..0000000 --- a/src/model/map.cc +++ /dev/null @@ -1,1212 +0,0 @@ -/* - 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 "auxiliary/functions.h" -#include "filesystem/filesystem.h" -#include "math/mathlib.h" -#include "model/map.h" -#include "model/material.h" -#include "model/model.h" -#include "model/vertexarray.h" -#include "sys/sys.h" - -#include <sstream> -#include <string> -#include <cstring> - -namespace model -{ - -// function to test spawnflags -inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag) -{ - return ((spawnflags & flag) == flag); -} - -// max geometry bounds -const float MAX_BOUNDS = 16384; - -const float MIN_DELTA = 10e-10; - -MapFile::MapFile() : map_center(0,0,0) -{ - mapfile_name.clear(); - map_brushes = 0; - map_faces = 0; - map_faces_detail = 0; - - warning_q2brush = false; -} - -MapFile::~MapFile() -{ - clear_materials(); -} - -void MapFile::clear_materials() -{ - for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) { - // delete list of primitives - delete(*mit).second; - } - map_materials.clear(); -} - -bool MapFile::open(std::string const & mapname) -{ - warning_q2brush = false; - last_read_was_classname = false; - last_read_was_key = false; - key_current = ""; - value_current = ""; - classname_current = ""; - line_number = 0; - parse_level = 0; - - clear_materials(); - - mapfile_name.append(mapname); - mapfile_name.append(".map"); - - mapfile_ifs.open(mapfile_name); - if (!mapfile_ifs.is_open()) { - return false; - } - return true; -} - - -bool MapFile::got_classname() const -{ - return last_read_was_classname; -} - -bool MapFile::got_classname(const char * classnamelabel) const -{ - return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0)); -} - -bool MapFile::got_classend(const char * classnamelabel) const -{ - return (last_read_was_classend && (classname_current.compare(classnamelabel) == 0)); -} - -bool MapFile::getline() -{ - using math::Vector3f; - - last_read_was_classname = false; - last_read_was_key = false; - last_read_was_classend = false; - - key_current = ""; - value_current = ""; - - if (!mapfile_ifs.is_open()) - return false; - - char data[1024]; - memset(data, 0, sizeof(data)); - - if (mapfile_ifs.getline(data, 1023)) { - line_number++; - std::istringstream linestream(data); - std::string firstword; - - if (linestream >> firstword) { - if (!firstword.size()) { - return true; - - } else if (firstword == "//") { - return true; - - } else if (firstword == "{") { - parse_level++; - - } else if (firstword == "}") { - if ((parse_level == 2) && (planes.size())) { - // end-of-brush - - // for every face - for (std::vector<Plane *>::iterator face = planes.begin(); face != planes.end(); face++) { - make_brushface((*face)); - } - - // clean planes - for (std::vector<Plane *>::iterator it = planes.begin(); it != planes.end(); it++) { - delete(*it); - } - planes.clear(); - - map_brushes++; - - value_current.clear(); - - } else if ((parse_level == 1)) { - // end-of-class - last_read_was_classend = true; - } - - parse_level--; - - } else if (parse_level == 1) { - - if (firstword == "\"classname\"") { - classname_current.clear(); - - if (linestream >> classname_current) { - if (classname_current.size() > 2) { - classname_current.erase(0,1); - classname_current.erase(classname_current.size()-1, 1); - last_read_was_classname = true; - } else { - classname_current.clear(); - } - } - - } else if ((firstword.size() > 2) && (firstword[0] == '\"') && (firstword[firstword.size()-1] == '\"')) { - - key_current.assign(firstword); - key_current.erase(0,1); - key_current.erase(key_current.size()-1, 1); - - value_current.clear(); - char c; - while ((linestream.get(c)) && (c != '"')); - while ((linestream.get(c)) && (c != '"')) - value_current += c; - - last_read_was_key = true; - } - - } else if (parse_level == 2) { - - if (firstword == "(") { - // brush plane - - Vector3f p1, p2, p3; - std::string tmp; - std::string texture; - int n = 0; - - linestream >> p1; - linestream >> tmp; // ) - linestream >> tmp; // ( - linestream >> p2; - linestream >> tmp; // ) - linestream >> tmp; // ( - linestream >> p3; - linestream >> tmp; // ) - linestream >> texture; - - // 5 numbers (texture alignment?) - for (int i=0; i < 5; i++) - linestream >> tmp; - - // content flags ? - if (!(linestream >> n)) - n = 0; - - Plane *plane = new Plane(p1, p2, p3); - aux::to_lowercase(texture); - plane->texture() = texture; - if (n > 0) - plane->detail() = true; - - // surface flags - if (!(linestream >> n)) { - n = 0; - warning_q2brush = true; - } - plane->surface_flags() = n; - - planes.push_back(plane); - - value_current.clear(); - } - } - } - } else { - - return false; - } - - return true; -} - -void MapFile::make_brushface(Plane *face) -{ - using math::Vector3f; - - // ignore caulk - if (face->texture() == "common/caulk") { - return; - } - - // FIXME clip should be parsed as collision blocks - if (face->texture() == "common/clip") { - return; - } - - // statistics - map_faces++; - if (face->detail()) { - map_faces_detail++; - } - - // using suggestions from - // http://www.flipcode.com/archives/Level_Editing.shtml - - // vertex list - std::vector<math::Vector3f *> vl; - - // calculate initial vertices on the bounding box - - // check if the face is x-axis oriented - if ((fabsf(face->normal().x) >= fabsf(face->normal().y)) && (fabsf(face->normal().x) >= fabsf(face->normal().z))) { - - if (face->normal().x > MIN_DELTA) { - vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, MAX_BOUNDS, MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, MAX_BOUNDS, -MAX_BOUNDS)); - } else { - vl.push_back(new math::Vector3f(0, MAX_BOUNDS, -MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, MAX_BOUNDS, MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, MAX_BOUNDS)); - vl.push_back(new math::Vector3f(0, -MAX_BOUNDS, -MAX_BOUNDS)); - } - // calculate the x coordinate of each face vertex - for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - (*it)->x = (-face->d() - - face->normal().z * (*it)->z - - face->normal().y * (*it)->y) / - face->normal().x; - } - } - - // check if the face is y-axis oriented - else if ((fabsf(face->normal().y) >= fabsf(face->normal().x)) && (fabsf(face->normal().y) >= fabsf(face->normal().z))) { - - if (face->normal().y > MIN_DELTA) { - vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS)); - vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS)); - vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS)); - vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS)); - } else { - vl.push_back(new Vector3f(-MAX_BOUNDS, 0, -MAX_BOUNDS)); - vl.push_back(new Vector3f(-MAX_BOUNDS, 0, MAX_BOUNDS)); - vl.push_back(new Vector3f(MAX_BOUNDS, 0, MAX_BOUNDS)); - vl.push_back(new Vector3f(MAX_BOUNDS, 0, -MAX_BOUNDS)); - } - - // calculate the x coordinate of each face vertex - for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - (*it)->y = (-face->d() - - face->normal().z * (*it)->z - - face->normal().x * (*it)->x) / - face->normal().y; - } - } - - // face must be z-axis oriented - else { - - if (face->normal().z > MIN_DELTA) { - vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(MAX_BOUNDS, MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(MAX_BOUNDS, -MAX_BOUNDS, 0)); - } else { - vl.push_back(new Vector3f(MAX_BOUNDS, -MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(MAX_BOUNDS, MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(-MAX_BOUNDS, MAX_BOUNDS, 0)); - vl.push_back(new Vector3f(-MAX_BOUNDS, -MAX_BOUNDS, 0)); - } - - // calculate the x coordinate of each face vertex - for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - (*it)->z = (-face->d() - - face->normal().x * (*it)->x - - face->normal().y * (*it)->y) / - face->normal().z; - } - } - - - // intersect the face with every plane - for (std::vector<Plane *>::iterator pit = planes.begin(); pit != planes.end(); pit++) { - - Plane *plane = (*pit); - if (plane == face) { - continue; - } - - Vector3f fn = crossproduct(face->point(1)-face->point(0), face->point(2)-face->point(0)); - Vector3f pn = crossproduct(plane->point(1)-plane->point(0), plane->point(2)-plane->point(0)); - - Vector3f t = crossproduct(fn, pn); - if ((t.x == 0) && (t.y == 0) && (t.z == 0)) { - continue; - } - - // intersect face with plane - for (int i=0; vl.size() - i > 0; i++) { - - Vector3f v(*vl.at(i)); - - Vector3f next; - if (vl.size() - i > 1) { - next = *vl.at(i+1); - } else { - next = *vl.front(); - } - - Vector3f prev; - if (i > 0) { - prev = *vl.at(i-1); - } else { - prev = *vl.back(); - } - - if ((v.x*plane->normal().x + v.y*plane->normal().y + v.z*plane->normal().z +plane->d()) < MIN_DELTA) { - - // find current - std::vector<Vector3f *>::iterator vit = vl.begin(); - while ((*vit) != vl.at(i)) { - vit++; - } - - // check if prev - v intersects with plane - if ((prev.x*plane->normal().x + prev.y*plane->normal().y + prev.z*plane->normal().z + plane->d()) > MIN_DELTA) { - - // calculate intersection - float t1 = -plane->normal().x * prev.x - plane->normal().y * prev.y - plane->normal().z * prev.z -plane->d(); - float t2 = (plane->normal().x * v.x - plane->normal().x * prev.x + - plane->normal().y * v.y - plane->normal().y * prev.y + - plane->normal().z * v.z - plane->normal().z * prev.z); - - Vector3f *s = new Vector3f; - - if (t2 == 0) { - *s = v; - } else { - for (int j = 0; j < 3; j++) - (*s)[j] = prev [j] + t1 * (v[j] - prev[j]) / t2; - } - - vit = vl.insert(vit,s); - vit++; - i++; - } - - // check if next - v intersects with plane - if ((next.x*plane->normal().x + next.y*plane->normal().y + next.z*plane->normal().z + plane->d()) > MIN_DELTA) { - - // calculate intersection - float t1 = -plane->normal().x * v.x - plane->normal().y * v.y - plane->normal().z * v.z -plane->d(); - float t2 = (plane->normal().x * next.x - plane->normal().x * v.x + - plane->normal().y * next.y - plane->normal().y * v.y + - plane->normal().z * next.z - plane->normal().z * v.z); - //cout << "next t2 " << t2 << std::endl; - Vector3f *s = new Vector3f; - - if (t2 == 0) { - *s = v; - } else { - for (int j = 0; j < 3; j++) - (*s)[j] = v [j] + t1 * (next[j] - v[j]) / t2; - } - - vit = vl.insert(vit,s); - vit++; - i++; - } - - // erase - delete *vit; - vl.erase(vit); - i--; - } - - } - } - - if (vl.size() > 2) { - - Material *material = Material::find("textures/" + face->texture()); - - if (!material) { - material = new Material("textures/" + face->texture()); - Material::add(material); - material->set_flags(Material::Texture); - material->set_texture(material->name()); - } - - // find the list if primitives for the current material, allocate a new one if necessary - Primitives *primitives = 0; - - Materials::iterator mit = map_materials.find(material); - if (mit == map_materials.end()) { - primitives = new Primitives(material); - map_materials[material] = primitives; - } else { - primitives = (*mit).second; - } - - // calculate bounding box - for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - *(*it) *= SCALE; - for (int i=0; i < 3; i++) { - if (class_maxbbox[i] < (*(*it))[i]) - class_maxbbox[i] = (*(*it))[i]; - - if (class_minbbox[i] > (*(*it))[i]) - class_minbbox[i] = (*(*it))[i]; - } - } - - -#ifndef HAVE_BULLET - - // Quads are disable to use model data for bullet physics - - // split polygon into quads - while (vl.size() > 3) { - std::vector<Vector3f *>::iterator v0 = vl.begin(); - std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin(); - std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin(); - ++vn1; - std::vector<Vector3f *>::reverse_iterator vn2 = vl.rbegin(); - ++vn2; - ++vn2; - - Vector3f n(face->normal()*-1); - n.normalize(); - - primitives->add_quad(*(*vn2), *(*vn1), *(*vn), *(*v0), n, face->detail()); - delete(*vn); - delete(*vn1); - vl.pop_back(); - vl.pop_back(); - } -#endif - // split polygon into triangles - while (vl.size() > 2) { - std::vector<Vector3f *>::iterator v0 = vl.begin(); - std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin(); - std::vector<Vector3f *>::reverse_iterator vn1 = vl.rbegin(); - ++vn1; - - Vector3f n(face->normal()*-1); - n.normalize(); - - primitives->add_triangle(*(*vn1), *(*vn), *(*v0), n, face->detail()); - delete(*vn); - vl.pop_back(); - } - } else { - con_debug << "Unresolved face!\n"; - } - - // clean up the vertex list - for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - delete(*it); - } - - vl.clear(); -} - -bool MapFile::got_key_string(const char * keylabel, std::string & valuestring) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - valuestring.assign(value_current); - return true; - } else { - return false; - } -} - -bool MapFile::got_key_vector3f(const char * keylabel, math::Vector3f & v) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - std::istringstream is(value_current); - float x, y, z; - if ((is >> x) && (is >> y) && (is >> z)) { - v = math::Vector3f(x,y,z); - } else { - v= math::Vector3f(); - } - return true; - } else { - return false; - } -} - -bool MapFile::got_key_float(const char * keylabel, float & f) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - std::istringstream is(value_current); - if (!(is >> f)) { - f = 0; - } - return true; - } else { - return false; - } -} - -bool MapFile::got_key_int(const char * keylabel, unsigned int & u) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - std::istringstream is(value_current); - if (!(is >> u)) { - u = 0; - } - return true; - } else { - return false; - } -} - -bool MapFile::got_key(const char * keylabel) -{ - return (last_read_was_key && (key_current.compare(keylabel) == 0)); -} - -bool MapFile::got_key_angle(const char * keylabel, float & f) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - std::istringstream is(value_current); - if ((is >> f)) { - f = math::degrees360f(f); - } else { - f = 0; - } - return true; - } else { - return false; - } -} - -bool MapFile::got_key_color(const char * keylabel, math::Color & color) -{ - if (last_read_was_key && (key_current.compare(keylabel) == 0)) { - std::istringstream is(value_current); - float r, g, b; - if ((is >> r) && (is >> g) && (is >> b)) { - if ((r > 1) || (g > 1) || (b > 1)) { - r /= 255; - g /= 255; - b /= 255; - } - color = math::Color(r, g, b); - } else { - color = math::Color(); - } - return true; - } else { - return false; - } -} - -void MapFile::close() -{ - mapfile_ifs.close(); -} - -void MapFile::clear_bbox() -{ - for (int i=0; i < 3; i++) { - class_minbbox[i] = MAX_BOUNDS; - class_maxbbox[i] = -MAX_BOUNDS; - } - - class_axis.clear(); - class_speed = 0; -} - -void MapFile::load_worldspawn(Model *model) -{ - if (!map_materials.size()) - return; - - // FIXME center in maps without brushes - map_center = (class_minbbox + class_maxbbox) / 2.0f; - - model->model_minbbox = class_minbbox - map_center; - model->model_maxbbox = class_maxbbox - map_center; - - model->model_radius = model->model_maxbbox.length(); - - load_fragmentgroup(model, FragmentGroup::None); -} - -void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) -{ - if (!VertexArray::instance() || VertexArray::instance()->overflow()) - return; - - if (!map_materials.size()) - return; - - FragmentGroup *group = new FragmentGroup(); - - if (class_type == FragmentGroup::Rotate) { - if (class_speed == 0) { - // default rotation speed 45 degrees per second - class_speed = 45.0f; - } - } - - if (class_type != FragmentGroup::None) { - group->set_transform(true); - } - - group->set_type(class_type); - group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center); - group->set_axis(class_axis); - group->set_speed(class_speed); - - math::Vector3f group_center(map_center); - if (group->transform()) { - group_center += group->location(); - } - - for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) { - // split the Primitives with this material into fragments - Primitives *primitives = (*mit).second; - - // store triangles - if (primitives->triangles().size()) { - Fragment *fragment = new Fragment(Fragment::Triangles, primitives->material()); - - // add structural triangles to the fragment - for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { - Triangle *triangle = (*tris_it); - if (!triangle->detail()) { - size_t count = 0; - count += fragment->add_vertex(triangle->v0()-group_center, triangle->normal(), false); - count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), false); - count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), false); - if (count == 3) - model->model_tris_count++; - } - } - - // add detail triangles to the fragment - for (Primitives::Triangles::iterator tris_it = primitives->triangles().begin(); tris_it != primitives->triangles().end(); tris_it++) { - Triangle *triangle = (*tris_it); - if (triangle->detail()) { - size_t count = 0; - count += fragment->add_vertex(triangle->v0()-group_center, triangle->normal(), true); - count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), true); - count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), true); - if (count == 3) { - model->model_tris_count++; - model->model_tris_detail_count++; - } - } - } - - // add the fragment to the group - group->add_fragment(fragment); - } - - // store quads - if (primitives->quads().size()) { - Fragment *fragment = new Fragment(Fragment::Quads, primitives->material()); - - // add structural triangles to the fragment - for (Primitives::Quads::iterator quad_it = primitives->quads().begin(); quad_it != primitives->quads().end(); quad_it++) { - Quad *quad = (*quad_it); - if (!quad->detail()) { - size_t count = 0; - count += fragment->add_vertex(quad->v0()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v1()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v2()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v3()-group_center, quad->normal(), false); - if (count == 4) - model->model_quad_count++; - } - } - - // add detail triangles to the fragment - for (Primitives::Quads::iterator quad_it = primitives->quads().begin(); quad_it != primitives->quads().end(); quad_it++) { - Quad *quad = (*quad_it); - if (quad->detail()) { - size_t count = 0; - count += fragment->add_vertex(quad->v0()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v1()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v2()-group_center, quad->normal(), false); - count += fragment->add_vertex(quad->v3()-group_center, quad->normal(), false); - if (count == 4) { - model->model_quad_count++; - model->model_quad_detail_count++; - } - } - } - - // add the fragment to the group - group->add_fragment(fragment); - } - - } - - // add the group to the model - model->add_group(group); -} - -void MapFile::unknown_value() const -{ - con_warn << name() << " unknown value '" << value() << "' for '" << classname() << ":" << key() << "' at line " << line() << std::endl; -} - -void MapFile::unknown_key() const -{ - con_warn << name() << " unknown key '" << classname() << ":" << key() << "' at line " << line() << std::endl; -} - -void MapFile::unknown_class() const -{ - con_warn << name() << " unknown class '" << classname() << "' at line " << line() << std::endl; -} - -Model * MapFile::load(std::string const &name) -{ - // open the .map file - MapFile mapfile; - - if (!mapfile.open(name)) { - return 0; - } - - Model *model = new Model(name); - mapfile.clear_bbox(); - - Dock *dock = 0; - Particles *particles = 0; - Flare *flare = 0; - Light *light = 0; - SubModel *submodel = 0; - - std::string modelname; - math::Vector3f location; - - typedef std::list<SubModel *> SubModelList; - SubModelList submodel_list; - - unsigned int u; - float angle; - float r, s; - std::string str; - - while (mapfile.getline()) { - - if (mapfile.got_classname("worldspawn")) { - mapfile.clear_bbox(); - - } else if (mapfile.got_classend("worldspawn")) { - mapfile.load_worldspawn(model); - mapfile.clear_materials(); - - } else if (mapfile.in_class("worldspawn")) { - - // worldspawn attributes - if (mapfile.got_key("name")) { - con_debug << " model name '" << name << "'" << std::endl; - - } else if (mapfile.got_key_int("enginesound", u)) { - model->model_enginesound = u; - continue; - - } else if (mapfile.got_key_int("impulsesound", u)) { - model->model_impulsesound = u; - continue; - - } else if (mapfile.got_key_color("enginecolor", model->model_enginecolor)) { - continue; - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - - } - - } else if (mapfile.got_classname("func_door")) { - mapfile.clear_bbox(); - - } else if (mapfile.got_classend("func_door")) { - mapfile.load_fragmentgroup(model, FragmentGroup::Door); - mapfile.clear_materials(); - - } else if (mapfile.in_class("func_door")) { - - } else if (mapfile.got_classname("func_group")) { - mapfile.clear_bbox(); - - } else if (mapfile.got_classend("func_group")) { - mapfile.load_fragmentgroup(model, FragmentGroup::None); - mapfile.clear_materials(); - - } else if (mapfile.got_classname("func_rotate")) { - mapfile.clear_bbox(); - - } else if (mapfile.got_classend("func_rotate")) { - mapfile.load_fragmentgroup(model, FragmentGroup::Rotate); - mapfile.clear_materials(); - - } else if (mapfile.in_class("func_rotate")) { - - if (mapfile.got_key_float("angle", angle)) { - if (angle == ANGLEUP) { - mapfile.class_axis.change_pitch(90.0f); - } else if (angle == ANGLEDOWN) { - mapfile.class_axis.change_pitch(-90.0f); - } else { - mapfile.class_axis.change_direction(angle); - } - } else if (mapfile.got_key_float("direction", angle)) { - mapfile.class_axis.change_direction(angle); - - } else if (mapfile.got_key_float("pitch", angle)) { - mapfile.class_axis.change_pitch(angle); - - } else if (mapfile.got_key_float("roll", angle)) { - mapfile.class_axis.change_roll(angle); - - } else if (mapfile.got_key_float("speed", mapfile.class_speed)) { - continue; - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - } - - } else if (mapfile.got_classend()) { - mapfile.clear_materials(); - - } 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 *= LIGHTSCALE; - - } else if (mapfile.got_key_float("radius", light->light_radius)) { - light->light_radius *= LIGHTSCALE; - - } 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_key()) { - mapfile.unknown_key(); - - } - - } else if (mapfile.got_classname("location_dock")) { - - // new docking location - dock = new Dock(); - model->add_dock(dock); - - } else if (mapfile.classname().compare("location_dock") == 0) { - - // dock attributes - if (mapfile.got_key_vector3f("origin", dock->dock_location)) { - dock->dock_location *= SCALE; - continue; - - } else if (mapfile.got_key_float("radius", dock->dock_radius)) { - dock->dock_radius *= SCALE; - continue; - - } else if (mapfile.got_key("angle")) { - continue; - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - - } - - } else if (mapfile.got_classname("location_cannon")) { - // new cannon - - } else if (mapfile.classname().compare("location_cannon") == 0) { - - } else if (mapfile.got_classname("location_turret")) { - // new turret - - } else if (mapfile.classname().compare("location_turret") == 0) { - - } else if (mapfile.got_classname("location_cockpit")) { - // cockpit location - - } else if (mapfile.classname().compare("location_cockpit") == 0) { - - } else if (mapfile.got_classname("fx_flare")) { - - // new flare - flare = new Flare(); - model->add_flare(flare); - - } else if (mapfile.classname().compare("fx_flare") == 0) { - - // flare attributes - if (mapfile.got_key_vector3f("origin", flare->light_location)) { - flare->light_location *= SCALE; - continue; - - } else if (mapfile.got_key_color("_color", flare->light_color)) { - continue; - - } else if (mapfile.got_key_int("spawnflags", u)) { - flare->light_strobe = spawnflag_isset(u, 1); - flare->light_entity = spawnflag_isset(u, 2); - flare->flare_engine = spawnflag_isset(u, 4); - - } else if (mapfile.got_key_float("radius", flare->light_radius)) { - flare->light_radius *= LIGHTSCALE; - - } else if (mapfile.got_key_float("frequency", flare->light_frequency)) { - continue; - - } else if (mapfile.got_key_float("offset", flare->light_offset)) { - continue; - - } else if (mapfile.got_key_float("time", flare->light_time)) { - continue; - - } else if (mapfile.got_key_int("flare", flare->light_flare)) { - continue; - - } else if (mapfile.got_key_float("angle", angle)) { - if (angle == ANGLEUP) { - flare->flare_axis.change_pitch(90.0f); - } else if (angle == ANGLEDOWN) { - flare->flare_axis.change_pitch(-90.0f); - } else { - flare->flare_axis.change_direction(angle); - } - } else if (mapfile.got_key_float("direction", angle)) { - flare->flare_axis.change_direction(angle); - - } else if (mapfile.got_key_float("pitch", angle)) { - flare->flare_axis.change_pitch(angle); - - } else if (mapfile.got_key_float("roll", angle)) { - flare->flare_axis.change_roll(angle); - - } else if (mapfile.got_key_string("cull", str)) { - - aux::to_lowercase(str); - if (str.compare("none") == 0) { - flare->flare_cull = CullNone; - } else if (str.compare("back") == 0) { - flare->flare_cull = CullBack; - } else if (str.compare("front") == 0) { - flare->flare_cull = CullFront; - } else { - mapfile.unknown_value(); - } - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - } - - } else if (mapfile.got_classname("misc_model")) { - - // new submodel - submodel = new SubModel(); - submodel_list.push_back(submodel); - - } else if (mapfile.classname().compare("misc_model") == 0) { - - // submodel attributes - if (mapfile.got_key_vector3f("origin", location)) { - submodel->set_location(location * SCALE); - continue; - - } else if (mapfile.got_key_string("model", modelname)) { - - // remove extension - if (modelname[modelname.size()-4] == '.') { - modelname.erase(modelname.size()-4); - } - - submodel->set_name(modelname); - continue; - - } else if (mapfile.got_key_float("angle", angle)) { - if (angle == ANGLEUP) { - submodel->axis().change_pitch(90.0f); - } else if (angle == ANGLEDOWN) { - submodel->axis().change_pitch(-90.0f); - } else { - submodel->axis().change_direction(angle); - } - - } else if (mapfile.got_key_float("modelscale", s)) { - if (s) { - submodel->set_scale(s); - } else { - submodel->set_scale(1.0f); - } - } - - } else if (mapfile.got_classname("fx_particles")) { - - // new particle system - particles = new Particles(); - model->add_particles(particles); - - } else if (mapfile.classname().compare("fx_particles") == 0) { - - // particle system attributes - if (mapfile.got_key_vector3f("origin", particles->particles_location)) { - particles->particles_location *= SCALE; - continue; - } else if (mapfile.got_key_string("script", particles->particles_script)) { - continue; - } else if (mapfile.got_key_float("angle", angle)) { - if (angle == ANGLEUP) { - particles->particles_axis.change_pitch(90.0f); - } else if (angle == ANGLEDOWN) { - particles->particles_axis.change_pitch(-90.0f); - } else { - particles->particles_axis.change_direction(angle); - } - } else if (mapfile.got_key_float("direction", angle)) { - particles->particles_axis.change_direction(angle); - - } else if (mapfile.got_key_float("pitch", angle)) { - particles->particles_axis.change_pitch(angle); - - } else if (mapfile.got_key_float("roll", angle)) { - particles->particles_axis.change_roll(angle); - - } else if (mapfile.got_key_int("spawnflags", u)) { - particles->particles_entity = spawnflag_isset(u, 2); - particles->particles_engine = spawnflag_isset(u, 4); - - } else if (mapfile.got_key_float("radius", r)) { - particles->set_radius(r * LIGHTSCALE); - - } else if (mapfile.got_key_string("cull", str)) { - - aux::to_lowercase(str); - if (str.compare("none") == 0) { - particles->particles_cull = CullNone; - } else if (str.compare("back") == 0) { - particles->particles_cull = CullBack; - } else if (str.compare("front") == 0) { - particles->particles_cull = CullFront; - } else { - mapfile.unknown_value(); - } - - } else if (mapfile.got_key()) { - mapfile.unknown_key(); - } - } else if (mapfile.got_classname()) { - mapfile.unknown_class(); - } - } - - mapfile.close(); - - // reposition docks, lights, flares and particles according to the model center - for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { - (*lit)->light_location -= mapfile.map_center; - } - - for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { - (*flit)->light_location -= mapfile.map_center; - } - - for (Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) { - (*pit)->particles_location -= mapfile.map_center; - } - - for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { - (*dit)->dock_location -= mapfile.map_center; - } - - // FIXME this will go wrong if a Rotate group is imported as submodel - for (SubModelList::iterator smit = submodel_list.begin(); smit != submodel_list.end(); smit++) { - submodel = (*smit); - Model *submodel_model = 0; - - if (submodel->name().size()) { - submodel_model = Model::load(submodel->name()); - } - - if (submodel_model) { - // copy fragmentgroups - for (Model::Groups::iterator git = submodel_model->groups().begin(); git != submodel_model->groups().end(); git++) { - FragmentGroup *groupsrc = (*git); - FragmentGroup *groupdst = new FragmentGroup(); - - groupdst->set_transform(true); - groupdst->set_type(groupsrc->type()); - groupdst->set_scale(groupsrc->scale() * submodel->scale()); - groupdst->set_speed(groupsrc->speed()); - groupdst->set_location(groupsrc->location() + (submodel->location() - mapfile.map_center)); - groupdst->set_axis(groupsrc->axis() * submodel->axis()); - - // copy fragments - for (FragmentGroup::iterator fit = groupsrc->begin(); fit != groupsrc->end(); fit++) { - Fragment *fragmentdst = new Fragment(*(*fit)); - groupdst->add_fragment(fragmentdst); - } - - if (groupdst->size()) { - model->add_group(groupdst); - } else { - delete groupdst; - } - } - - con_debug << " imported submodel '" << submodel->name() << "'" << std::endl; - } - - delete submodel; - - } - - con_debug << " " << mapfile.name() << " " << mapfile.map_brushes << " brushes " << - mapfile.map_faces << "/" << mapfile.map_faces_detail << " faces/detail " << std::endl; - if (mapfile.warning_q2brush) - con_warn << " quake2 style brushes detected" << std::endl; - - return model; -} - -} - |