Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
Diffstat (limited to 'src/model')
-rw-r--r--src/model/asefile.cc13
-rw-r--r--src/model/classes.cc21
-rw-r--r--src/model/classes.h54
-rw-r--r--src/model/fragment.cc11
-rw-r--r--src/model/fragment.h18
-rw-r--r--src/model/map.cc161
-rw-r--r--src/model/map.h14
-rw-r--r--src/model/material.cc1
-rw-r--r--src/model/model.cc4
9 files changed, 216 insertions, 81 deletions
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index 22fcd78..28c84cf 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -18,7 +18,6 @@ const float MAX_BOUNDS = 16384.0f;
ASEFile::ASEFile(std::string const &name)
{
- asefile_name.assign("models/");
asefile_name.append(name);
asefile_name.append(".ase");
@@ -90,7 +89,7 @@ bool ASEFile::read_mesh_vertex_list(std::istream &is)
line >> firstword;
if (firstword.compare("}") == 0) {
- con_debug << count << " mesh vertices" << std::endl;
+ con_debug << " " << count << " mesh vertices" << std::endl;
return true;
@@ -428,9 +427,9 @@ Model * ASEFile::load(const std::string &name)
Model *model = new Model(name);
// default material
- Material *material = Material::find("models/" + name);
+ Material *material = Material::find(name);
if (!material) {
- material = new Material("models/" + name);
+ material = new Material(name);
Material::add(material);
material->set_flags(Material::Texture);
material->set_texture(material->name());
@@ -440,13 +439,13 @@ Model * ASEFile::load(const std::string &name)
Fragment *fragment = new Fragment(Fragment::Triangles, material);
FragmentGroup *group = new FragmentGroup();
group->set_type(FragmentGroup::None);
- group->push_back(fragment);
+ group->add_fragment(fragment);
// calculate model center
math::Vector3f center((asefile.ase_minbbox + asefile.ase_maxbbox) * 0.5f);
- //const float scale = SCALE;
- const float scale = 0.125f;
+ const float scale = SCALE;
+ //const float scale = 0.125f;
// caculate bounding box
model->model_minbbox = (asefile.ase_minbbox - center) * scale;
diff --git a/src/model/classes.cc b/src/model/classes.cc
index 3907184..2a16bae 100644
--- a/src/model/classes.cc
+++ b/src/model/classes.cc
@@ -8,16 +8,6 @@
namespace model {
-/* ---- class MapClass --------------------------------------------- */
-
-MapClass::MapClass()
-{
-}
-
-MapClass::~MapClass()
-{
-}
-
/* ---- class Light ------------------------------------------------ */
Light::Light() :
@@ -83,4 +73,15 @@ Dock::~Dock()
{
}
+/* ---- class SubModel---------------------------------------------- */
+
+SubModel::SubModel()
+{
+ submodel_scale = 1.0f;
+}
+
+SubModel::~SubModel()
+{
+}
+
}
diff --git a/src/model/classes.h b/src/model/classes.h
index c2b6a20..111d7d0 100644
--- a/src/model/classes.h
+++ b/src/model/classes.h
@@ -23,28 +23,6 @@ namespace model
*/
enum Cull { CullNone=0, CullBack=1, CullFront=2 };
-/* ---- class MapClass --------------------------------------------- */
-
-class MapClass
-{
-public:
- MapClass();
- ~MapClass();
-
- inline const math::Vector3f &location() const { return mapclass_location; }
-
- inline const math::Axis &axis() const { return mapclass_axis; }
-
-
- inline void set_location(const math::Vector3f location) { mapclass_location.assign(location); }
-
- inline void set_axis(const math::Axis axis) { mapclass_axis.assign(axis); }
-
-private:
- math::Vector3f mapclass_location;
- math::Axis mapclass_axis;
-};
-
/* ---- class Light ------------------------------------------------ */
/// an exterior light
@@ -243,6 +221,38 @@ public:
float dock_radius;
};
+/* ---- class SubModel --------------------------------------------- */
+
+/// a submodel
+class SubModel
+{
+public:
+ SubModel();
+ ~SubModel();
+
+ inline const std::string &name() const { return submodel_name; }
+
+ inline const float scale() const { return submodel_scale; }
+
+ inline const math::Vector3f &location() const { return submodel_location; }
+
+ inline math::Axis &axis() { return submodel_axis; }
+
+ inline void set_scale(const float scale) { submodel_scale = scale; }
+
+ inline void set_name(const std::string &name) { submodel_name.assign(name); }
+
+ inline void set_location(const math::Vector3f &location) { submodel_location.assign(location); }
+
+ inline void set_axis(const math::Axis &axis) { submodel_axis.assign(axis); }
+
+private:
+ std::string submodel_name;
+ float submodel_scale;
+ math::Vector3f submodel_location;
+ math::Axis submodel_axis;
+};
+
}
#endif // __INCLUDED_MODEL_CLASSES_H__
diff --git a/src/model/fragment.cc b/src/model/fragment.cc
index 72d8e2a..8c3481c 100644
--- a/src/model/fragment.cc
+++ b/src/model/fragment.cc
@@ -16,6 +16,15 @@ namespace model
Quads: the number of Quads is size/4
*/
+Fragment::Fragment(const Fragment &other)
+{
+ fragment_type = other.fragment_type;
+ fragment_index = other.fragment_index;
+ fragment_structural_size = other.fragment_structural_size;
+ fragment_detail_size = other.fragment_detail_size;
+ fragment_material = other.fragment_material;
+}
+
Fragment::Fragment(Type type, const Material *material)
{
fragment_type = type;
@@ -53,6 +62,8 @@ size_t Fragment::add_vertex(math::Vector3f const & vertex, math::Vector3f const
FragmentGroup::FragmentGroup()
{
group_type = None;
+ group_scale = 1.0f;
+ group_transform = false;
}
FragmentGroup::~FragmentGroup()
diff --git a/src/model/fragment.h b/src/model/fragment.h
index 9d992e1..0a9ca6a 100644
--- a/src/model/fragment.h
+++ b/src/model/fragment.h
@@ -26,6 +26,11 @@ public:
/// create a new fragment
Fragment(Type type, const Material *material);
+
+ /**
+ * @brief copy constructor
+ */
+ Fragment(const Fragment &other);
/// add a vertex to the fragment
size_t add_vertex(math::Vector3f const & vertex, math::Vector3f const &normal, bool detail);
@@ -95,6 +100,10 @@ public:
inline const float speed() const { return group_speed; }
+ inline const float scale() const { return group_scale; }
+
+ inline const bool transform() const { return group_transform; }
+
inline void set_type(const Type type) { group_type = type; }
@@ -104,6 +113,9 @@ public:
inline void set_speed(const float speed) { group_speed = speed; }
+ inline void set_scale(const float scale) { group_scale = scale; }
+
+ inline void set_transform(const bool transform) { group_transform = transform; }
inline iterator begin() { return group_fragments.begin(); }
@@ -111,7 +123,7 @@ public:
inline const size_t size() const { return group_fragments.size(); }
- inline void push_back(Fragment *fragment) { group_fragments.push_back(fragment); }
+ inline void add_fragment(Fragment *fragment) { group_fragments.push_back(fragment); }
void clear();
@@ -121,11 +133,13 @@ private:
Fragments group_fragments;
math::Vector3f group_location;
- math::Vector3f group_forward;
math::Axis group_axis;
Type group_type;
float group_speed;
+ float group_scale;
+
+ bool group_transform;
};
}
diff --git a/src/model/map.cc b/src/model/map.cc
index 9cb5295..164be3e 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -31,20 +31,22 @@ const float MAX_BOUNDS = 16384;
const float MIN_DELTA = 10e-10;
-Map::Map() : map_center(0,0,0)
+MapFile::MapFile() : map_center(0,0,0)
{
mapfile_name.clear();
map_brushes = 0;
map_faces = 0;
map_faces_detail = 0;
+
+ warning_q2brush = false;
}
-Map::~Map()
+MapFile::~MapFile()
{
clear_materials();
}
-void Map::clear_materials()
+void MapFile::clear_materials()
{
for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) {
// delete list of primitives
@@ -53,9 +55,9 @@ void Map::clear_materials()
map_materials.clear();
}
-bool Map::open(std::string const & mapname)
+bool MapFile::open(std::string const & mapname)
{
-
+ warning_q2brush = false;
last_read_was_classname = false;
last_read_was_key = false;
key_current = "";
@@ -66,7 +68,6 @@ bool Map::open(std::string const & mapname)
clear_materials();
- mapfile_name.assign("maps/");
mapfile_name.append(mapname);
mapfile_name.append(".map");
@@ -78,22 +79,22 @@ bool Map::open(std::string const & mapname)
}
-bool Map::got_classname() const
+bool MapFile::got_classname() const
{
return last_read_was_classname;
}
-bool Map::got_classname(const char * classnamelabel) const
+bool MapFile::got_classname(const char * classnamelabel) const
{
return (last_read_was_classname && (classname_current.compare(classnamelabel) == 0));
}
-bool Map::got_classend(const char * classnamelabel) const
+bool MapFile::got_classend(const char * classnamelabel) const
{
return (last_read_was_classend && (classname_current.compare(classnamelabel) == 0));
}
-bool Map::getline()
+bool MapFile::getline()
{
using math::Vector3f;
@@ -216,8 +217,10 @@ bool Map::getline()
plane->detail() = true;
// surface flags
- if (!(linestream >> n))
+ if (!(linestream >> n)) {
n = 0;
+ warning_q2brush = true;
+ }
plane->surface_flags() = n;
planes.push_back(plane);
@@ -234,7 +237,7 @@ bool Map::getline()
return true;
}
-void Map::make_brushface(Plane *face)
+void MapFile::make_brushface(Plane *face)
{
using math::Vector3f;
@@ -517,7 +520,7 @@ void Map::make_brushface(Plane *face)
vl.clear();
}
-bool Map::got_key_string(const char * keylabel, std::string & valuestring)
+bool MapFile::got_key_string(const char * keylabel, std::string & valuestring)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
valuestring.assign(value_current);
@@ -527,7 +530,7 @@ bool Map::got_key_string(const char * keylabel, std::string & valuestring)
}
}
-bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v)
+bool MapFile::got_key_vector3f(const char * keylabel, math::Vector3f & v)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
@@ -543,7 +546,7 @@ bool Map::got_key_vector3f(const char * keylabel, math::Vector3f & v)
}
}
-bool Map::got_key_float(const char * keylabel, float & f)
+bool MapFile::got_key_float(const char * keylabel, float & f)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
@@ -556,7 +559,7 @@ bool Map::got_key_float(const char * keylabel, float & f)
}
}
-bool Map::got_key_int(const char * keylabel, unsigned int & u)
+bool MapFile::got_key_int(const char * keylabel, unsigned int & u)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
@@ -569,12 +572,12 @@ bool Map::got_key_int(const char * keylabel, unsigned int & u)
}
}
-bool Map::got_key(const char * keylabel)
+bool MapFile::got_key(const char * keylabel)
{
return (last_read_was_key && (key_current.compare(keylabel) == 0));
}
-bool Map::got_key_angle(const char * keylabel, float & f)
+bool MapFile::got_key_angle(const char * keylabel, float & f)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
@@ -589,7 +592,7 @@ bool Map::got_key_angle(const char * keylabel, float & f)
}
}
-bool Map::got_key_color(const char * keylabel, math::Color & color)
+bool MapFile::got_key_color(const char * keylabel, math::Color & color)
{
if (last_read_was_key && (key_current.compare(keylabel) == 0)) {
std::istringstream is(value_current);
@@ -610,12 +613,12 @@ bool Map::got_key_color(const char * keylabel, math::Color & color)
}
}
-void Map::close()
+void MapFile::close()
{
mapfile_ifs.close();
}
-void Map::clear_bbox()
+void MapFile::clear_bbox()
{
for (int i=0; i < 3; i++) {
class_minbbox[i] = MAX_BOUNDS;
@@ -626,7 +629,7 @@ void Map::clear_bbox()
class_speed = 0;
}
-void Map::load_worldspawn(Model *model)
+void MapFile::load_worldspawn(Model *model)
{
if (!map_materials.size())
return;
@@ -642,22 +645,25 @@ void Map::load_worldspawn(Model *model)
load_fragmentgroup(model, FragmentGroup::None);
}
-void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
+void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
{
if (!VertexArray::instance() || VertexArray::instance()->overflow())
return;
if (!map_materials.size())
return;
+
+ FragmentGroup *group = new FragmentGroup();
if (class_type == FragmentGroup::Rotate) {
if (class_speed == 0) {
// default rotation speed 45 degrees per second
class_speed = 45.0f;
}
+
+ group->set_transform(true);
}
- FragmentGroup *group = new FragmentGroup();
group->set_type(class_type);
group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center);
group->set_axis(class_axis);
@@ -700,7 +706,7 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
}
// add the fragment to the group
- group->push_back(fragment);
+ group->add_fragment(fragment);
}
// store quads
@@ -738,7 +744,7 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
}
// add the fragment to the group
- group->push_back(fragment);
+ group->add_fragment(fragment);
}
}
@@ -747,25 +753,25 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
model->add_group(group);
}
-void Map::unknown_value() const
+void MapFile::unknown_value() const
{
con_warn << name() << " unknown value '" << value() << "' for '" << classname() << ":" << key() << "' at line " << line() << std::endl;
}
-void Map::unknown_key() const
+void MapFile::unknown_key() const
{
con_warn << name() << " unknown key '" << classname() << ":" << key() << "' at line " << line() << std::endl;
}
-void Map::unknown_class() const
+void MapFile::unknown_class() const
{
con_warn << name() << " unknown class '" << classname() << "' at line " << line() << std::endl;
}
-Model * Map::load(std::string const &name)
+Model * MapFile::load(std::string const &name)
{
// open the .map file
- Map mapfile;
+ MapFile mapfile;
if (!mapfile.open(name)) {
return 0;
@@ -778,10 +784,17 @@ Model * Map::load(std::string const &name)
Particles *particles = 0;
Flare *flare = 0;
Light *light = 0;
+ SubModel *submodel = 0;
+
+ std::string modelname;
+ math::Vector3f location;
+
+ typedef std::list<SubModel *> SubModelList;
+ SubModelList submodel_list;
unsigned int u;
float angle;
- float r;
+ float r, s;
std::string str;
while (mapfile.getline()) {
@@ -1019,6 +1032,46 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key()) {
mapfile.unknown_key();
}
+
+ } else if (mapfile.got_classname("misc_model")) {
+
+ // new submodel
+ submodel = new SubModel();
+ submodel_list.push_back(submodel);
+
+ } else if (mapfile.classname().compare("misc_model") == 0) {
+
+ // submodel attributes
+ if (mapfile.got_key_vector3f("origin", location)) {
+ submodel->set_location(location * SCALE);
+ continue;
+
+ } else if (mapfile.got_key_string("model", modelname)) {
+
+ // remove extension
+ if (modelname[modelname.size()-4] == '.') {
+ modelname.erase(modelname.size()-4);
+ }
+
+ submodel->set_name(modelname);
+ continue;
+
+ } else if (mapfile.got_key_float("angle", angle)) {
+ if (angle == ANGLEUP) {
+ submodel->axis().change_pitch(90.0f);
+ } else if (angle == ANGLEDOWN) {
+ submodel->axis().change_pitch(-90.0f);
+ } else {
+ submodel->axis().change_direction(angle);
+ }
+
+ } else if (mapfile.got_key_float("modelscale", s)) {
+ if (s) {
+ submodel->set_scale(s);
+ } else {
+ submodel->set_scale(1.0f);
+ }
+ }
} else if (mapfile.got_classname("fx_particles")) {
@@ -1098,8 +1151,52 @@ Model * Map::load(std::string const &name)
(*dit)->dock_location -= mapfile.map_center;
}
+ // FIXME this will go wrong if a Rotate group is imported as submodel
+ for (SubModelList::iterator smit = submodel_list.begin(); smit != submodel_list.end(); smit++) {
+ submodel = (*smit);
+ Model *submodel_model = 0;
+
+ if (submodel->name().size()) {
+ submodel_model = Model::load(submodel->name());
+ }
+
+ if (submodel_model) {
+ // copy fragmentgroups
+ for (Model::Groups::iterator git = submodel_model->groups().begin(); git != submodel_model->groups().end(); git++) {
+ FragmentGroup *groupsrc = (*git);
+ FragmentGroup *groupdst = new FragmentGroup();
+
+ groupdst->set_transform(true);
+ groupdst->set_type(groupsrc->type());
+ groupdst->set_scale(groupsrc->scale() * submodel->scale());
+ groupdst->set_speed(groupsrc->speed());
+ groupdst->set_location(groupsrc->location() + (submodel->location() - mapfile.map_center));
+ groupdst->set_axis(groupsrc->axis() * submodel->axis());
+
+ // copy fragments
+ for (FragmentGroup::iterator fit = groupsrc->begin(); fit != groupsrc->end(); fit++) {
+ Fragment *fragmentdst = new Fragment(*(*fit));
+ groupdst->add_fragment(fragmentdst);
+ }
+
+ if (groupdst->size()) {
+ model->add_group(groupdst);
+ } else {
+ delete groupdst;
+ }
+ }
+
+ con_debug << " imported submodel '" << submodel->name() << "'" << std::endl;
+ }
+
+ delete submodel;
+
+ }
+
con_debug << " " << mapfile.name() << " " << mapfile.map_brushes << " brushes " <<
mapfile.map_faces << "/" << mapfile.map_faces_detail << " faces/detail " << std::endl;
+ if (mapfile.warning_q2brush)
+ con_warn << " quake2 style brushes detected" << std::endl;
return model;
}
diff --git a/src/model/map.h b/src/model/map.h
index 8dc688e..ed0b3e1 100644
--- a/src/model/map.h
+++ b/src/model/map.h
@@ -4,8 +4,8 @@
the terms of the GNU General Public License version 2
*/
-#ifndef __INCLUDED_MODEL_MAP_H__
-#define __INCLUDED_MODEL_MAP_H__
+#ifndef __INCLUDED_MODEL_MAPFILE_H__
+#define __INCLUDED_MODEL_MAPFILE_H__
#include <string>
#include <vector>
@@ -20,7 +20,7 @@ namespace model
{
/// class to parse the .map file structure and load geometry data into a model
-class Map
+class MapFile
{
public:
@@ -32,8 +32,8 @@ public:
static Model *load(std::string const &name);
private:
- Map();
- ~Map();
+ MapFile();
+ ~MapFile();
/// tpye definition for a per-material list of Primitives
typedef std::map<Material *, Primitives *> Materials;
@@ -180,8 +180,10 @@ private:
math::Vector3f map_center;
Materials map_materials;
+
+ bool warning_q2brush;
};
}
-#endif // __INCLUDED_MODEL_MAP_H__
+#endif // __INCLUDED_MODEL_MAPFILE_H__
diff --git a/src/model/material.cc b/src/model/material.cc
index 7d278f9..c35740f 100644
--- a/src/model/material.cc
+++ b/src/model/material.cc
@@ -163,6 +163,7 @@ void Material::load_shader(const std::string &shadername)
// texture name should not contain spaces
if (linestream >> firstword) {
+ // FIXME remve extension
material->set_texture(firstword);
material->set_flags(Material::Texture);
} else {
diff --git a/src/model/model.cc b/src/model/model.cc
index 3ed5a93..b02f127 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -103,7 +103,7 @@ Model *Model::load(std::string const & name)
Model *model = find(name);
if (!model) {
// try loading the .map model
- model = Map::load(name);
+ model = MapFile::load(name);
}
if (!model) {
@@ -112,7 +112,7 @@ Model *Model::load(std::string const & name)
}
if (!model) {
- con_warn << "Could not load maps/" << name << ".map or models/" << name << ".ase" << std::endl;
+ con_warn << "Could not open " << name << std::endl;
} else {
model_registry[model->name()] = model;
}