diff options
author | Stijn Buys <ingar@osirion.org> | 2009-08-11 11:49:12 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2009-08-11 11:49:12 +0000 |
commit | 25bcd92706ce2cd6aee24cfb81e9ff2fd7dd4820 (patch) | |
tree | 19e71f817ffc36247f4db718454f3634904284b0 /src/model/map.cc | |
parent | a2ae048571310e80ba7502f1d81b5dd2eb1e38fa (diff) |
misc_model support
Diffstat (limited to 'src/model/map.cc')
-rw-r--r-- | src/model/map.cc | 161 |
1 files changed, 129 insertions, 32 deletions
diff --git a/src/model/map.cc b/src/model/map.cc index 9cb5295..164be3e 100644 --- a/src/model/map.cc +++ b/src/model/map.cc @@ -31,20 +31,22 @@ const float MAX_BOUNDS = 16384; const float MIN_DELTA = 10e-10; -Map::Map() : map_center(0,0,0) +MapFile::MapFile() : map_center(0,0,0) { mapfile_name.clear(); map_brushes = 0; map_faces = 0; map_faces_detail = 0; + + warning_q2brush = false; } -Map::~Map() +MapFile::~MapFile() { clear_materials(); } -void Map::clear_materials() +void MapFile::clear_materials() { for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) { // delete list of primitives @@ -53,9 +55,9 @@ void Map::clear_materials() map_materials.clear(); } -bool Map::open(std::string const & mapname) +bool MapFile::open(std::string const & mapname) { - + warning_q2brush = false; last_read_was_classname = false; last_read_was_key = false; key_current = ""; @@ -66,7 +68,6 @@ bool Map::open(std::string const & mapname) clear_materials(); - mapfile_name.assign("maps/"); mapfile_name.append(mapname); mapfile_name.append(".map"); @@ -78,22 +79,22 @@ bool Map::open(std::string const & mapname) } -bool Map::got_classname() const +bool MapFile::got_classname() const { return last_read_was_classname; } -bool Map::got_classname(const char * classnamelabel) const +bool MapFile::got_classname(const char * classnamelabel) const { return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0)); } -bool Map::got_classend(const char * classnamelabel) const +bool MapFile::got_classend(const char * classnamelabel) const { return (last_read_was_classend && (classname_current.compare(classnamelabel) == 0)); } -bool Map::getline() +bool MapFile::getline() { using math::Vector3f; @@ -216,8 +217,10 @@ bool Map::getline() plane->detail() = true; // surface flags - if (!(linestream >> n)) + if (!(linestream >> n)) { n = 0; + warning_q2brush = true; + } plane->surface_flags() = n; planes.push_back(plane); @@ -234,7 +237,7 @@ bool Map::getline() return true; } -void Map::make_brushface(Plane *face) +void MapFile::make_brushface(Plane *face) { using math::Vector3f; @@ -517,7 +520,7 @@ void Map::make_brushface(Plane *face) vl.clear(); } -bool Map::got_key_string(const char * keylabel, std::string & valuestring) +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); @@ -527,7 +530,7 @@ bool Map::got_key_string(const char * keylabel, std::string & valuestring) } } -bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v) +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); @@ -543,7 +546,7 @@ bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v) } } -bool Map::got_key_float(const char * keylabel, float & f) +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); @@ -556,7 +559,7 @@ bool Map::got_key_float(const char * keylabel, float & f) } } -bool Map::got_key_int(const char * keylabel, unsigned int & u) +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); @@ -569,12 +572,12 @@ bool Map::got_key_int(const char * keylabel, unsigned int & u) } } -bool Map::got_key(const char * keylabel) +bool MapFile::got_key(const char * keylabel) { return (last_read_was_key && (key_current.compare(keylabel) == 0)); } -bool Map::got_key_angle(const char * keylabel, float & f) +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); @@ -589,7 +592,7 @@ bool Map::got_key_angle(const char * keylabel, float & f) } } -bool Map::got_key_color(const char * keylabel, math::Color & color) +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); @@ -610,12 +613,12 @@ bool Map::got_key_color(const char * keylabel, math::Color & color) } } -void Map::close() +void MapFile::close() { mapfile_ifs.close(); } -void Map::clear_bbox() +void MapFile::clear_bbox() { for (int i=0; i < 3; i++) { class_minbbox[i] = MAX_BOUNDS; @@ -626,7 +629,7 @@ void Map::clear_bbox() class_speed = 0; } -void Map::load_worldspawn(Model *model) +void MapFile::load_worldspawn(Model *model) { if (!map_materials.size()) return; @@ -642,22 +645,25 @@ void Map::load_worldspawn(Model *model) load_fragmentgroup(model, FragmentGroup::None); } -void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) +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; } + + group->set_transform(true); } - FragmentGroup *group = new FragmentGroup(); group->set_type(class_type); group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center); group->set_axis(class_axis); @@ -700,7 +706,7 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) } // add the fragment to the group - group->push_back(fragment); + group->add_fragment(fragment); } // store quads @@ -738,7 +744,7 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) } // add the fragment to the group - group->push_back(fragment); + group->add_fragment(fragment); } } @@ -747,25 +753,25 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) model->add_group(group); } -void Map::unknown_value() const +void MapFile::unknown_value() const { con_warn << name() << " unknown value '" << value() << "' for '" << classname() << ":" << key() << "' at line " << line() << std::endl; } -void Map::unknown_key() const +void MapFile::unknown_key() const { con_warn << name() << " unknown key '" << classname() << ":" << key() << "' at line " << line() << std::endl; } -void Map::unknown_class() const +void MapFile::unknown_class() const { con_warn << name() << " unknown class '" << classname() << "' at line " << line() << std::endl; } -Model * Map::load(std::string const &name) +Model * MapFile::load(std::string const &name) { // open the .map file - Map mapfile; + MapFile mapfile; if (!mapfile.open(name)) { return 0; @@ -778,10 +784,17 @@ Model * Map::load(std::string const &name) 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; + float r, s; std::string str; while (mapfile.getline()) { @@ -1019,6 +1032,46 @@ Model * Map::load(std::string const &name) } 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")) { @@ -1098,8 +1151,52 @@ Model * Map::load(std::string const &name) (*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; } |