Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2010-10-24 22:22:34 +0000
committerStijn Buys <ingar@osirion.org>2010-10-24 22:22:34 +0000
commitfa852cfee26d3bdff0e18589ffb00851b0c25775 (patch)
tree45c2308424e77508fc79708932b5f163ec2992d9 /src/model
parenta704318f507f486ac04834747eb209d0a9410702 (diff)
corrects model bounding box issues
Diffstat (limited to 'src/model')
-rw-r--r--src/model/asefile.cc20
-rw-r--r--src/model/mapfile.cc174
-rw-r--r--src/model/mapfile.h9
-rw-r--r--src/model/model.cc8
-rw-r--r--src/model/model.h17
5 files changed, 121 insertions, 107 deletions
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<Vector3f *>::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;
};