diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/model/Makefile.am | 6 | ||||
-rw-r--r-- | src/model/asefile.cc | 26 | ||||
-rw-r--r-- | src/model/face.cc | 43 | ||||
-rw-r--r-- | src/model/face.h | 113 | ||||
-rw-r--r-- | src/model/mapfile.cc (renamed from src/model/map.cc) | 249 | ||||
-rw-r--r-- | src/model/mapfile.h (renamed from src/model/map.h) | 6 | ||||
-rw-r--r-- | src/model/material.cc | 34 | ||||
-rw-r--r-- | src/model/material.h | 34 | ||||
-rw-r--r-- | src/model/model.cc | 6 | ||||
-rw-r--r-- | src/model/model.h | 2 | ||||
-rw-r--r-- | src/model/parts.cc (renamed from src/model/classes.cc) | 2 | ||||
-rw-r--r-- | src/model/parts.h (renamed from src/model/classes.h) | 6 | ||||
-rw-r--r-- | src/model/plane.cc | 42 | ||||
-rw-r--r-- | src/model/plane.h | 88 | ||||
-rw-r--r-- | src/model/primitives.cc | 6 | ||||
-rw-r--r-- | src/model/primitives.h | 4 | ||||
-rw-r--r-- | src/render/particles.h | 2 | ||||
-rw-r--r-- | src/render/textures.cc | 25 | ||||
-rw-r--r-- | src/render/textures.h | 5 |
19 files changed, 478 insertions, 221 deletions
diff --git a/src/model/Makefile.am b/src/model/Makefile.am index 94b3c96..fe398a2 100644 --- a/src/model/Makefile.am +++ b/src/model/Makefile.am @@ -1,11 +1,11 @@ METASOURCES = AUTO -libmodel_la_SOURCES = asefile.cc classes.cc fragment.cc map.cc material.cc \ - model.cc plane.cc primitives.cc quad.cc triangle.cc vertexarray.cc +libmodel_la_SOURCES = asefile.cc parts.cc fragment.cc mapfile.cc material.cc \ + model.cc face.cc primitives.cc quad.cc triangle.cc vertexarray.cc libmodel_la_LDFLAGS = -avoid-version -no-undefined -lm noinst_LTLIBRARIES = libmodel.la -noinst_HEADERS = asefile.h classes.h fragment.h map.h material.h model.h plane.h \ +noinst_HEADERS = asefile.h parts.h fragment.h mapfile.h material.h model.h face.h \ primitives.h quad.h triangle.h vertexarray.h INCLUDES = -I$(top_srcdir)/src diff --git a/src/model/asefile.cc b/src/model/asefile.cc index 28c84cf..67be531 100644 --- a/src/model/asefile.cc +++ b/src/model/asefile.cc @@ -89,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; @@ -130,7 +130,7 @@ bool ASEFile::read_mesh_face_list(std::istream &is) line >> word; if (word.compare("}") == 0) { - con_debug << " " << count << " mesh faces" << std::endl; + //con_debug << " " << count << " mesh faces" << std::endl; return true; } else if ( word.compare("*MESH_FACE") == 0) { @@ -178,7 +178,7 @@ bool ASEFile::read_mesh_normals(std::istream &is) line >> firstword; if (firstword.compare("}") == 0) { - con_debug << " " << count << " face normals" << std::endl; + //con_debug << " " << count << " face normals" << std::endl; return true; } else if ( firstword.compare("*MESH_FACENORMAL") == 0) { @@ -188,7 +188,7 @@ bool ASEFile::read_mesh_normals(std::istream &is) (*it).second->normal().assign(x, y, z); count++; } else { - con_debug << " could not find face " << index << std::endl; + con_warn << " could not find face " << index << std::endl; } vertindex = 0; } else { @@ -227,7 +227,7 @@ bool ASEFile::read_mesh_tvertex_list(std::istream &is) line >> firstword; if (firstword.compare("}") == 0) { - con_debug << " " << count << " texture vertices" << std::endl; + //con_debug << " " << count << " texture vertices" << std::endl; return true; } else if ( firstword.compare("*MESH_TVERT") == 0) { @@ -258,7 +258,7 @@ size_t count = 0; line >> firstword; if (firstword.compare("}") == 0) { - con_debug << " " << count << " face texture coordinates" << std::endl; + //con_debug << " " << count << " face texture coordinates" << std::endl; return true; } else if ( firstword.compare("*MESH_TFACE") == 0) { @@ -300,31 +300,31 @@ bool ASEFile::read_mesh(std::istream &is) if ((level == 1 ) && (word.compare("*MESH_VERTEX_LIST") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " *MESH_VERTEX_LIST" << std::endl; + //con_debug << " " << name() << " *MESH_VERTEX_LIST" << std::endl; read_mesh_vertex_list(is); } } else if ((level == 1 ) && (word.compare("*MESH_FACE_LIST") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " *MESH_FACE_LIST" << std::endl; + //con_debug << " " << name() << " *MESH_FACE_LIST" << std::endl; read_mesh_face_list(is); } } else if ((level == 1 ) && (word.compare("*MESH_NORMALS") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " *MESH_NORMALS" << std::endl; + //con_debug << " " << name() << " *MESH_NORMALS" << std::endl; read_mesh_normals(is); } } else if ((level == 1 ) && (word.compare("*MESH_TVERTLIST") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " *MESH_TVERTLIST" << std::endl; + //con_debug << " " << name() << " *MESH_TVERTLIST" << std::endl; read_mesh_tvertex_list(is); } } else if ((level == 1 ) && (word.compare("*MESH_TFACELIST") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " *MESH_TFACELIST" << std::endl; + //con_debug << " " << name() << " *MESH_TFACELIST" << std::endl; read_mesh_tface_list(is); } @@ -360,7 +360,7 @@ bool ASEFile::read_geom(std::istream &is) if ((level == 1 ) && (word.compare("*MESH") == 0)) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " " << "*MESH" << std::endl; + //con_debug << " " << name() << " " << "*MESH" << std::endl; read_mesh(is); } @@ -400,7 +400,7 @@ bool ASEFile::read() if (word.compare("*GEOMOBJECT") == 0) { if ((line >> word) && (word.compare("{") == 0)) { - con_debug << " " << name() << " " << "*GEOMOBJECT" << std::endl; + //con_debug << " " << name() << " " << "*GEOMOBJECT" << std::endl; read_geom(asefile_ifs); } } diff --git a/src/model/face.cc b/src/model/face.cc new file mode 100644 index 0000000..c6c3269 --- /dev/null +++ b/src/model/face.cc @@ -0,0 +1,43 @@ +/* + model/face.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include <string> + +#include "model/face.h" + +namespace model +{ + +using math::Vector3f; +/* + * all points p(x, y, z) on the plane satisfy the general equation + * x*a() + y*b() + z*c() + d() = 0 + */ + +Face::Face(Vector3f const & point0, Vector3f const &point1, Vector3f const &point2) +{ + face_detail = false; + face_surface_flags = 0; + face_material = 0; + + face_point[0] = point0; + face_point[1] = point1; + face_point[2] = point2; + + face_normal = crossproduct((face_point[1] - face_point[0]) , (face_point[2] - face_point[0])); + pd = -1 * (face_normal.x * face_point[0].x + face_normal.y * face_point[0].y + face_normal.z * face_point[0].z); +} + +Face::Face(Face const & other) +{ + for (size_t i=0; i < 3; i++) + this->face_point[i] = other.face_point[i]; + + face_normal = crossproduct((face_point[1] - face_point[0]) , (face_point[2] - face_point[0])); + pd = -1 * (face_normal.x * face_point[0].x + face_normal.y * face_point[0].y + face_normal.z * face_point[0].z); +} + +} diff --git a/src/model/face.h b/src/model/face.h new file mode 100644 index 0000000..8c75522 --- /dev/null +++ b/src/model/face.h @@ -0,0 +1,113 @@ +/* + model/face.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_MODEL_FACE_H__ +#define __INCLUDED_MODEL_FACE_H__ + +#include <string> + +#include "math/vector2f.h" +#include "math/vector3f.h" +#include "model/material.h" + +namespace model +{ + +/** @brief A class representing the plane of a single model face + * all points p(x, y, z) on the plane satisfy the general equation + * x*a() + y*b() + z*c() + d() = 0 + */ +class Face +{ +public: + /// a plane defined by 3 points in space + Face(math::Vector3f const & point0, math::Vector3f const &point1, math::Vector3f const &point2); + + /// copy constructor + Face(Face const & other); + + /// normal of the plane, not normalized to lenght 1 + inline math::Vector3f const & normal() const + { + return face_normal; + } + + /// the points defining the plane. + /// @param index 0 <= i < 3 + inline math::Vector3f const & point(size_t index) const + { + return face_point[index]; + } + + /// face material + inline Material *material() const + { + return face_material; + } + + /// first parameter of the general plane equation + inline float a() const + { + return face_normal[0]; + } + + /// second parameter of the general plane equation + inline float b() const + { + return face_normal[1]; + } + + /// third param of the general plane equation + inline float c() const + { + return face_normal[2]; + } + + /// fourth parameter of the general plane equation + inline float d() const + { + return pd; + } + + /// indidcates if this plane was generated from a detail brush + inline bool & detail() + { + return face_detail; + } + + /// surface flags + inline unsigned int & surface_flags() + { + return face_surface_flags; + } + + /// return texture transformation vectors + /// @param index 0 <= i < 2 + inline math::Vector3f &tex_vec(size_t index) { return face_tex_vec[index]; } + + /// return texture shift + inline math::Vector2f &tex_shift() { return face_tex_shift; } + + + inline void set_material(Material *material) { face_material = material; } + + +private: + math::Vector3f face_normal; + math::Vector3f face_point[3]; + + math::Vector3f face_tex_vec[2]; + math::Vector2f face_tex_shift; + + Material *face_material; + unsigned int face_surface_flags; + bool face_detail; + float pd; +}; + +} + +#endif // __INCLUDED_MODEL_FACE_H__ diff --git a/src/model/map.cc b/src/model/mapfile.cc index 5d699e6..21d318b 100644 --- a/src/model/map.cc +++ b/src/model/mapfile.cc @@ -7,7 +7,7 @@ #include "auxiliary/functions.h" #include "filesystem/filesystem.h" #include "math/mathlib.h" -#include "model/map.h" +#include "model/mapfile.h" #include "model/material.h" #include "model/model.h" #include "model/vertexarray.h" @@ -20,6 +20,123 @@ namespace model { +/* + from radiant tools/quake3/map.c +*/ + +math::Vector3f texture_baseaxis[18] = +{ + math::Vector3f(0,0,1), math::Vector3f(1,0,0), math::Vector3f(0,-1,0), // floor + math::Vector3f(0,0,-1), math::Vector3f(1,0,0), math::Vector3f(0,-1,0), // ceiling + math::Vector3f(1,0,0), math::Vector3f(0,1,0), math::Vector3f(0,0,-1), // west wall + 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 +}; + +// determines best orthagonal axis to project a texture onto a wall (must be identical in radiant!) +void texture_axis_from_plane(const Face &face, math::Vector3f &xv, math::Vector3f &yv) +{ + size_t best_axis = 0; + float dot = 0; + float best = 0; + + for (size_t i=0 ; i<6 ; i++) + { + dot = math::dotproduct(face.normal(), texture_baseaxis[i *3]); + if( dot > best + 0.0001f ) /* ydnar: bug 637 fix, suggested by jmonroe */ + { + best = dot; + best_axis = i; + } + } + + xv.assign(texture_baseaxis[best_axis*3+1]); + yv.assign(texture_baseaxis[best_axis*3+2]); +} + +// creates world-to-texture mapping vecs for crappy quake plane arrangements +void face_texture_verts(Face &face, const math::Vector2f &tex_shift, const float tex_rotate, const math::Vector2f & tex_scale) +{ + math::Vector3f vecs[2]; + math::Vector2f scale(tex_scale); + + int sv, tv; + float ang, sinv, cosv; + float ns, nt; + int i, j; + + texture_axis_from_plane(face, vecs[0], vecs[1]); + + if (!scale[0]) + scale[0] = 1; + if (!scale[1]) + scale[1] = 1; + + // rotate axis + if (tex_rotate == 0.0f) + { sinv = 0.0f ; cosv = 1.0f; } + else if (tex_rotate == 90.0f) + { sinv = 1.0f ; cosv = 0.0f; } + else if (tex_rotate == 180.0f) + { sinv = 0.0f; cosv = -1.0f; } + else if (tex_rotate == 270.0f) + { sinv = -1.0f ; cosv = 0.0f; } + else + { + ang = tex_rotate / 180.0f * M_PI; + sinv = sinf(ang); + cosv = cosf(ang); + } + + if (vecs[0][0]) + sv = 0; + else if (vecs[0][1]) + sv = 1; + else + sv = 2; + + if (vecs[1][0]) + tv = 0; + else if (vecs[1][1]) + tv = 1; + else + tv = 2; + + for (i=0 ; i<2 ; i++) { + ns = cosv * vecs[i][sv] - sinv * vecs[i][tv]; + nt = sinv * vecs[i][sv] + cosv * vecs[i][tv]; + vecs[i][sv] = ns; + vecs[i][tv] = nt; + } + + for (i=0 ; i<2 ; i++) + for (j=0 ; j<3 ; j++) + face.tex_vec(i)[j] = vecs[i][j] / scale[i]; + + face.tex_shift().assign(tex_shift); +} + +const math::Vector2f map_texture_coords(Face *face, const math::Vector3f &v) +{ + math::Vector2f t ( + (face->tex_shift().x + math::dotproduct(face->tex_vec(0), v)) / face->material()->size().width(), + (face->tex_shift().y + math::dotproduct(face->tex_vec(1), v)) / face->material()->size().height() + ); + + //con_debug << " texture coords for vertex (" << v << ") set to (" << t.x << "," << t.y << ")" << std::endl; + return t; +} +/* + + // nearest-axial projection + dv->st[ 0 ] = s->vecs[ 0 ][ 3 ] + DotProduct( s->vecs[ 0 ], vTranslated ); + dv->st[ 1 ] = s->vecs[ 1 ][ 3 ] + DotProduct( s->vecs[ 1 ], vTranslated ); + dv->st[ 0 ] /= si->shaderWidth; + dv->st[ 1 ] /= si->shaderHeight; + +*/ + // function to test spawnflags inline bool spawnflag_isset(unsigned int spawnflags, unsigned int flag) { @@ -131,12 +248,12 @@ bool MapFile::getline() // end-of-brush // for every face - for (std::vector<Plane *>::iterator face = planes.begin(); face != planes.end(); face++) { + for (std::vector<Face *>::iterator face = planes.begin(); face != planes.end(); face++) { make_brushface((*face)); } // clean planes - for (std::vector<Plane *>::iterator it = planes.begin(); it != planes.end(); it++) { + for (std::vector<Face *>::iterator it = planes.begin(); it != planes.end(); it++) { delete(*it); } planes.clear(); @@ -200,30 +317,55 @@ bool MapFile::getline() linestream >> tmp; // ( linestream >> p3; linestream >> tmp; // ) + + Face *face = new Face(p1, p2, p3); + + // material linestream >> texture; + aux::to_lowercase(texture); + + Material *material = Material::find("textures/" + texture); + if (!material) { + material = new Material("textures/" + texture); + Material::add(material); + material->set_flags(Material::Texture); + material->set_texture(material->name()); + } + face->set_material(material); - // 5 numbers (texture alignment?) - for (int i=0; i < 5; i++) - linestream >> tmp; + // texture alignment + float tx, ty, tr, tsx, tsy; + linestream >> tx >> ty; // texture translation + linestream >> tr; // texture rotation angle + linestream >> tsx >> tsy; // texture scale + /* + face->tex_translate().assign(tx, ty); + face->tex_rotate() = tr; + face->tex_scale().assign(tsx, tsy); + */ + + // from radiant: tools/quake3/q3map2map.c + tsx -= (floor( tsx / material->size().width()) * material->size().width()); + tsy -= (floor( tsy / material->size().height()) * material->size().height()); + + // store the texture transformation for this face + face_texture_verts((*face), math::Vector2f(tx, ty), tr, math::Vector2f(tsx, tsy)); - // content flags ? + // content flags if (!(linestream >> n)) n = 0; - - Plane *plane = new Plane(p1, p2, p3); - aux::to_lowercase(texture); - plane->texture() = texture; if (n > 0) - plane->detail() = true; - + face->detail() = true; + // surface flags if (!(linestream >> n)) { n = 0; warning_q2brush = true; } - plane->surface_flags() = n; - - planes.push_back(plane); + face->surface_flags() = n; + + + planes.push_back(face); value_current.clear(); } @@ -237,22 +379,18 @@ bool MapFile::getline() return true; } -void MapFile::make_brushface(Plane *face) +void MapFile::make_brushface(Face *face) { using math::Vector3f; - // ignore caulk - if (face->texture() == "common/caulk") { + // ignore materials with the 'Ignore' flag set + if ((face->material()->flags() & Material::Ignore) == Material::Ignore) { return; } - - // FIXME clip should be parsed as collision blocks - if (face->texture() == "common/clip") { - return; - } - + // statistics map_faces++; + if (face->detail()) { map_faces_detail++; } @@ -338,9 +476,9 @@ void MapFile::make_brushface(Plane *face) // intersect the face with every plane - for (std::vector<Plane *>::iterator pit = planes.begin(); pit != planes.end(); pit++) { + for (std::vector<Face *>::iterator pit = planes.begin(); pit != planes.end(); pit++) { - Plane *plane = (*pit); + Face *plane = (*pit); if (plane == face) { continue; } @@ -436,40 +574,31 @@ void MapFile::make_brushface(Plane *face) } if (vl.size() > 2) { - - Material *material = Material::find("textures/" + face->texture()); - if (!material) { - material = new Material("textures/" + face->texture()); - Material::add(material); - material->set_flags(Material::Texture); - material->set_texture(material->name()); - } - // find the list if primitives for the current material, allocate a new one if necessary Primitives *primitives = 0; - Materials::iterator mit = map_materials.find(material); + Materials::iterator mit = map_materials.find(face->material()); if (mit == map_materials.end()) { - primitives = new Primitives(material); - map_materials[material] = primitives; + primitives = new Primitives(face->material()); + map_materials[face->material()] = primitives; } else { primitives = (*mit).second; } - // calculate bounding box + // scale vertices and calculate the bounding box for (std::vector<Vector3f *>::iterator it = vl.begin(); it != vl.end(); it++) { - *(*it) *= SCALE; + //*(*it) *= SCALE; for (int i=0; i < 3; i++) { - if (class_maxbbox[i] < (*(*it))[i]) - class_maxbbox[i] = (*(*it))[i]; + if (class_maxbbox[i] < (*(*it))[i] * SCALE) + class_maxbbox[i] = (*(*it))[i] * SCALE; - if (class_minbbox[i] > (*(*it))[i]) - class_minbbox[i] = (*(*it))[i]; + if (class_minbbox[i] > (*(*it))[i] * SCALE) + class_minbbox[i] = (*(*it))[i] * SCALE; } } - +/* #ifndef HAVE_BULLET // Quads are disable to use model data for bullet physics @@ -494,6 +623,7 @@ void MapFile::make_brushface(Plane *face) vl.pop_back(); } #endif +*/ // split polygon into triangles while (vl.size() > 2) { std::vector<Vector3f *>::iterator v0 = vl.begin(); @@ -504,7 +634,18 @@ void MapFile::make_brushface(Plane *face) Vector3f n(face->normal()*-1); n.normalize(); - primitives->add_triangle(*(*vn1), *(*vn), *(*v0), n, face->detail()); + Triangle *triangle = primitives->add_triangle(*(*vn1) * SCALE, *(*vn) * SCALE, *(*v0) * SCALE, n, face->detail()); + + if (face->material()->flags() & Material::Texture) { + triangle->t0().assign(map_texture_coords(face, *(*vn1))); + triangle->t1().assign(map_texture_coords(face, *(*vn))); + triangle->t2().assign(map_texture_coords(face, *(*v0))); + } + /* + triangle->t0().assign(0, 0); + triangle->t1().assign(0, 1); + triangle->t2().assign(1, 1); + */ delete(*vn); vl.pop_back(); } @@ -689,9 +830,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(), false); - count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), false); - count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), false); + 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); if (count == 3) model->model_tris_count++; } @@ -702,9 +843,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(), true); - count += fragment->add_vertex(triangle->v1()-group_center, triangle->normal(), true); - count += fragment->add_vertex(triangle->v2()-group_center, triangle->normal(), true); + 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); if (count == 3) { model->model_tris_count++; model->model_tris_detail_count++; @@ -1177,7 +1318,7 @@ Model * MapFile::load(std::string const &name) 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_location(groupsrc->location() + submodel->location() - mapfile.map_center); groupdst->set_axis(groupsrc->axis() * submodel->axis()); // copy fragments diff --git a/src/model/map.h b/src/model/mapfile.h index ed0b3e1..fd6bf48 100644 --- a/src/model/map.h +++ b/src/model/mapfile.h @@ -12,7 +12,7 @@ #include "model/material.h" #include "model/model.h" -#include "model/plane.h" +#include "model/face.h" #include "model/primitives.h" #include "filesystem/filestream.h" @@ -132,7 +132,7 @@ private: void close(); /// generate triangles for one plane in the plane list - void make_brushface(Plane *face); + void make_brushface(Face *face); /// load parsed primitives into model worldspawn void load_worldspawn(Model *model); @@ -153,7 +153,7 @@ private: void unknown_value() const; /// list of planes for the current brush - std::vector<Plane *> planes; + std::vector<Face *> planes; std::string classname_current; diff --git a/src/model/material.cc b/src/model/material.cc index c35740f..280ebba 100644 --- a/src/model/material.cc +++ b/src/model/material.cc @@ -15,11 +15,18 @@ namespace model { -Material::Material(const std::string &name) : material_name(name), material_color(1.0f) +Material::LoaderFuncPtr Material::material_loaderfunc = 0; +Material::Registry Material::material_registry; + +Material::Material(const std::string &name) : + material_name(name), + material_color(1.0f) , + material_size(64.0f, 64.0f) { aux::to_lowercase(material_name); material_flags = 0; material_texture_id = 0; + } Material::~Material() @@ -35,6 +42,9 @@ void Material::set_color(const math::Color &color) void Material::set_texture(const std::string &texture) { material_texture.assign(texture); + + if (material_loaderfunc) + material_loaderfunc(this); } void Material::set_texture_id(const size_t texture_id) @@ -42,7 +52,15 @@ void Material::set_texture_id(const size_t texture_id) material_texture_id = texture_id; } -Material::Registry Material::material_registry; +void Material::set_size(const float width, const float height) +{ + material_size.assign(width, height); +} + +void Material::set_size(const math::Vector2f &size) +{ + material_size.assign(size); +} void Material::init() { @@ -155,6 +173,8 @@ void Material::load_shader(const std::string &shadername) material->set_flags(Secondary); } else if (firstword.compare("entitythird") == 0) { material->set_flags(Tertiary); + } else if (firstword.compare("ignore") == 0) { + material->set_flags(Ignore); } else if (firstword.compare("qer_editorimage") == 0) { continue; } else if (firstword.compare("qer_trans") == 0) { @@ -163,7 +183,10 @@ void Material::load_shader(const std::string &shadername) // texture name should not contain spaces if (linestream >> firstword) { - // FIXME remve extension + // remove extension + if (firstword[firstword.size()-4] == '.') { + firstword.erase(firstword.size()-4); + } material->set_texture(firstword); material->set_flags(Material::Texture); } else { @@ -216,4 +239,9 @@ Material *Material::find(const std::string &name) return 0; } +void Material::set_loader_func(LoaderFuncPtr func) +{ + material_loaderfunc = func; +} + } diff --git a/src/model/material.h b/src/model/material.h index 9072a4d..9185fd2 100644 --- a/src/model/material.h +++ b/src/model/material.h @@ -11,6 +11,7 @@ #include <map> #include "math/color.h" +#include "math/vector2f.h" namespace model { @@ -19,8 +20,11 @@ namespace model class Material { public: + /// function pointer type for local functions + typedef void(* LoaderFuncPtr)(Material *); + /// surface flags - enum SurfaceFlags { None=0, Primary=1, Secondary=2, Tertiary=3, Bright=4, Engine=8, Environment=16, Texture=32}; + enum SurfaceFlags { None=0, Primary=1, Secondary=2, Tertiary=3, Bright=4, Engine=8, Environment=16, Texture=32, Ignore=64}; /// type definition for the material registry typedef std::map<std::string, Material *> Registry; @@ -41,14 +45,35 @@ public: inline const size_t texture_id() const { return material_texture_id; } + /** + * @brief returns the material texture size + */ + inline const math::Vector2f & size() const { return material_size; } + /* ---- mutators ------------------------------------------- */ void set_color(const math::Color &color); + /** + * @brief set the material texture name + */ void set_texture(const std::string &texture); + /** + * @brief set the material texture id + */ void set_texture_id(const size_t texture_id); + /** + * @brief set the material texture size + */ + void set_size(const float width, const float height); + + /** + * @brief set the material texture size + */ + void set_size(const math::Vector2f &size); + inline void set_flags(SurfaceFlags flags) { material_flags |= flags; @@ -92,6 +117,8 @@ public: */ static Material *find(const std::string &name); + static void set_loader_func(LoaderFuncPtr func); + private: std::string material_name; @@ -100,10 +127,15 @@ private: std::string material_texture; size_t material_texture_id; + /// size of the material + math::Vector2f material_size; + /// the materials registry static Registry material_registry; static void load_shader(const std::string &shadername); + + static LoaderFuncPtr material_loaderfunc; }; } diff --git a/src/model/model.cc b/src/model/model.cc index b02f127..1f9fcb5 100644 --- a/src/model/model.cc +++ b/src/model/model.cc @@ -5,9 +5,9 @@ */ #include "sys/sys.h" -#include "model/asefile.h" #include "model/model.h" -#include "model/map.h" +#include "model/asefile.h" +#include "model/mapfile.h" #include "model/vertexarray.h" namespace model @@ -112,7 +112,7 @@ Model *Model::load(std::string const & name) } if (!model) { - con_warn << "Could not open " << name << std::endl; + con_warn << "Could not open model " << name << std::endl; } else { model_registry[model->name()] = model; } diff --git a/src/model/model.h b/src/model/model.h index 6e9c5d8..2ca2734 100644 --- a/src/model/model.h +++ b/src/model/model.h @@ -12,7 +12,7 @@ #include <map> #include "math/mathlib.h" -#include "model/classes.h" +#include "model/parts.h" #include "model/fragment.h" /// classes representing 3D geometry diff --git a/src/model/classes.cc b/src/model/parts.cc index 2a16bae..a4a2d1e 100644 --- a/src/model/classes.cc +++ b/src/model/parts.cc @@ -4,7 +4,7 @@ the terms of the GNU General Public License version 2 */ -#include "model/classes.h" +#include "model/parts.h" namespace model { diff --git a/src/model/classes.h b/src/model/parts.h index 111d7d0..8593147 100644 --- a/src/model/classes.h +++ b/src/model/parts.h @@ -4,8 +4,8 @@ the terms of the GNU General Public License version 2 */ -#ifndef __INCLUDED_MODEL_CLASSES_H__ -#define __INCLUDED_MODEL_CLASSES_H__ +#ifndef __INCLUDED_MODEL_PARTS_H__ +#define __INCLUDED_MODEL_PARTS_H__ #include "math/axis.h" #include "math/color.h" @@ -255,5 +255,5 @@ private: } -#endif // __INCLUDED_MODEL_CLASSES_H__ +#endif // __INCLUDED_MODEL_PARTS_H__ diff --git a/src/model/plane.cc b/src/model/plane.cc deleted file mode 100644 index 6d80df6..0000000 --- a/src/model/plane.cc +++ /dev/null @@ -1,42 +0,0 @@ -/* - model/plane.cc - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2 -*/ - -#include <string> - -#include "model/plane.h" - -namespace model -{ - -using math::Vector3f; -/* - * all points p(x, y, z) on the plane satisfy the general equation - * x*a() + y*b() + z*c() + d() = 0 - */ - -Plane::Plane(Vector3f const & point0, Vector3f const &point1, Vector3f const &point2) -{ - plane_detail = false; - plane_surface_flags = 0; - - plane_point[0] = point0; - plane_point[1] = point1; - plane_point[2] = point2; - - plane_normal = crossproduct((plane_point[1] - plane_point[0]) , (plane_point[2] - plane_point[0])); - pd = -1 * (plane_normal.x * plane_point[0].x + plane_normal.y * plane_point[0].y + plane_normal.z * plane_point[0].z); -} - -Plane::Plane(Plane const & other) -{ - for (size_t i=0; i < 3; i++) - this->plane_point[i] = other.plane_point[i]; - - plane_normal = crossproduct((plane_point[1] - plane_point[0]) , (plane_point[2] - plane_point[0])); - pd = -1 * (plane_normal.x * plane_point[0].x + plane_normal.y * plane_point[0].y + plane_normal.z * plane_point[0].z); -} - -} diff --git a/src/model/plane.h b/src/model/plane.h deleted file mode 100644 index 6c19a5a..0000000 --- a/src/model/plane.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - model/plane.h - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_MODEL_PLANE_H__ -#define __INCLUDED_MODEL_PLANE_H__ - -#include <string> - -#include "math/vector3f.h" - -namespace model -{ - -/** @brief A class representing a plane in 3d space - * all points p(x, y, z) on the plane satisfy the general equation - * x*a() + y*b() + z*c() + d() = 0 - */ -class Plane -{ -public: - /// a plane defined by 3 points in space - Plane(math::Vector3f const & point0, math::Vector3f const &point1, math::Vector3f const &point2); - /// copy constructor - Plane(Plane const & other); - - /// normal of the plane, not normalized to lenght 1 - inline math::Vector3f const & normal() const - { - return plane_normal; - } - /// the points defining the plane. - /// @param i 0 <= i < 3 - inline math::Vector3f const & point(size_t i) const - { - return plane_point[i]; - } - /// plane texture - inline std::string & texture() - { - return plane_texture; - } - /// first parameter of the general equation - inline float a() const - { - return plane_normal[0]; - } - /// second parameter of the general equation - inline float b() const - { - return plane_normal[1]; - } - /// third param of the general equation - inline float c() const - { - return plane_normal[2]; - } - /// fourth parameter of the general equation - inline float d() const - { - return pd; - } - /// indidcates if this plane was generated from a detail brush - inline bool & detail() - { - return plane_detail; - } - /// surface flags - inline unsigned int & surface_flags() - { - return plane_surface_flags; - } - - -private: - math::Vector3f plane_point[3]; - math::Vector3f plane_normal; - std::string plane_texture; - unsigned int plane_surface_flags; - bool plane_detail; - float pd; -}; - -} - -#endif // __INCLUDED_MODEL_PLANE_H__ diff --git a/src/model/primitives.cc b/src/model/primitives.cc index 5e58b50..8eec0f4 100644 --- a/src/model/primitives.cc +++ b/src/model/primitives.cc @@ -27,18 +27,20 @@ Primitives::~Primitives() primitives_quads.clear(); } -void Primitives::add_triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, +Triangle *Primitives::add_triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &normal, bool detail) { Triangle *triangle = new Triangle(v0, v1, v2, normal, detail); primitives_triangles.push_back(triangle); + return triangle; } -void Primitives::add_quad(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &v3, +Quad *Primitives::add_quad(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &v3, math::Vector3f const &normal, bool detail) { Quad *quad = new Quad(v0, v1, v2, v3, normal, detail); primitives_quads.push_back(quad); + return quad; } } diff --git a/src/model/primitives.h b/src/model/primitives.h index d113961..116d01b 100644 --- a/src/model/primitives.h +++ b/src/model/primitives.h @@ -49,11 +49,11 @@ public: } /// add a Triangle primitive - void add_triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, + Triangle *add_triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &normal, bool detail); /// add a Quad primitive - void add_quad(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &v3, + Quad *add_quad(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2, math::Vector3f const &v3, math::Vector3f const &normal, bool detail); private: Triangles primitives_triangles; diff --git a/src/render/particles.h b/src/render/particles.h index a36b142..cf0f5eb 100644 --- a/src/render/particles.h +++ b/src/render/particles.h @@ -13,7 +13,7 @@ #include "math/color.h" #include "math/vector3f.h" #include "core/entity.h" -#include "model/classes.h" +#include "model/parts.h" namespace render { diff --git a/src/render/textures.cc b/src/render/textures.cc index 5845bb6..fe85c8d 100644 --- a/src/render/textures.cc +++ b/src/render/textures.cc @@ -23,6 +23,12 @@ namespace render std::map<std::string, size_t> Textures::registry; GLuint Textures::textures[MAXTEXTURES]; +math::Vector2f Textures::texture_size[MAXTEXTURES]; + +void material_loader_func(model::Material *material) +{ + Textures::material_loader(material); +} void Textures::init() { @@ -49,10 +55,13 @@ void Textures::init() load("bitmaps/pointers/center"); load("bitmaps/pointers/control"); load("bitmaps/pointers/target"); + + model::Material::set_loader_func(Textures::material_loader); } void Textures::shutdown() { + model::Material::set_loader_func(0); clear(); } @@ -159,7 +168,7 @@ size_t Textures::load(const std::string &name, const bool filter) if (!image) { // add to the registry with id 0 (texture not found) - con_warn << "Could not open " << filename << std::endl; + con_warn << "Could not open texture " << name << std::endl; registry[name] = 0; return 0; } @@ -181,6 +190,10 @@ size_t Textures::load(const std::string &name, const bool filter) // hardware generated mipmaps (requires OpenGL 1.4) glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); } + + // enable texture wrapping + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } else { // scaling functions glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); @@ -210,6 +223,7 @@ size_t Textures::load(const std::string &name, const bool filter) // add to the registry registry[name] = id; + texture_size[id].assign((float) image->width(), (float) image->height()); // delete image data delete image; @@ -258,4 +272,13 @@ size_t Textures::bind(const size_t texture, const bool filter) return id; } +void Textures::material_loader(model::Material *material) +{ + if ((material->flags() & model::Material::Texture) & (material->texture().size())) { + size_t id = load(material->texture()); + material->set_texture_id(id); + material->set_size(texture_size[id]); + } +} + } diff --git a/src/render/textures.h b/src/render/textures.h index 84d5c9a..c1ccabe 100644 --- a/src/render/textures.h +++ b/src/render/textures.h @@ -10,6 +10,7 @@ #include <string> #include <map> +#include "model/material.h" #include "render/gl.h" namespace render @@ -56,11 +57,15 @@ public: /// list loaded textures static void list(); + /// material loader func + static void material_loader(model::Material *material); + private: static void clear(); typedef std::map<std::string, size_t>::iterator iterator; + static math::Vector2f texture_size[MAXTEXTURES]; static std::map<std::string, size_t> registry; static GLuint textures[MAXTEXTURES]; }; |