From bbd04914749b2e3918796fe331daf649b06163ea Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 9 Aug 2009 21:11:55 +0000 Subject: adds r_normals cvar, read normals from .ase models --- src/model/asefile.cc | 200 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 139 insertions(+), 61 deletions(-) (limited to 'src/model/asefile.cc') 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 -- cgit v1.2.3