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.cc200
-rw-r--r--src/model/asefile.h16
-rw-r--r--src/model/triangle.cc31
-rw-r--r--src/model/triangle.h39
4 files changed, 202 insertions, 84 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;
}