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-09 21:11:55 +0000
committerStijn Buys <ingar@osirion.org>2009-08-09 21:11:55 +0000
commitbbd04914749b2e3918796fe331daf649b06163ea (patch)
tree0139a4024950ecc5533fd7018ee35942d2ba2680 /src/model/asefile.cc
parent4f576711828f35179dc5d28cfda93eff47e80a74 (diff)
adds r_normals cvar, read normals from .ase models
Diffstat (limited to 'src/model/asefile.cc')
-rw-r--r--src/model/asefile.cc200
1 files changed, 139 insertions, 61 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