From 324f5431245f2a550acddea70ea72770430a19d1 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 9 Aug 2009 16:34:38 +0000 Subject: initial .ase support --- src/model/asefile.cc | 295 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 src/model/asefile.cc (limited to 'src/model/asefile.cc') diff --git a/src/model/asefile.cc b/src/model/asefile.cc new file mode 100644 index 0000000..182c58c --- /dev/null +++ b/src/model/asefile.cc @@ -0,0 +1,295 @@ +/* + model/asefile.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "sys/sys.h" +#include "model/asefile.h" + +#include +#include + +namespace model +{ + +// max geometry bounds +const float MAX_BOUNDS = 16384.0f; + +ASEFile::ASEFile(std::string const &name) +{ + asefile_name.assign("models/"); + asefile_name.append(name); + asefile_name.append(".ase"); + + asefile_ifs.open(asefile_name); + + for (int i=0; i < 3; i++) { + ase_minbbox[i] = MAX_BOUNDS; + ase_maxbbox[i] = -MAX_BOUNDS; + } + +} + +ASEFile::~ASEFile() +{ + ase_vertexlist.clear(); + + if (asefile_ifs.is_open()) + asefile_ifs.close(); +} + +bool ASEFile::read_header(std::istream &is) +{ + if (!is.good()) { + return false; + } + + char data[1024]; + memset(data, 0, sizeof(data)); + + if (!is.getline(data, sizeof(data) -1 )) { + return false; + } + + std::istringstream line(data); + std::string word; + line >> word; + + if (!word.compare("*3DSMAX_ASCIIEXPORT") == 0) { + return false; + } + + return true; +} + +bool ASEFile::read_mesh_face_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); + } + + Fragment *fragment = new Fragment(Fragment::Triangles, material); + + FragmentGroup *group = new FragmentGroup(); + group->set_type(FragmentGroup::None); + group->push_back(fragment); + + 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 word; + line >> word; + + if (word.compare("}") == 0) { + con_debug << count << " mesh faces" << std::endl; + + model->add_group(group); + + return true; + + } else if ( word.compare("*MESH_FACE") == 0) { + size_t a, b, c; + if ( (line >> word) && + (line >> word) && (line >> a) && + (line >> word) && (line >> b) && + (line >> word) && (line >> c)) { + + fragment->add_vertex(ase_vertexlist[a], ase_vertexlist[a], false); + fragment->add_vertex(ase_vertexlist[b], ase_vertexlist[b], false); + fragment->add_vertex(ase_vertexlist[c], ase_vertexlist[c], false); + + model->model_tris_count++; + model->model_tris_detail_count++; + } + count++; + } + } + + delete group; + return false; +} + +bool ASEFile::read_mesh_vertex_list(std::istream &is) +{ + 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(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++; + } + } + } + + return false; +} + +bool ASEFile::read_mesh(std::istream &is) +{ + char data[1024]; + memset(data, 0, sizeof(data)); + int level = 1; + + ase_vertexlist.clear(); + + while (is.getline(data, sizeof(data) -1 )) { + std::istringstream line(data); + + std::string word; + line >> word; + + if ((level == 1 ) && (word.compare("*MESH_VERTEX_LIST") == 0)) { + if ((line >> word) && (word.compare("{") == 0)) { + 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 { + + do { + if (word.compare("{") == 0) { + level++; + } else if (word.compare("}") == 0) { + level--; + } + } while (line >> word); + } + + if (level == 0) + return true; + } + + return false; +} + +bool ASEFile::read_geom(std::istream &is) +{ + char data[1024]; + memset(data, 0, sizeof(data)); + int level = 1; + + while (is.getline(data, sizeof(data) -1 )) { + + std::istringstream line(data); + std::string word; + line >> word; + + if ((level == 1 ) && (word.compare("*MESH") == 0)) { + if ((line >> word) && (word.compare("{") == 0)) { + con_debug << " " << name() << " " << "*MESH" << std::endl; + read_mesh(is); + } + + } else { + do { + if (word.compare("{") == 0) { + level++; + } else if (word.compare("}") == 0) { + level--; + } + } while (line >> word); + } + + if (level == 0) + return true; + } + + return false; +} + +bool ASEFile::read() +{ + if (!read_header(asefile_ifs)) { + con_warn << name() << ": not a valid ASE file!\n"; + return 0; + } + + char data[1024]; + memset(data, 0, sizeof(data)); + + while (asefile_ifs.getline(data, sizeof(data) -1 )) { + std::istringstream line(data); + + std::string word; + line >> word; + + if (word.compare("*GEOMOBJECT") == 0) { + + if ((line >> word) && (word.compare("{") == 0)) { + con_debug << " " << name() << " " << "*GEOMOBJECT" << std::endl; + read_geom(asefile_ifs); + } + } + } + + // 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; +} + +Model * ASEFile::load(const std::string &name) +{ + ASEFile asefile(name); + + if (!asefile.is_open()) { + return 0; + } + + asefile.model = new Model(name); + + con_debug << " " << asefile.name() << std::endl; + + if (!asefile.read()) { + delete asefile.model; + asefile.model = 0; + } + + return asefile.model; +} + +} // namespace model -- cgit v1.2.3