Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2009-08-12 12:03:18 +0000
committerStijn Buys <ingar@osirion.org>2009-08-12 12:03:18 +0000
commit183f0f0b905715f0d89b38174fdfd44641c1a79c (patch)
tree6cae553ac6284044002fb668c7991da27291825d
parent8bf8afe68ca15c61b0dea1f5c1ef5fc7186dca0f (diff)
src/model filenames cleanup, parse .map texture coordinates, early loading of material textures
-rw-r--r--src/model/Makefile.am6
-rw-r--r--src/model/asefile.cc26
-rw-r--r--src/model/face.cc43
-rw-r--r--src/model/face.h113
-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.cc34
-rw-r--r--src/model/material.h34
-rw-r--r--src/model/model.cc6
-rw-r--r--src/model/model.h2
-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.cc42
-rw-r--r--src/model/plane.h88
-rw-r--r--src/model/primitives.cc6
-rw-r--r--src/model/primitives.h4
-rw-r--r--src/render/particles.h2
-rw-r--r--src/render/textures.cc25
-rw-r--r--src/render/textures.h5
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];
};