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>2008-08-15 13:05:58 +0000
committerStijn Buys <ingar@osirion.org>2008-08-15 13:05:58 +0000
commit62de0496836e729ff955274cf153914709775bfb (patch)
tree54a868d8e4620b4dad49881af7a2614128697cbf /src/model
parent68fc01c7ce3f089e10a53e6dac92e2f63a9a8efd (diff)
func_group support
Diffstat (limited to 'src/model')
-rw-r--r--src/model/Makefile.am8
-rw-r--r--src/model/fragment.cc21
-rw-r--r--src/model/fragment.h34
-rw-r--r--src/model/light.h2
-rw-r--r--src/model/map.cc164
-rw-r--r--src/model/map.h21
-rw-r--r--src/model/model.cc19
-rw-r--r--src/model/model.h29
8 files changed, 218 insertions, 80 deletions
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 <list>
+
#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<Fragment *>::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<Fragment *> 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<Plane *>::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 <map>
#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<Flare *> Flares;
+ /// type definition for a lost of dockable locations
+ typedef std::list<Dock *> Docks;
+
/// type definition for a list of model engines
typedef std::list<Engine *> 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;
};