Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/model/fragment.cc1
-rw-r--r--src/model/fragment.h16
-rw-r--r--src/model/map.cc65
-rw-r--r--src/model/map.h5
-rw-r--r--src/model/model.cc20
-rw-r--r--src/model/model.h15
-rw-r--r--src/render/draw.cc133
7 files changed, 168 insertions, 87 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;
};
}
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 35b9956..2566dd0 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -575,72 +575,89 @@ void draw_model_fragments(core::Entity *entity)
}
}
- for (model::FragmentGroup::iterator fit = model->worldspawn().begin(); fit != model->worldspawn().end(); fit++) {
+ for (model::Model::Groups::iterator git = model->groups().begin(); git != model->groups().end(); git++) {
- Fragment *fragment = (*fit);
+ model::FragmentGroup *group = (*git);
- if (fragment->material() != material) {
- material = fragment->material();
-
- if (material & Material::Engine) {
-
- if (use_color_array) {
- glDisableClientState(GL_COLOR_ARRAY);
- use_color_array = false;
- }
-
- gl::color(model->enginecolor() * thrust);
-
- } else if (material & Material::Tertiary) {
- if (use_color_array) {
- use_color_array = false;
- glDisableClientState(GL_COLOR_ARRAY);
- }
-
- math::Color color;
-
- if ((material & Material::Tertiary) == Material::Tertiary) {
- for (size_t i = 0; i < 3; i++)
- color[i] = (entity->color()[i] + entity->color_second()[i]) / 2;
-
- } else if ((material & Material::Secondary) == Material::Secondary) {
- color.assign(entity->color_second());
-
- } if ((material & Material::Primary) == Material::Primary) {
- color.assign(entity->color());
- }
-
- if (material & Material::Dark)
- color *= 0.5f;
-
- gl::color(color);
-
- } else {
- if (!use_color_array) {
- glEnableClientState(GL_COLOR_ARRAY);
- use_color_array = true;
- }
- }
+ if (group->type() == model::FragmentGroup::Rotate) {
+ gl::push();
+ gl::translate(group->location() * -1.0f);
+ float angle = math::degrees360f(core::application()->time() * 90.0f);
+ gl::rotate(angle, math::Vector3f::Xaxis());
+ gl::translate(group->location());
+ }
- if (power && (material & Material::Light)) {
- if (use_light) {
- gl::disable(GL_LIGHTING);
- use_light = false;
- }
- } else if (power && (material & Material::Engine)) {
- if (use_light) {
- gl::disable(GL_LIGHTING);
- use_light = false;
+ for (model::FragmentGroup::iterator fit = group->begin(); fit != group->end(); fit++) {
+
+ Fragment *fragment = (*fit);
+
+ if (fragment->material() != material) {
+ material = fragment->material();
+
+ if (material & Material::Engine) {
+
+ if (use_color_array) {
+ glDisableClientState(GL_COLOR_ARRAY);
+ use_color_array = false;
+ }
+
+ gl::color(model->enginecolor() * thrust);
+
+ } else if (material & Material::Tertiary) {
+ if (use_color_array) {
+ use_color_array = false;
+ glDisableClientState(GL_COLOR_ARRAY);
+ }
+
+ math::Color color;
+
+ if ((material & Material::Tertiary) == Material::Tertiary) {
+ for (size_t i = 0; i < 3; i++)
+ color[i] = (entity->color()[i] + entity->color_second()[i]) / 2;
+
+ } else if ((material & Material::Secondary) == Material::Secondary) {
+ color.assign(entity->color_second());
+
+ } if ((material & Material::Primary) == Material::Primary) {
+ color.assign(entity->color());
+ }
+
+ if (material & Material::Dark)
+ color *= 0.5f;
+
+ gl::color(color);
+
+ } else {
+ if (!use_color_array) {
+ glEnableClientState(GL_COLOR_ARRAY);
+ use_color_array = true;
+ }
}
- } else {
- if (!use_light) {
- gl::enable(GL_LIGHTING);
- use_light = true;
+
+ if (power && (material & Material::Light)) {
+ if (use_light) {
+ gl::disable(GL_LIGHTING);
+ use_light = false;
+ }
+ } else if (power && (material & Material::Engine)) {
+ if (use_light) {
+ gl::disable(GL_LIGHTING);
+ use_light = false;
+ }
+ } else {
+ if (!use_light) {
+ gl::enable(GL_LIGHTING);
+ use_light = true;
+ }
}
}
+
+ draw_fragment(fragment, ext_render(entity)->detailvisible());
}
- draw_fragment(fragment, ext_render(entity)->detailvisible());
+ if (group->type() == model::FragmentGroup::Rotate) {
+ gl::pop();
+ }
}
if (!use_light) {