From 62de0496836e729ff955274cf153914709775bfb Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 15 Aug 2008 13:05:58 +0000 Subject: func_group support --- src/model/Makefile.am | 8 +-- src/model/fragment.cc | 21 +++++++ src/model/fragment.h | 34 ++++++++++- src/model/light.h | 2 +- src/model/map.cc | 164 ++++++++++++++++++++++++++++++++------------------ src/model/map.h | 21 ++++++- src/model/model.cc | 19 ++++-- src/model/model.h | 29 ++++++--- src/render/draw.cc | 4 +- 9 files changed, 220 insertions(+), 82 deletions(-) (limited to 'src') diff --git a/src/model/Makefile.am b/src/model/Makefile.am index a6e8a99..f029390 100644 --- a/src/model/Makefile.am +++ b/src/model/Makefile.am @@ -1,11 +1,11 @@ METASOURCES = AUTO -libmodel_la_SOURCES = engine.cc flare.cc fragment.cc light.cc map.cc model.cc \ - plane.cc primitives.cc quad.cc triangle.cc vertexarray.cc +libmodel_la_SOURCES = dock.cc engine.cc flare.cc fragment.cc light.cc map.cc \ + model.cc plane.cc primitives.cc quad.cc triangle.cc vertexarray.cc libmodel_la_LDFLAGS = -avoid-version -no-undefined -lm noinst_LTLIBRARIES = libmodel.la -noinst_HEADERS = engine.h flare.h fragment.h light.h map.h material.h model.h \ - plane.h primitives.h quad.h triangle.h vertexarray.h +noinst_HEADERS = dock.h engine.h flare.h fragment.h light.h map.h material.h \ + model.h plane.h primitives.h quad.h triangle.h vertexarray.h INCLUDES = -I$(top_srcdir)/src diff --git a/src/model/fragment.cc b/src/model/fragment.cc index b655807..db34fdb 100644 --- a/src/model/fragment.cc +++ b/src/model/fragment.cc @@ -10,10 +10,12 @@ namespace model { +/* ---- class Fragment --------------------------------------------- */ /* Triangles: the number of triangles is size/3 Quads: the number of Quads is size/4 */ + Fragment::Fragment(Type type, unsigned int material) { fragment_type = type; @@ -35,5 +37,24 @@ size_t Fragment::add_vertex(math::Vector3f const & vertex, math::Vector3f const return n; } +/* ---- class FragmentGroup ---------------------------------------- */ + +FragmentGroup::FragmentGroup() +{ +} + +FragmentGroup::~FragmentGroup() +{ + clear(); +} + +void FragmentGroup::clear() { + + for (iterator it = group_fragments.begin(); it != group_fragments.end(); it++) { + delete(*it); + } + group_fragments.clear(); +} + } diff --git a/src/model/fragment.h b/src/model/fragment.h index 0df1b79..409bb97 100644 --- a/src/model/fragment.h +++ b/src/model/fragment.h @@ -7,13 +7,15 @@ #ifndef __INCLUDED_MODEL_FRAGMENT_H__ #define __INCLUDED_MODEL_FRAGMENT_H__ +#include + #include "math/vector3f.h" #include "math/color.h" namespace model { -/// a fragment of a model, a pointer into a continuues part of the VertexArray containt Tris or Quad data +/// a fragment of a model, a pointer into a continuous part of the VertexArray containing tris or quads class Fragment { public: @@ -64,6 +66,36 @@ private: unsigned int fragment_material; }; +/// a collection of fragments +/** + * a FragmentGroup contains the model fragments for one class in the .map file. + * worldspawn is a FragmentGroup + */ +class FragmentGroup +{ +public: + typedef std::list::iterator iterator; + + FragmentGroup(); + ~FragmentGroup(); + + void clear(); + + inline iterator begin() { return group_fragments.begin(); } + + inline iterator end() { return group_fragments.end(); } + + inline size_t size() const { return group_fragments.size(); } + + inline void push_back(Fragment *fragment) { group_fragments.push_back(fragment); } + +private: + /// type definition for a list of model fragments + typedef std::list Fragments; + + Fragments group_fragments; +}; + } #endif // __INCLUDED_MODEL_FRAGMENT_H__ diff --git a/src/model/light.h b/src/model/light.h index 00587f3..f91cabe 100644 --- a/src/model/light.h +++ b/src/model/light.h @@ -45,7 +45,7 @@ public: return light_entity; } - /// size if the light, default is 1.0f + /// size of the light, default is 1.0f inline float radius() const { return light_radius; diff --git a/src/model/map.cc b/src/model/map.cc index e902cfd..d138b49 100644 --- a/src/model/map.cc +++ b/src/model/map.cc @@ -6,6 +6,7 @@ #include "filesystem/filesystem.h" #include "math/mathlib.h" +#include "model/dock.h" #include "model/engine.h" #include "model/light.h" #include "model/map.h" @@ -34,9 +35,12 @@ const float SCALE = 1.0f / 1024.0f; const float MIN_DELTA = 10e-10; -Map::Map() +Map::Map() : map_center(0,0,0) { mapfile_name.clear(); + map_brushes = 0; + map_faces = 0; + map_faces_detail = 0; } Map::~Map() @@ -51,10 +55,6 @@ void Map::clear_materials() delete(*mit).second; } map_materials.clear(); - - map_brushes = 0; - map_faces = 0; - map_faces_detail = 0; } bool Map::open(std::string const & name) @@ -104,6 +104,11 @@ bool Map::got_classname(const char * classnamelabel) const return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0)); } +bool Map::got_classend(const char * classnamelabel) const +{ + return (last_read_was_classend && (classname_current.compare(classnamelabel) == 0)); +} + bool Map::getline() { using math::Vector3f; @@ -112,6 +117,7 @@ bool Map::getline() last_read_was_classname = false; last_read_was_key = false; + last_read_was_classend = false; key_current = ""; value_current = ""; @@ -135,8 +141,8 @@ bool Map::getline() parse_level++; } else if (firstword == "}") { - if ((parse_level == 2) && (classname_current == "worldspawn")) { - // brush + if ((parse_level == 2) && (planes.size())) { + // end-of-brush if (VertexArray::instance()) { // for every face for (std::vector::iterator face = planes.begin(); face != planes.end(); face++) { @@ -152,7 +158,12 @@ bool Map::getline() 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) { @@ -187,7 +198,7 @@ bool Map::getline() } else if (parse_level == 2) { - if ((firstword == "(") && (classname_current == "worldspawn")) { + if (firstword == "(") { // brush plane if (VertexArray::instance()) { Vector3f p1, p2, p3; @@ -666,35 +677,34 @@ void Map::close() mapfile_ifs.close(); } -void Map::load_fragments(Model *model) +void Map::load_worldspawn(Model *model) { + // set default values if (!VertexArray::instance() || VertexArray::instance()->overflow()) return; if (!map_materials.size()) return; - + // FIXME center in maps without brushes - math::Vector3f center = (class_minbbox + class_maxbbox) / 2; + map_center = (class_minbbox + class_maxbbox) / 2; - model->model_minbbox = class_minbbox - center; - model->model_maxbbox = class_maxbbox - center; + model->model_minbbox = class_minbbox - map_center; + model->model_maxbbox = class_maxbbox - map_center; model->model_radius = model->model_maxbbox.length(); - - // reposition lights, flares and engines - for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { - (*lit)->light_location -= center; - } - - for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { - (*flit)->light_location -= center; - } - - for (Model::Engines::iterator eit = model->engines().begin(); eit != model->engines().end(); eit++) { - (*eit)->engine_location -= center; - } - + + load_fragmentgroup(model, model->worldspawn()); +} + +void Map::load_fragmentgroup(Model *model, FragmentGroup &group) +{ + if (!VertexArray::instance() || VertexArray::instance()->overflow()) + return; + + if (!map_materials.size()) + return; + for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) { // split the Primitives with this material into fragments Primitives *primitives = (*mit).second; @@ -708,9 +718,9 @@ void Map::load_fragments(Model *model) Triangle *triangle = (*tris_it); if (!triangle->detail()) { size_t count = 0; - count += fragment->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color(), false); - count += fragment->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color(), false); - count += fragment->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color(), false); + count += fragment->add_vertex(triangle->v0()-map_center, triangle->normal(), triangle->color(), false); + count += fragment->add_vertex(triangle->v1()-map_center, triangle->normal(), triangle->color(), false); + count += fragment->add_vertex(triangle->v2()-map_center, triangle->normal(), triangle->color(), false); if (count == 3) model->model_tris_count++; } @@ -721,9 +731,9 @@ void Map::load_fragments(Model *model) Triangle *triangle = (*tris_it); if (triangle->detail()) { size_t count = 0; - count += fragment->add_vertex(triangle->v0()-center, triangle->normal(), triangle->color(), true); - count += fragment->add_vertex(triangle->v1()-center, triangle->normal(), triangle->color(), true); - count += fragment->add_vertex(triangle->v2()-center, triangle->normal(), triangle->color(), true); + count += fragment->add_vertex(triangle->v0()-map_center, triangle->normal(), triangle->color(), true); + count += fragment->add_vertex(triangle->v1()-map_center, triangle->normal(), triangle->color(), true); + count += fragment->add_vertex(triangle->v2()-map_center, triangle->normal(), triangle->color(), true); if (count == 3) { model->model_tris_count++; model->model_tris_detail_count++; @@ -731,8 +741,8 @@ void Map::load_fragments(Model *model) } } - // add the fragment to the model - model->fragments().push_back(fragment); + // add the fragment to the fragment group + group.push_back(fragment); } // store quads @@ -744,10 +754,10 @@ void Map::load_fragments(Model *model) Quad *quad = (*quad_it); if (!quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v1()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v2()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v3()-center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v0()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v1()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v2()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v3()-map_center, quad->normal(), quad->color(), false); if (count == 4) model->model_quad_count++; } @@ -758,10 +768,10 @@ void Map::load_fragments(Model *model) Quad *quad = (*quad_it); if (quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v1()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v2()-center, quad->normal(), quad->color(), false); - count += fragment->add_vertex(quad->v3()-center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v0()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v1()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v2()-map_center, quad->normal(), quad->color(), false); + count += fragment->add_vertex(quad->v3()-map_center, quad->normal(), quad->color(), false); if (count == 4) { model->model_quad_count++; model->model_quad_detail_count++; @@ -770,7 +780,7 @@ void Map::load_fragments(Model *model) } // add the fragment to the model - model->fragments().push_back(fragment); + group.push_back(fragment); } } @@ -787,17 +797,23 @@ Model * Map::load(std::string const &name) } Model *model = new Model(name); - Light *light = 0; - Flare *flare = 0; - Engine *engine = 0; + Dock *dock = 0; + Engine *engine = 0; + Flare *flare = 0; + Light *light = 0; + unsigned int u; while (mapfile.getline()) { if (mapfile.got_classname("worldspawn")) { - // new wordspawn + + } else if (mapfile.got_classend("worldspawn")) { + + mapfile.load_worldspawn(model); + mapfile.clear_materials(); } else if (mapfile.classname().compare("worldspawn") == 0) { @@ -808,7 +824,16 @@ Model * Map::load(std::string const &name) } else if (mapfile.got_key_color("enginecolor", model->model_enginecolor) ==0) { continue; } - + + } else if (mapfile.got_classend("func_group")) { + + // func_group fragments are loaded into worldspawn + mapfile.load_fragmentgroup(model, model->worldspawn()); + + } else if (mapfile.got_classend()) { + + mapfile.clear_materials(); + } else if (mapfile.got_classname("light")) { // new light @@ -846,6 +871,24 @@ Model * Map::load(std::string const &name) } + } else if (mapfile.got_classname("trigger_dock")) { + + // new docking location + dock = new Dock(); + model->add_dock(dock); + + } else if (mapfile.classname().compare("target_dock") == 0) { + + // dock attributes + if (mapfile.got_key_vector3f("origin", dock->dock_location)) { + flare->light_location *= SCALE; + continue; + + } else if (mapfile.got_key_float("radius", dock->dock_radius)) { + continue; + + } + } else if (mapfile.got_classname("target_flare")) { // new flare @@ -915,18 +958,23 @@ Model * Map::load(std::string const &name) } mapfile.close(); + + // reposition lights, flares and engines 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::Engines::iterator eit = model->engines().begin(); eit != model->engines().end(); eit++) { + (*eit)->engine_location -= mapfile.map_center; + } + con_debug << " " << mapfile.name() << " " << mapfile.map_brushes << " brushes " << mapfile.map_faces << "/" << mapfile.map_faces_detail << " faces/detail " << std::endl; - - mapfile.load_fragments(model); - -/* con_debug << " " << mapfile.name() << " " << model->fragments().size() << " 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; -*/ - mapfile.clear_materials(); - + return model; } diff --git a/src/model/map.h b/src/model/map.h index afe925b..5137e6c 100644 --- a/src/model/map.h +++ b/src/model/map.h @@ -63,7 +63,16 @@ private: /// true if the last read line contained a new classname bool got_classname() const; + + /// true if the last read line contained a class closing bracket + inline bool got_classend() const + { + return last_read_was_classend; + } + /// true if the last read line contained the closing bracket for the requested class + bool got_classend(const char*) const; + /// true if the last read line contained a new classname bool got_classname(const char*) const; @@ -117,9 +126,12 @@ private: /// generate triangles for one plane in the plane list void make_brushface(Plane *face); - /// load parsed primitives into Model Fragments - void load_fragments(Model *model); - + /// load parsed primitives into model worldspawn + void load_worldspawn(Model *model); + + /// load parsed primitives into a FragmentGroup + void load_fragmentgroup(Model *model, FragmentGroup &group); + /// clear the current list of per-material geometry void clear_materials(); @@ -132,6 +144,7 @@ private: bool last_read_was_key; bool last_read_was_classname; + bool last_read_was_classend; unsigned int map_brushes; unsigned int map_faces; @@ -144,6 +157,8 @@ private: math::Vector3f class_maxbbox; math::Vector3f class_minbbox; + + math::Vector3f map_center; Materials map_materials; }; diff --git a/src/model/model.cc b/src/model/model.cc index 3fa0cc0..813515b 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -31,12 +31,14 @@ Model::Model(std::string const & name) : Model::~Model() { - // delete all fragments - for (Fragments::iterator fragit = model_fragments.begin(); fragit != model_fragments.end(); fragit++) { - delete(*fragit); - } - model_fragments.clear(); + // delete worldspawn + model_worldspawn.clear(); + // delete all docks + for (Docks::iterator dit = model_docks.begin(); dit != model_docks.end(); dit++) { + delete (*dit); + } + // delete all engines for (Engines::iterator eit = model_engines.begin(); eit != model_engines.end(); eit++) { delete(*eit); @@ -71,6 +73,11 @@ void Model::add_flare(Flare *flare) model_flares.push_back(flare); } +void Model::add_dock(Dock *dock) +{ + model_docks.push_back(dock); +} + Model *Model::find(std::string const & name) { Registry::iterator it = model_registry.find(name); @@ -108,7 +115,7 @@ void Model::clear() void Model::list_model(Model *model) { - con_print << " " << model->name() << " " << model->fragments().size() << " frags " << + con_print << " " << model->name() << " " << model->worldspawn().size() << " 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 47728cb..35e8971 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -12,6 +12,7 @@ #include #include "math/mathlib.h" +#include "model/dock.h" #include "model/engine.h" #include "model/fragment.h" #include "model/light.h" @@ -37,6 +38,9 @@ public: /// type definition for a list of model flares typedef std::list Flares; + /// type definition for a lost of dockable locations + typedef std::list Docks; + /// type definition for a list of model engines typedef std::list Engines; @@ -58,17 +62,23 @@ public: return model_radius; } - /// list of fragments - inline Fragments & fragments() + /// the worldspawn fragment group + inline FragmentGroup & worldspawn() { - return model_fragments; + return model_worldspawn; } - + /// list of lights inline Lights & lights() { return model_lights; } + + /// list of dockable locations + inline Docks & docks() + { + return model_docks; + } /// list of flares inline Flares & flares() @@ -111,6 +121,9 @@ public: /// add a flare to the model void add_flare(Flare *flare); + + /// add a docking location to the model + void add_dock(Dock *dock); float model_radius; @@ -157,10 +170,12 @@ private: static Registry model_registry; std::string model_name; - - Fragments model_fragments; - Flares model_flares; + + FragmentGroup model_worldspawn; + + Docks model_docks; Engines model_engines; + Flares model_flares; Lights model_lights; }; diff --git a/src/render/draw.cc b/src/render/draw.cc index 2104981..18234f5 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -129,7 +129,7 @@ void pass_prepare(float seconds) if (entity->model()) { float r = entity->model()->radius(); - math::clamp(r, 1.0f, 5.0f); + math::clamp(r, 1.0f, farplane / drawfxdistance); if (entity->state()->distance() < drawfxdistance * r) { // entites within detail range entity->state()->state_visible = true; @@ -585,7 +585,7 @@ void draw_model_fragments(core::Entity *entity) } } - for (Model::Fragments::iterator fit = model->fragments().begin(); fit != model->fragments().end(); fit++) { + for (model::FragmentGroup::iterator fit = model->worldspawn().begin(); fit != model->worldspawn().end(); fit++) { Fragment *fragment = (*fit); -- cgit v1.2.3