From fa852cfee26d3bdff0e18589ffb00851b0c25775 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 24 Oct 2010 22:22:34 +0000 Subject: corrects model bounding box issues --- src/model/asefile.cc | 20 +++--- src/model/mapfile.cc | 174 +++++++++++++++++++++++++++------------------------ src/model/mapfile.h | 9 ++- src/model/model.cc | 8 +-- src/model/model.h | 17 +++-- 5 files changed, 121 insertions(+), 107 deletions(-) (limited to 'src/model') diff --git a/src/model/asefile.cc b/src/model/asefile.cc index 0275603..afe74ea 100644 --- a/src/model/asefile.cc +++ b/src/model/asefile.cc @@ -680,17 +680,23 @@ Model *ASEFile::load(const std::string &name) Model *model = new Model(name); // set bounding box properties - math::Vector3f origin(0.0f, 0.0f, 0.0f); - model->set_origin(origin); - model->model_minbbox.assign (asefile.ase_minbbox * SCALE); - model->model_maxbbox.assign (asefile.ase_maxbbox * SCALE); - model->set_radius(math::max(model->model_minbbox.length(), model->model_maxbbox.length())); + asefile.ase_minbbox *= SCALE; + asefile.ase_maxbbox *= SCALE; - for (FragmentGroup::Fragments::const_iterator fit = asefile.fragmentgroup()->fragments().begin(); fit != asefile.fragmentgroup()->fragments().end(); fit++) { - + math::Vector3f ase_center((asefile.ase_maxbbox + asefile.ase_minbbox) * 0.5f); + asefile.fragmentgroup()->set_transform(true); + asefile.fragmentgroup()->set_location(ase_center * -1.0f); + + model->model_minbbox.assign(asefile.ase_minbbox - ase_center); + model->model_maxbbox.assign(asefile.ase_maxbbox - ase_center); + model->set_radius(asefile.ase_maxbbox.length()); + model->set_origin(ase_center); + + for (FragmentGroup::Fragments::const_iterator fit = asefile.fragmentgroup()->fragments().begin(); fit != asefile.fragmentgroup()->fragments().end(); fit++) { const Fragment *fragment = (*fit); model->model_tris_count += fragment->structural_size() + fragment->detail_size(); } + model->add_group(asefile.fragmentgroup()); con_debug << " " << asefile.name() << " " << asefile.vertexcount() << " vertices " << asefile.facecount() << " faces " << std::endl; diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index e3fda6c..32eee8a 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -34,7 +34,6 @@ math::Vector3f texture_baseaxis[18] = { math::Vector3f(-1, 0, 0), math::Vector3f(0, 1, 0), math::Vector3f(0, 0, -1), // east wall math::Vector3f(0, 1, 0), math::Vector3f(1, 0, 0), math::Vector3f(0, 0, -1), // south wall math::Vector3f(0, -1, 0), math::Vector3f(1, 0, 0), math::Vector3f(0, 0, -1) // north wall - }; // from radiant tools/quake3/q3map2/map.c @@ -142,7 +141,7 @@ inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag) return ((spawnflags & flag) == flag); } -MapFile::MapFile() : map_center(0.0f, 0.0f, 0.0f) +MapFile::MapFile() { mapfile_name.clear(); map_brushes = 0; @@ -151,6 +150,14 @@ MapFile::MapFile() : map_center(0.0f, 0.0f, 0.0f) in_patchdef = false; warning_q2brush = false; + + for (size_t i = 0; i < 3; i++) { + class_minbbox[i] = MAX_BOUNDS; + class_maxbbox[i] = -MAX_BOUNDS; + + map_minbbox[i] = MAX_BOUNDS; + map_maxbbox[i] = -MAX_BOUNDS; + } } MapFile::~MapFile() @@ -644,7 +651,7 @@ void MapFile::make_brushface(Face *face) Vector3f face_normal(face->normal()* -1); face_normal.normalize(); -#ifndef HAVE_BULLET +//#ifndef HAVE_BULLET // Quads are disable to use model data for bullet physics @@ -673,7 +680,7 @@ void MapFile::make_brushface(Face *face) vl.pop_back(); vl.pop_back(); } -#endif +//#endif // split polygon into triangles while (vl.size() > 2) { std::vector::iterator v0 = vl.begin(); @@ -813,21 +820,6 @@ void MapFile::clear_bbox() 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) * 0.5f; - - model->model_minbbox = class_minbbox - map_center; - model->model_maxbbox = class_maxbbox - map_center; - model->set_radius(model->model_maxbbox.length()); - model->set_origin(map_center); - load_fragmentgroup(model, FragmentGroup::None); -} - void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type) { if (!VertexArray::instance() || VertexArray::instance()->overflow()) @@ -845,20 +837,24 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t } } - if (class_type != FragmentGroup::None) { - group->set_transform(true); + // calculate map bbox + for (size_t i = 0; i < 3 ; i++) { + if (class_minbbox[i] < map_minbbox[i]) + map_minbbox[i] = class_minbbox[i]; + + if (class_maxbbox[i] > map_maxbbox[i]) + map_maxbbox[i] = class_maxbbox[i]; } - + + // special groups like func_door and func_group are re-centered + math::Vector3f translation((class_minbbox + class_maxbbox) * 0.5f); + + group->set_transform(true); + group->set_location(translation); 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; @@ -872,9 +868,9 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Triangle *triangle = (*tris_it); if (!triangle->detail()) { size_t count = 0; - count += fragment->add_vertex(triangle->v0() - group_center, triangle->normal(), triangle->t0(), false); - count += fragment->add_vertex(triangle->v1() - group_center, triangle->normal(), triangle->t1(), false); - count += fragment->add_vertex(triangle->v2() - group_center, triangle->normal(), triangle->t2(), false); + count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), false); + count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), false); + count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), false); if (count == 3) model->model_tris_count++; } @@ -885,9 +881,9 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Triangle *triangle = (*tris_it); if (triangle->detail()) { size_t count = 0; - count += fragment->add_vertex(triangle->v0() - group_center, triangle->normal(), triangle->t0(), true); - count += fragment->add_vertex(triangle->v1() - group_center, triangle->normal(), triangle->t1(), true); - count += fragment->add_vertex(triangle->v2() - group_center, triangle->normal(), triangle->t2(), true); + count += fragment->add_vertex(triangle->v0() - translation, triangle->normal(), triangle->t0(), true); + count += fragment->add_vertex(triangle->v1() - translation, triangle->normal(), triangle->t1(), true); + count += fragment->add_vertex(triangle->v2() - translation, triangle->normal(), triangle->t2(), true); if (count == 3) { model->model_tris_count++; model->model_tris_detail_count++; @@ -908,10 +904,10 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Quad *quad = (*quad_it); if (!quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0() - group_center, quad->normal(), quad->t0(), false); - count += fragment->add_vertex(quad->v1() - group_center, quad->normal(), quad->t1(), false); - count += fragment->add_vertex(quad->v2() - group_center, quad->normal(), quad->t2(), false); - count += fragment->add_vertex(quad->v3() - group_center, quad->normal(), quad->t3(), false); + count += fragment->add_vertex(quad->v0() - translation, quad->normal(), quad->t0(), false); + count += fragment->add_vertex(quad->v1() - translation, quad->normal(), quad->t1(), false); + count += fragment->add_vertex(quad->v2() - translation, quad->normal(), quad->t2(), false); + count += fragment->add_vertex(quad->v3() - translation, quad->normal(), quad->t3(), false); if (count == 4) model->model_quad_count++; } @@ -922,10 +918,10 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t Quad *quad = (*quad_it); if (quad->detail()) { size_t count = 0; - count += fragment->add_vertex(quad->v0() - group_center, quad->normal(), quad->t0(), false); - count += fragment->add_vertex(quad->v1() - group_center, quad->normal(), quad->t1(), false); - count += fragment->add_vertex(quad->v2() - group_center, quad->normal(), quad->t2(), false); - count += fragment->add_vertex(quad->v3() - group_center, quad->normal(), quad->t3(), false); + count += fragment->add_vertex(quad->v0() - translation, quad->normal(), quad->t0(), false); + count += fragment->add_vertex(quad->v1() - translation, quad->normal(), quad->t1(), false); + count += fragment->add_vertex(quad->v2() - translation, quad->normal(), quad->t2(), false); + count += fragment->add_vertex(quad->v3() - translation, quad->normal(), quad->t3(), false); if (count == 4) { model->model_quad_count++; model->model_quad_detail_count++; @@ -995,7 +991,7 @@ Model * MapFile::load(std::string const &name) mapfile.clear_bbox(); } else if (mapfile.got_classend("worldspawn")) { - mapfile.load_worldspawn(model); + mapfile.load_fragmentgroup(model, FragmentGroup::None); mapfile.clear_materials(); } else if (mapfile.in_class("worldspawn")) { @@ -1406,27 +1402,6 @@ Model * MapFile::load(std::string const &name) mapfile.close(); - // translate model tags - for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { - (*lit)->get_location() -= mapfile.map_center; - } - - for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { - (*flit)->get_location() -= mapfile.map_center; - } - - for (Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) { - (*pit)->get_location() -= mapfile.map_center; - } - - for(Model::Sounds::iterator sit = model->sounds().begin(); sit != model->sounds().end(); sit++) { - (*sit)->get_location() -= mapfile.map_center; - } - - for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { - (*dit)->get_location() -= mapfile.map_center; - } - for (SubModelList::iterator smit = submodel_list.begin(); smit != submodel_list.end(); smit++) { tag_submodel = (*smit); Model *submodel_model = 0; @@ -1436,8 +1411,8 @@ Model * MapFile::load(std::string const &name) } if (submodel_model) { - tag_submodel->get_location() -= mapfile.map_center; - + tag_submodel->get_location() += submodel_model->origin() * tag_submodel->scale(); + // copy fragmentgroups for (Model::Groups::iterator git = submodel_model->groups().begin(); git != submodel_model->groups().end(); git++) { FragmentGroup *groupsrc = (*git); @@ -1447,7 +1422,7 @@ Model * MapFile::load(std::string const &name) groupdst->set_type(groupsrc->type()); groupdst->set_scale(groupsrc->scale() * tag_submodel->scale()); groupdst->set_speed(groupsrc->speed()); - groupdst->set_location(tag_submodel->location() + (submodel_model->origin() + groupsrc->location()) * tag_submodel->scale()); + groupdst->set_location(tag_submodel->location() + groupsrc->location() * tag_submodel->scale()); groupdst->set_axis(groupsrc->axis() * tag_submodel->axis()); // copy fragments, this only copies the original fragment's pointer into the vertex array @@ -1466,23 +1441,22 @@ Model * MapFile::load(std::string const &name) // recalculate bbox for (size_t i = 0; i < 3; i ++) { float c; - c = tag_submodel->location()[i] + (submodel_model->origin()[i] + submodel_model->model_maxbbox[i]) * tag_submodel->scale(); - if (c > model->model_maxbbox[i]) { - model->model_maxbbox[i] = c; + c = tag_submodel->location()[i] + submodel_model->model_maxbbox[i] * tag_submodel->scale(); + if (c > mapfile.map_maxbbox[i]) { + mapfile.map_maxbbox[i] = c; } - c = tag_submodel->location()[i] + (submodel_model->origin()[i] + submodel_model->model_minbbox[i]) * tag_submodel->scale(); - if (c < model->model_minbbox[i]) { - model->model_minbbox[i] = c; + c = tag_submodel->location()[i] + submodel_model->model_minbbox[i] * tag_submodel->scale(); + if (c < mapfile.map_minbbox[i]) { + mapfile.map_minbbox[i] = c; } } - model->set_radius(sqrtf(math::max(model->model_maxbbox.lengthsquared(), model->model_minbbox.lengthsquared()))); // copy light tags for (Model::Lights::const_iterator lit = submodel_model->lights().begin(); lit != submodel_model->lights().end(); lit++) { tag_light = new Light(*(*lit)); - tag_light->get_location().assign(tag_submodel->location() + (submodel_model->origin() + tag_light->location()) * tag_submodel->scale()); + tag_light->get_location().assign(tag_submodel->location() + tag_light->location() * tag_submodel->scale()); tag_light->set_radius(tag_light->radius() * tag_submodel->scale()); model->add_light(tag_light); } @@ -1490,7 +1464,7 @@ Model * MapFile::load(std::string const &name) // copy flare tags for (Model::Flares::const_iterator flit = submodel_model->flares().begin(); flit != submodel_model->flares().end(); flit++) { tag_flare = new Flare(*(*flit)); - tag_flare->get_location().assign(tag_submodel->location() + (submodel_model->origin() + tag_flare->location()) * tag_submodel->scale()); + tag_flare->get_location().assign(tag_submodel->location() + tag_flare->location() * tag_submodel->scale()); tag_flare->set_radius(tag_flare->radius() * tag_submodel->scale()); model->add_flare(tag_flare); } @@ -1498,7 +1472,7 @@ Model * MapFile::load(std::string const &name) // copy particle system tags for (Model::ParticleSystems::const_iterator pit = submodel_model->particles().begin(); pit != submodel_model->particles().end(); pit++) { tag_particles = new Particles(*(*pit)); - tag_particles->get_location().assign(tag_submodel->location() + (submodel_model->origin() + tag_particles->location()) * tag_submodel->scale()); + tag_particles->get_location().assign(tag_submodel->location() + tag_particles->location() * tag_submodel->scale()); tag_particles->set_radius(tag_particles->radius() * tag_submodel->scale()); model->add_particles(tag_particles); } @@ -1506,16 +1480,52 @@ Model * MapFile::load(std::string const &name) // copy sound tags for (Model::Sounds::const_iterator sit = submodel_model->sounds().begin(); sit != submodel_model->sounds().end(); sit++) { tag_sound = new Sound(*(*sit)); - tag_sound->get_location().assign(tag_submodel->location() + (submodel_model->origin() + tag_sound->location()) * tag_submodel->scale()); + tag_sound->get_location().assign(tag_submodel->location() + tag_sound->location() * tag_submodel->scale()); + } + + // copy dock tags + for (Model::Docks::const_iterator dit = submodel_model->docks().begin(); dit != submodel_model->docks().end(); dit++) { + tag_dock = new Dock(*(*dit)); + tag_dock->get_location().assign(tag_submodel->location() + tag_dock->location() * tag_submodel->scale()); } - - // TODO copy engines and docks - //con_debug << " imported submodel '" << submodel->name() << "'" << std::endl; } - delete tag_submodel; + } + + // center model around (0,0,0) + math::Vector3f map_center = (mapfile.map_minbbox + mapfile.map_maxbbox) * 0.5f; + model->model_minbbox.assign(mapfile.map_minbbox - map_center); + model->model_maxbbox.assign(mapfile.map_maxbbox - map_center); + model->set_radius(model->model_maxbbox.length()); + model->set_origin(map_center); + // translate transformed vertex groups + for (Model::Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) { + FragmentGroup *fragmentgroup = (*git); + fragmentgroup->set_transform(true); + fragmentgroup->set_location(fragmentgroup->location() - map_center); + } + + // translate tags + for (Model::Lights::iterator lit = model->lights().begin(); lit != model->lights().end(); lit++) { + (*lit)->get_location() -= map_center; + } + + for (Model::Flares::iterator flit = model->flares().begin(); flit != model->flares().end(); flit++) { + (*flit)->get_location() -= map_center; + } + + for (Model::ParticleSystems::iterator pit = model->particles().begin(); pit != model->particles().end(); pit++) { + (*pit)->get_location() -= map_center; + } + + for(Model::Sounds::iterator sit = model->sounds().begin(); sit != model->sounds().end(); sit++) { + (*sit)->get_location() -= map_center; + } + + for (Model::Docks::iterator dit = model->docks().begin(); dit != model->docks().end(); dit++) { + (*dit)->get_location() -= map_center; } if (mapfile.warning_q2brush) diff --git a/src/model/mapfile.h b/src/model/mapfile.h index be1e789..75db76e 100644 --- a/src/model/mapfile.h +++ b/src/model/mapfile.h @@ -128,9 +128,6 @@ private: /// generate triangles for one plane in the plane list void make_brushface(Face *face); - /// load parsed primitives into model worldspawn - void load_worldspawn(Model *model); - /// load parsed primitives into a FragmentGroup void load_fragmentgroup(Model *model, const FragmentGroup::Type class_type); @@ -167,12 +164,14 @@ private: filesystem::IFileStream mapfile_ifs; std::string mapfile_name; - math::Vector3f class_maxbbox; + math::Vector3f map_minbbox; + math::Vector3f map_maxbbox; + math::Vector3f class_minbbox; + math::Vector3f class_maxbbox; math::Axis class_axis; float class_speed; - math::Vector3f map_center; Materials map_materials; bool warning_q2brush; diff --git a/src/model/model.cc b/src/model/model.cc index 7552b07..fb33bd0 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -70,14 +70,14 @@ Model::~Model() model_sounds.clear(); } -void Model::set_radius(const float radius) +void Model::set_origin(const math::Vector3f &origin) { - model_radius = radius; + model_origin.assign(origin); } -void Model::set_origin(const math::Vector3f &origin) +void Model::set_radius(const float radius) { - model_origin.assign(origin); + model_radius = radius; } void Model::add_particles(Particles *particles) diff --git a/src/model/model.h b/src/model/model.h index dd9cdf2..287b0cf 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -125,12 +125,12 @@ public: inline const math::Color & enginecolor() const { return model_enginecolor; } - - /// original origin + + /// original model origin inline const math::Vector3f & origin() const { return model_origin; } - + /// add a light tag to the model void add_light(Light *light); @@ -149,10 +149,13 @@ public: /// add a fragment group to the model void add_group(FragmentGroup *group); + /// set model radius void set_radius(const float radius); - + + /// set model origin void set_origin(const math::Vector3f &origin); - + + math::Vector3f model_origin; math::Vector3f model_maxbbox; math::Vector3f model_minbbox; @@ -195,17 +198,13 @@ public: private: std::string model_name; - Docks model_docks; Flares model_flares; Sounds model_sounds; Lights model_lights; ParticleSystems model_particles; Groups model_groups; - - math::Vector3f model_origin; float model_radius; - static Registry model_registry; }; -- cgit v1.2.3