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 16:34:38 +0000
committerStijn Buys <ingar@osirion.org>2009-08-09 16:34:38 +0000
commit324f5431245f2a550acddea70ea72770430a19d1 (patch)
treeaa05d127c20f5bb5995a3fdceb915b5280887e4b /src/model/asefile.cc
parentb808c0e24cc4a59bd801059147bc9805944bee9a (diff)
initial .ase support
Diffstat (limited to 'src/model/asefile.cc')
-rw-r--r--src/model/asefile.cc295
1 files changed, 295 insertions, 0 deletions
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 <sstream>
+#include <cstring>
+
+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