diff options
Diffstat (limited to 'src/model')
-rw-r--r-- | src/model/fragment.cc | 1 | ||||
-rw-r--r-- | src/model/fragment.h | 16 | ||||
-rw-r--r-- | src/model/map.cc | 65 | ||||
-rw-r--r-- | src/model/map.h | 5 | ||||
-rw-r--r-- | src/model/model.cc | 20 | ||||
-rw-r--r-- | src/model/model.h | 15 |
6 files changed, 93 insertions, 29 deletions
diff --git a/src/model/fragment.cc b/src/model/fragment.cc index db34fdb..044e232 100644 --- a/src/model/fragment.cc +++ b/src/model/fragment.cc @@ -41,6 +41,7 @@ size_t Fragment::add_vertex(math::Vector3f const & vertex, math::Vector3f const FragmentGroup::FragmentGroup() { + group_type = None; } FragmentGroup::~FragmentGroup() diff --git a/src/model/fragment.h b/src/model/fragment.h index 409bb97..fcdeca3 100644 --- a/src/model/fragment.h +++ b/src/model/fragment.h @@ -74,12 +74,17 @@ private: class FragmentGroup { public: + enum Type {None = 0, Rotate = 1, Door = 2 }; + typedef std::list<Fragment *>::iterator iterator; FragmentGroup(); + ~FragmentGroup(); - void clear(); + inline const math::Vector3f &location() const { return group_location; } + + inline const Type type() const { return group_type; } inline iterator begin() { return group_fragments.begin(); } @@ -89,11 +94,20 @@ public: inline void push_back(Fragment *fragment) { group_fragments.push_back(fragment); } + inline void set_location(const math::Vector3f &location) { group_location.assign(location); } + + inline void set_type(const Type type) { group_type = type; } + + void clear(); private: /// type definition for a list of model fragments typedef std::list<Fragment *> Fragments; Fragments group_fragments; + math::Vector3f group_location; + math::Vector3f group_forward; + + Type group_type; }; } diff --git a/src/model/map.cc b/src/model/map.cc index f2c519f..71b0dda 100644 --- a/src/model/map.cc +++ b/src/model/map.cc @@ -242,6 +242,14 @@ bool Map::getline() return true; } +void Map::clear_bbox() +{ + for (int i=0; i < 3; i++) { + class_minbbox[i] = MAX_BOUNDS; + class_maxbbox[i] = -MAX_BOUNDS; + } +} + void Map::make_brushface(Plane *face) { using math::Vector3f; @@ -445,7 +453,7 @@ void Map::make_brushface(Plane *face) // default material is none unsigned int material = 0; - // default color makrs unknown textures hot pink + // default color makes unknown textures hot pink math::Color color(1.0f, 0.0, 1.0f, 1.0f); // translate texture names to color and material @@ -516,9 +524,7 @@ void Map::make_brushface(Plane *face) // 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]; @@ -528,6 +534,7 @@ void Map::make_brushface(Plane *face) } } + // split polygon into quads while (vl.size() > 3) { std::vector<Vector3f *>::iterator v0 = vl.begin(); std::vector<Vector3f *>::reverse_iterator vn = vl.rbegin(); @@ -677,24 +684,28 @@ void Map::load_worldspawn(Model *model) return; // FIXME center in maps without brushes - map_center = (class_minbbox + class_maxbbox) / 2; + 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, model->worldspawn()); + load_fragmentgroup(model, FragmentGroup::None); } -void Map::load_fragmentgroup(Model *model, FragmentGroup &group) +void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type type) { if (!VertexArray::instance() || VertexArray::instance()->overflow()) return; if (!map_materials.size()) return; - + + FragmentGroup *group = new FragmentGroup(); + group->set_type(type); + group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center); + for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) { // split the Primitives with this material into fragments Primitives *primitives = (*mit).second; @@ -731,8 +742,8 @@ void Map::load_fragmentgroup(Model *model, FragmentGroup &group) } } - // add the fragment to the fragment group - group.push_back(fragment); + // add the fragment to the group + group->push_back(fragment); } // store quads @@ -769,12 +780,14 @@ void Map::load_fragmentgroup(Model *model, FragmentGroup &group) } } - // add the fragment to the model - group.push_back(fragment); + // add the fragment to the group + group->push_back(fragment); } } - + + // add the group to the model + model->add_group(group); } Model * Map::load(std::string const &name) @@ -787,6 +800,7 @@ Model * Map::load(std::string const &name) } Model *model = new Model(name); + mapfile.clear_bbox(); Dock *dock = 0; Particles *particles = 0; @@ -799,13 +813,12 @@ Model * Map::load(std::string const &name) while (mapfile.getline()) { if (mapfile.got_classname("worldspawn")) { - // new wordspawn - - } else if (mapfile.got_classend("worldspawn")) { + mapfile.clear_bbox(); + } else if (mapfile.got_classend("worldspawn")) { mapfile.load_worldspawn(model); mapfile.clear_materials(); - + } else if (mapfile.classname().compare("worldspawn") == 0) { // worldspawn attributes @@ -827,14 +840,28 @@ Model * Map::load(std::string const &name) con_warn "Unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl; } + } 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.got_classname("func_group")) { + mapfile.clear_bbox(); } else if (mapfile.got_classend("func_group")) { + mapfile.load_fragmentgroup(model, FragmentGroup::None); + mapfile.clear_materials(); - // func_group fragments are loaded into worldspawn - mapfile.load_fragmentgroup(model, model->worldspawn()); + } else if (mapfile.got_classname("func_rotate")) { + mapfile.clear_bbox(); - } else if (mapfile.got_classend()) { + } else if (mapfile.got_classend("func_rotate")) { + mapfile.load_fragmentgroup(model, FragmentGroup::Rotate); + mapfile.clear_materials(); + } else if (mapfile.got_classend()) { mapfile.clear_materials(); } else if (mapfile.got_classname("light")) { diff --git a/src/model/map.h b/src/model/map.h index 5137e6c..9b75f7a 100644 --- a/src/model/map.h +++ b/src/model/map.h @@ -130,10 +130,13 @@ private: void load_worldspawn(Model *model); /// load parsed primitives into a FragmentGroup - void load_fragmentgroup(Model *model, FragmentGroup &group); + void load_fragmentgroup(Model *model, const FragmentGroup::Type type); /// clear the current list of per-material geometry void clear_materials(); + + /// clear class bounding box + void clear_bbox(); /// list of planes for the current brush std::vector<Plane *> planes; diff --git a/src/model/model.cc b/src/model/model.cc index 8fadb33..3ec75d7 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -32,13 +32,17 @@ Model::Model(std::string const & name) : Model::~Model() { - // delete worldspawn - model_worldspawn.clear(); + // delete all fragment groups + for (Groups::iterator git = model_groups.begin(); git != model_groups.end(); git++) { + delete (*git); + } + model_groups.clear(); // delete all docks for (Docks::iterator dit = model_docks.begin(); dit != model_docks.end(); dit++) { delete (*dit); } + model_docks.clear(); // delete all particle systems for (Model::ParticleSystems::iterator pit = model_particles.begin(); pit != model_particles.end(); pit++) { @@ -64,6 +68,11 @@ void Model::add_particles(Particles *particles) model_particles.push_back(particles); } +void Model::add_group(FragmentGroup *group) +{ + model_groups.push_back(group); +} + void Model::add_light(Light *light) { model_lights.push_back(light); @@ -116,7 +125,12 @@ void Model::clear() void Model::list_model(Model *model) { - con_print << " " << model->name() << " " << model->worldspawn().size() << " frags " << + size_t frags = 0; + for (Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) { + frags += (*git)->size(); + } + + con_print << " " << model->name() << " " << frags << " frags " << model->model_tris_count << "/" << model->model_tris_detail_count << " tris/detail " << model->model_quad_count << "/" << model->model_quad_detail_count << " quads/detail" << std::endl; } diff --git a/src/model/model.h b/src/model/model.h index 5b52fde..bdaa74a 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -44,6 +44,9 @@ public: /// type definition for a list of model particles typedef std::list<Particles *> ParticleSystems; + + /// type definition for a list of FragmentGroups + typedef std::list<FragmentGroup *> Groups; /// create a model with a name Model(std::string const & name); @@ -63,10 +66,10 @@ public: return model_radius; } - /// the worldspawn fragment group - inline FragmentGroup & worldspawn() + /// additional model fragment groups + inline Groups & groups() { - return model_worldspawn; + return model_groups; } /// list of lights @@ -131,6 +134,9 @@ public: /// add a docking location to the model void add_dock(Dock *dock); + + /// add a fragment group to the model + void add_group(FragmentGroup *group); float model_radius; @@ -179,12 +185,11 @@ private: std::string model_name; - FragmentGroup model_worldspawn; - Docks model_docks; Flares model_flares; Lights model_lights; ParticleSystems model_particles; + Groups model_groups; }; } |