Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2009-08-09 21:11:55 +0000
committerStijn Buys <ingar@osirion.org>2009-08-09 21:11:55 +0000
commitbbd04914749b2e3918796fe331daf649b06163ea (patch)
tree0139a4024950ecc5533fd7018ee35942d2ba2680 /src
parent4f576711828f35179dc5d28cfda93eff47e80a74 (diff)
adds r_normals cvar, read normals from .ase models
Diffstat (limited to 'src')
-rw-r--r--src/model/asefile.cc200
-rw-r--r--src/model/asefile.h16
-rw-r--r--src/model/triangle.cc31
-rw-r--r--src/model/triangle.h39
-rw-r--r--src/render/draw.cc32
-rw-r--r--src/render/render.cc4
-rw-r--r--src/render/render.h2
7 files changed, 233 insertions, 91 deletions
diff --git a/src/model/asefile.cc b/src/model/asefile.cc
index a267d9b..7b574d7 100644
--- a/src/model/asefile.cc
+++ b/src/model/asefile.cc
@@ -33,8 +33,16 @@ ASEFile::ASEFile(std::string const &name)
ASEFile::~ASEFile()
{
+ for (VertexList::iterator it = ase_vertexlist.begin(); it != ase_vertexlist.end(); it++) {
+ delete (*it).second;
+ }
ase_vertexlist.clear();
+ for (FaceList::iterator it = ase_facelist.begin(); it != ase_facelist.end(); it++) {
+ delete (*it).second;
+ }
+ ase_facelist.clear();
+
if (asefile_ifs.is_open())
asefile_ifs.close();
}
@@ -63,22 +71,49 @@ bool ASEFile::read_header(std::istream &is)
return true;
}
-bool ASEFile::read_mesh_face_list(std::istream &is)
+bool ASEFile::read_mesh_vertex_list(std::istream &is)
{
- Material *material = Material::find("ase_placeholder");
- if (!material) {
- material = new Material("ase_placeholder");
- Material::add(material);
- //material->set_color(math::Color(0.8, 0.8f, 0.8f));
- material->set_flags(Material::Primary);
+ size_t count = 0;
+
+ char data[1024];
+ memset(data, 0, sizeof(data));
+
+ while (is.getline(data, sizeof(data) -1 )) {
+ std::istringstream line(data);
+
+ std::string firstword;
+ line >> firstword;
+
+ if (firstword.compare("}") == 0) {
+ con_debug << count << " mesh vertices" << std::endl;
+
+ return true;
+
+ } else if ( firstword.compare("*MESH_VERTEX") == 0) {
+ size_t index;
+ float x, y, z;
+ if (line >> index >> x >> y >> z) {
+ math::Vector3f *v = new math::Vector3f(x, y, z);
+ ase_vertexlist[index] = v;
+
+ for (size_t i = 0; i < 3; i++) {
+ if ((*v)[i] > ase_maxbbox[i]) {
+ ase_maxbbox[i] = (*v)[i];
+ }
+ if ((*v)[i] < ase_minbbox[i]) {
+ ase_minbbox[i] = (*v)[i];
+ }
+ }
+ count++;
+ }
+ }
}
- Fragment *fragment = new Fragment(Fragment::Triangles, material);
-
- FragmentGroup *group = new FragmentGroup();
- group->set_type(FragmentGroup::None);
- group->push_back(fragment);
+ return false;
+}
+bool ASEFile::read_mesh_face_list(std::istream &is)
+{
size_t count = 0;
char data[1024];
@@ -92,48 +127,44 @@ bool ASEFile::read_mesh_face_list(std::istream &is)
if (word.compare("}") == 0) {
con_debug << count << " mesh faces" << std::endl;
-
- model->add_group(group);
-
return true;
} else if ( word.compare("*MESH_FACE") == 0) {
+ std::string facestr;
size_t a, b, c;
- if ( (line >> word) &&
+ if ( (line >> facestr) &&
(line >> word) && (line >> a) &&
(line >> word) && (line >> b) &&
(line >> word) && (line >> c)) {
-
- math::Vector3f n(ase_vertexlist[a]);
- n.normalize();
- fragment->add_vertex(ase_vertexlist[a], n, false);
-
- n.assign(ase_vertexlist[b]);
- n.normalize();
- fragment->add_vertex(ase_vertexlist[b], n, false);
- n.assign(ase_vertexlist[c]);
- n.normalize();
- fragment->add_vertex(ase_vertexlist[c], n, false);
+ if (facestr.size() && facestr[facestr.size()-1] == ':') {
+ facestr.erase(facestr.size()-1);
+ }
- model->model_tris_count++;
- model->model_tris_detail_count++;
+ size_t index;
+ std::istringstream faceindexstr(facestr);
+ faceindexstr >> index;
+
+ Triangle *triangle = new Triangle(*ase_vertexlist[a], *ase_vertexlist[b], *ase_vertexlist[c]);
+ ase_facelist[index] = triangle;
}
count++;
}
}
- delete group;
return false;
}
-bool ASEFile::read_mesh_vertex_list(std::istream &is)
+bool ASEFile::read_mesh_normals(std::istream &is)
{
- size_t count = 0;
-
char data[1024];
memset(data, 0, sizeof(data));
+ size_t index = 0;
+ size_t vertindex = 0;
+ float x, y, z;
+ FaceList::iterator it;
+
while (is.getline(data, sizeof(data) -1 )) {
std::istringstream line(data);
@@ -141,26 +172,33 @@ bool ASEFile::read_mesh_vertex_list(std::istream &is)
line >> firstword;
if (firstword.compare("}") == 0) {
- con_debug << count << " mesh vertices" << std::endl;
-
return true;
- } else if ( firstword.compare("*MESH_VERTEX") == 0) {
- size_t index;
- float x, y, z;
+ } else if ( firstword.compare("*MESH_FACENORMAL") == 0) {
if (line >> index >> x >> y >> z) {
- math::Vector3f v(x, y, z);
- ase_vertexlist[index] = v;
-
- for (size_t i = 0; i < 3; i++) {
- if (v[i] > ase_maxbbox[i]) {
- ase_maxbbox[i] = v[i];
- }
- if (v[i] < ase_minbbox[i]) {
- ase_minbbox[i] = v[i];
- }
+ it = ase_facelist.find(index);
+ if (it != ase_facelist.end()) {
+ (*it).second->normal().assign(x, y, z);
+ } else {
+ con_debug << " could not find face " << index << std::endl;
}
- count++;
+ vertindex = 0;
+ } else {
+ it = ase_facelist.end();
+ }
+ } else if ( firstword.compare("*MESH_VERTEXNORMAL") == 0) {
+
+ if ( (it != ase_facelist.end()) && (line >> index >> x >> y >> z)) {
+
+ if (vertindex == 0) {
+ (*it).second->n0().assign(x, y, z);
+ } else if (vertindex == 1) {
+ (*it).second->n1().assign(x, y, z);
+ } else if (vertindex == 2) {
+ (*it).second->n2().assign(x, y, z);
+ }
+
+ vertindex++;
}
}
}
@@ -187,12 +225,19 @@ bool ASEFile::read_mesh(std::istream &is)
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;
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;
+ read_mesh_normals(is);
+ }
+
} else {
do {
@@ -271,12 +316,6 @@ bool ASEFile::read()
}
}
- // TODO CENTER
- model->model_minbbox = ase_minbbox;
- model->model_maxbbox = ase_maxbbox;
-
- model->model_radius = math::max(ase_minbbox.length(), ase_maxbbox.length());
-
return true;
}
@@ -288,16 +327,55 @@ Model * ASEFile::load(const std::string &name)
return 0;
}
- asefile.model = new Model(name);
+ if (!asefile.read()) {
+ return 0;
+ }
+
+ if (!asefile.ase_facelist.size())
+ return 0;
- con_debug << " " << asefile.name() << std::endl;
+ Model *model = new Model(name);
- if (!asefile.read()) {
- delete asefile.model;
- asefile.model = 0;
+ // default material
+ Material *material = Material::find("textures/common/entity");
+ if (!material) {
+ material = new Material("placeholder");
+ Material::add(material);
+ material->set_flags(Material::Primary);
+ }
+
+ // a single fragment for all the model triangles
+ Fragment *fragment = new Fragment(Fragment::Triangles, material);
+ FragmentGroup *group = new FragmentGroup();
+ group->set_type(FragmentGroup::None);
+ group->push_back(fragment);
+
+ // calculate model center
+ math::Vector3f center((asefile.ase_minbbox + asefile.ase_maxbbox) * 0.5f);
+
+ model->model_minbbox = asefile.ase_minbbox - center;
+ model->model_maxbbox = asefile.ase_maxbbox - center;
+
+ model->model_radius = asefile.ase_minbbox.length();
+
+ // load the model faces into the fragment
+ for (FaceList::iterator it = asefile.ase_facelist.begin(); it != asefile.ase_facelist.end(); it++) {
+ Triangle *triangle = (*it).second;
+
+ fragment->add_vertex(triangle->v0() - center , triangle->n0(), false);
+ fragment->add_vertex(triangle->v1() - center , triangle->n1(), false);
+ fragment->add_vertex(triangle->v2() - center , triangle->n2(), false);
+
+ model->model_tris_count++;
+ model->model_tris_detail_count++;
}
- return asefile.model;
+ model->add_group(group);
+
+ con_debug << " " << asefile.name() << " " << asefile.ase_vertexlist.size() << " vertices " <<
+ model->model_tris_count << "/" << model->model_tris_detail_count << " faces/detail" << std::endl;
+
+ return model;
}
} // namespace model
diff --git a/src/model/asefile.h b/src/model/asefile.h
index bb731b7..7f5ab03 100644
--- a/src/model/asefile.h
+++ b/src/model/asefile.h
@@ -10,6 +10,7 @@
#include "math/vector3f.h"
#include "model/model.h"
+#include "model/triangle.h"
#include "filesystem/filestream.h"
#include <string>
@@ -31,12 +32,19 @@ public:
private:
- typedef std::map<size_t, math::Vector3f> VertexList;
+ typedef std::map<size_t, math::Vector3f *> VertexList;
+
+ typedef std::map<size_t, Triangle *> FaceList;
ASEFile(std::string const &name);
~ASEFile();
/**
+ * @brief read *MESH_NORMALS
+ */
+ bool read_mesh_normals(std::istream &is);
+
+ /**
* @brief read *MESH_FACE_LIST
*/
bool read_mesh_face_list(std::istream &is);
@@ -76,13 +84,11 @@ private:
VertexList ase_vertexlist;
+ FaceList ase_facelist;
+
math::Vector3f ase_maxbbox;
math::Vector3f ase_minbbox;
-
- math::Vector3f ase_center;
-
- Model *model;
};
} // namespace model
diff --git a/src/model/triangle.cc b/src/model/triangle.cc
index a649fdd..429c1d9 100644
--- a/src/model/triangle.cc
+++ b/src/model/triangle.cc
@@ -9,6 +9,11 @@
namespace model
{
+Triangle::Triangle()
+{
+ triangle_detail = false;
+}
+
Triangle::Triangle(
math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2,
math::Vector3f const &normal, bool detail) :
@@ -23,17 +28,10 @@ Triangle::Triangle(
triangle_detail = detail;
}
-Triangle::Triangle(math::Vector3f const &v0, math::Vector3f const &n0,
- math::Vector3f const &v1, math::Vector3f const &n1,
- math::Vector3f const &v2, math::Vector3f const &n2,
- math::Vector3f const &normal) :
+Triangle::Triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2) :
triangle_v0(v0),
- triangle_n0(n0),
triangle_v1(v1),
- triangle_n1(n1),
- triangle_v2(v2),
- triangle_n2(n2),
- triangle_normal(normal)
+ triangle_v2(v2)
{
triangle_detail = false;
}
@@ -41,4 +39,19 @@ Triangle::Triangle(math::Vector3f const &v0, math::Vector3f const &n0,
Triangle::~Triangle()
{}
+void Triangle::assign(const Triangle &other)
+{
+ triangle_v0.assign(other.triangle_v0);
+ triangle_n0.assign(other.triangle_n0);
+
+ triangle_v1.assign(other.triangle_v1);
+ triangle_n1.assign(other.triangle_n1);
+
+ triangle_v2.assign(other.triangle_v2);
+ triangle_n2.assign(other.triangle_n2);
+
+ triangle_normal.assign(other.triangle_normal);
+ triangle_detail = other.triangle_detail;
+}
+
}
diff --git a/src/model/triangle.h b/src/model/triangle.h
index 27abeed..fe1c720 100644
--- a/src/model/triangle.h
+++ b/src/model/triangle.h
@@ -17,24 +17,45 @@ namespace model
class Triangle
{
public:
- /// a new triangle with 3 vertices, a normal and detail flag
- Triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2,
- math::Vector3f const &normal, bool detail);
+ /**
+ * @brief default constructor
+ */
+ Triangle();
/**
- * @brief a new triangle with 3 vertices with normals and a face normal
+ * @brief copy constructor
+ */
+ Triangle(const Triangle &other);
+
+ /**
+ * @brief a new triangle with 3 vertices
* this constructor sets the detail flag to false
*/
- Triangle( math::Vector3f const &v0, math::Vector3f const &n0,
- math::Vector3f const &v1, math::Vector3f const &n1,
- math::Vector3f const &v2, math::Vector3f const &n2,
- math::Vector3f const &normal);
+ Triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2);
+
+ /// a new triangle with 3 vertices, a normal and detail flag
+ Triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2,
+ math::Vector3f const &normal, bool detail);
/// delete triangle
~Triangle();
+ /**
+ * @brief assignment
+ */
+ void assign(const Triangle &other);
+
+ /**
+ * @brief assignment oeprator
+ */
+ inline const Triangle & operator=(const Triangle &other)
+ {
+ assign(other);
+ return (*this);
+ }
+
/// normal of the triangle
- inline math::Vector3f const & normal() const
+ inline math::Vector3f & normal()
{
return triangle_normal;
}
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 52933b7..4392f87 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -535,6 +535,27 @@ void draw_fragment(model::Fragment *fragment, bool draw_details)
Stats::quads += vertex_count / 4;
break;
}
+
+ if (r_normals->value()) {
+ gl::begin(gl::Lines );
+
+ gl::color(1.0f, 0.0f, 0.0f);
+
+ const float s = 0.1f;
+
+ const float *n = core::game()->vertexarray()->normal() + index * 3;
+ const float *v = core::game()->vertexarray()->vertex() + index * 3;
+
+ for (size_t i = 0; i < vertex_count; i++) {
+ gl::normal(-n[i*3], -n[i*3 +1 ], -n[i*3 +2]);
+ gl::vertex(v[i*3], v[i*3 +1 ], v[i*3 +2]);
+
+ gl::normal(n[i*3], n[i*3 +1 ], n[i*3 +2]);
+ gl::vertex(v[i*3] + n[i*3] * s, v[i*3 +1] + n[i*3 +1] * s, v[i*3 +2] + n[i*3+2] * s);
+ }
+ gl::end();
+ }
+
}
void draw_model_fragments(model::Model *model,
@@ -543,6 +564,7 @@ void draw_model_fragments(model::Model *model,
{
// default material, lighted and geometry color
const model::Material *material = 0;
+ math::Color color(1.0f, 0.0f, 1.0f); // current drawing color
bool use_light = true; // gl::disable(GL_LIGHTING) is set
bool use_env = false; // environment mapping
//bool use_color_array = true; // glEnableClientState(GL_COLOR_ARRAY) is set
@@ -587,8 +609,6 @@ void draw_model_fragments(model::Model *model,
glDisableClientState(GL_COLOR_ARRAY);
}*/
- math::Color color;
-
if ((material->flags() & model::Material::Tertiary) == model::Material::Tertiary) {
for (size_t i = 0; i < 3; i++)
color[i] = (color_primary[i] + color_secondary[i]) / 2;
@@ -603,15 +623,12 @@ void draw_model_fragments(model::Model *model,
color.r *= material->color().r;
color.g *= material->color().g;
color.b *= material->color().b;
-
- gl::color(color);
-
} else {
/* if (!use_color_array) {
glEnableClientState(GL_COLOR_ARRAY);
use_color_array = true;
}*/
- gl::color(material->color());
+ color.assign(material->color());
}
if (power && (material->flags() & model::Material::Bright)) {
@@ -671,10 +688,11 @@ void draw_model_fragments(model::Model *model,
glEnableClientState(GL_COLOR_ARRAY);
use_color_array = true;
}*/
- gl::color(1.0f, 0.0f, 1.0f);
+ color.assign(1.0f, 0.0f, 1.0f);
}
}
+ gl::color(color);
draw_fragment(fragment, detail);
}
diff --git a/src/render/render.cc b/src/render/render.cc
index ce23645..e37f5f2 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -34,6 +34,7 @@ core::Cvar *r_sky = 0;
core::Cvar *r_wireframe = 0;
core::Cvar *r_mipmap = 0;
core::Cvar *r_collision = 0;
+core::Cvar *r_normals = 0;
void func_list_textures(std::string const &args)
{
@@ -68,6 +69,9 @@ void init(int width, int height)
r_wireframe = core::Cvar::get("r_wireframe", "0", core::Cvar::Archive);
r_wireframe->set_info("[bool] render wireframe");
+ r_normals = core::Cvar::get("r_normals", "0", core::Cvar::Archive);
+ r_normals->set_info("[bool] render face normals");
+
r_grid = core::Cvar::get("r_grid", "0", core::Cvar::Archive);
r_grid->set_info("[bool] render the space grid");
diff --git a/src/render/render.h b/src/render/render.h
index 54205bc..a453464 100644
--- a/src/render/render.h
+++ b/src/render/render.h
@@ -48,6 +48,8 @@ namespace render {
extern core::Cvar *r_sky;
/// render wireframe models
extern core::Cvar *r_wireframe;
+ /// render vertex normals
+ extern core::Cvar *r_normals;
/// render collision
extern core::Cvar *r_collision;
/// use hardware generated mipmaps (requires OpenGL 1.4, does not work on all cards)