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
parentb808c0e24cc4a59bd801059147bc9805944bee9a (diff)
initial .ase support
-rw-r--r--src/model/Makefile.am7
-rw-r--r--src/model/asefile.cc295
-rw-r--r--src/model/asefile.h90
-rw-r--r--src/model/map.cc9
-rw-r--r--src/model/map.h8
-rw-r--r--src/model/model.cc16
-rw-r--r--src/model/triangle.cc31
-rw-r--r--src/model/triangle.h38
8 files changed, 473 insertions, 21 deletions
diff --git a/src/model/Makefile.am b/src/model/Makefile.am
index 81512ab..94b3c96 100644
--- a/src/model/Makefile.am
+++ b/src/model/Makefile.am
@@ -1,11 +1,12 @@
METASOURCES = AUTO
-libmodel_la_SOURCES = classes.cc fragment.cc map.cc material.cc model.cc \
- plane.cc primitives.cc quad.cc triangle.cc vertexarray.cc
+libmodel_la_SOURCES = asefile.cc classes.cc fragment.cc map.cc material.cc \
+ model.cc plane.cc primitives.cc quad.cc triangle.cc vertexarray.cc
libmodel_la_LDFLAGS = -avoid-version -no-undefined -lm
noinst_LTLIBRARIES = libmodel.la
-noinst_HEADERS = classes.h fragment.h map.h material.h model.h plane.h \
+noinst_HEADERS = asefile.h classes.h fragment.h map.h material.h model.h plane.h \
primitives.h quad.h triangle.h vertexarray.h
INCLUDES = -I$(top_srcdir)/src
+
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
diff --git a/src/model/asefile.h b/src/model/asefile.h
new file mode 100644
index 0000000..bb731b7
--- /dev/null
+++ b/src/model/asefile.h
@@ -0,0 +1,90 @@
+/*
+ model/asefile.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+
+#ifndef __INCLUDED_MODEL_ASEFILE_H__
+#define __INCLUDED_MODEL_ASEFILE_H__
+
+#include "math/vector3f.h"
+#include "model/model.h"
+#include "filesystem/filestream.h"
+
+#include <string>
+#include <map>
+
+namespace model
+{
+
+/// class to parse the .ase file structure and load geometry data into a model
+class ASEFile
+{
+public:
+ /**
+ * @brief load a .ase file into a Model
+ * @param name name of the model to be loaded, without .ase extension or models/ prefix
+ * If the file can not be read, load() returns the NULL-pointer
+ */
+ static Model *load(std::string const &name);
+
+private:
+
+ typedef std::map<size_t, math::Vector3f> VertexList;
+
+ ASEFile(std::string const &name);
+ ~ASEFile();
+
+ /**
+ * @brief read *MESH_FACE_LIST
+ */
+ bool read_mesh_face_list(std::istream &is);
+
+ /**
+ * @brief read *MESH_VERTEX_LIST
+ */
+ bool read_mesh_vertex_list(std::istream &is);
+
+ /**
+ * @brief read *MESH
+ */
+ bool read_mesh(std::istream &is);
+
+ /**
+ * @brief read *GEOMOBJECT
+ */
+ bool read_geom(std::istream &is);
+
+ /**
+ * @brief read the .ase header
+ */
+ bool read_header(std::istream &is);
+
+ /**
+ * @brief read the .ase file
+ */
+ bool read();
+
+ inline const std::string &name() const { return asefile_name; }
+
+ inline const bool is_open() const { return asefile_ifs.is_open(); }
+
+ std::string asefile_name;
+
+ filesystem::IFileStream asefile_ifs;
+
+ VertexList ase_vertexlist;
+
+ math::Vector3f ase_maxbbox;
+
+ math::Vector3f ase_minbbox;
+
+ math::Vector3f ase_center;
+
+ Model *model;
+};
+
+} // namespace model
+
+#endif // __INCLUDED_MODEL_ASEFILE_H__
diff --git a/src/model/map.cc b/src/model/map.cc
index c2b184f..8165e3a 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -1,5 +1,5 @@
/*
- filesystem/map.cc
+ model/map.cc
This file is part of the Osirion project and is distributed under
the terms of the GNU General Public License version 2
*/
@@ -15,6 +15,7 @@
#include <sstream>
#include <string>
+#include <cstring>
namespace model
{
@@ -71,7 +72,6 @@ bool Map::open(std::string const & mapname)
mapfile_ifs.open(mapfile_name);
if (!mapfile_ifs.is_open()) {
- con_warn << "Could not open " << mapfile_name << "!\n";
return false;
}
return true;
@@ -97,8 +97,6 @@ bool Map::getline()
{
using math::Vector3f;
- char data[1024];
-
last_read_was_classname = false;
last_read_was_key = false;
last_read_was_classend = false;
@@ -108,6 +106,9 @@ bool Map::getline()
if (!mapfile_ifs.is_open())
return false;
+
+ char data[1024];
+ memset(data, 0, sizeof(data));
if (mapfile_ifs.getline(data, 1023)) {
line_number++;
diff --git a/src/model/map.h b/src/model/map.h
index d7b01d7..8dc688e 100644
--- a/src/model/map.h
+++ b/src/model/map.h
@@ -24,8 +24,10 @@ class Map
{
public:
- /// load a .map file into a Model
- /** @param name name of the model to be loaded, without .map extension or maps/ prefix
+ /**
+ * @brief load a .map file into a Model
+ * @param name name of the model to be loaded, without .map extension or maps/ prefix
+ * If the file can not be read, load() returns the NULL-pointer
*/
static Model *load(std::string const &name);
@@ -114,7 +116,7 @@ private:
return line_number;
}
- /// return true of the ini file is open for reading
+ /// return true of the map file is open for reading
inline bool is_open()
{
return mapfile_ifs.is_open();
diff --git a/src/model/model.cc b/src/model/model.cc
index 3ec75d7..3ed5a93 100644
--- a/src/model/model.cc
+++ b/src/model/model.cc
@@ -5,6 +5,7 @@
*/
#include "sys/sys.h"
+#include "model/asefile.h"
#include "model/model.h"
#include "model/map.h"
#include "model/vertexarray.h"
@@ -101,10 +102,19 @@ Model *Model::load(std::string const & name)
{
Model *model = find(name);
if (!model) {
+ // try loading the .map model
model = Map::load(name);
- if (model) {
- model_registry[model->name()] = model;
- }
+ }
+
+ if (!model) {
+ // if it can't be found, try the ase model
+ model = ASEFile::load(name);
+ }
+
+ if (!model) {
+ con_warn << "Could not load maps/" << name << ".map or models/" << name << ".ase" << std::endl;
+ } else {
+ model_registry[model->name()] = model;
}
return model;
diff --git a/src/model/triangle.cc b/src/model/triangle.cc
index 162b68a..a649fdd 100644
--- a/src/model/triangle.cc
+++ b/src/model/triangle.cc
@@ -9,16 +9,35 @@
namespace model
{
-Triangle::Triangle(math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2,
- math::Vector3f const &normal, bool detail) :
- triangle_v0(v0),
- triangle_v1(v1),
- triangle_v2(v2),
- triangle_normal(normal)
+Triangle::Triangle(
+ math::Vector3f const &v0, math::Vector3f const &v1, math::Vector3f const &v2,
+ math::Vector3f const &normal, bool detail) :
+ triangle_v0(v0),
+ triangle_n0(normal),
+ triangle_v1(v1),
+ triangle_n1(normal),
+ triangle_v2(v2),
+ triangle_n2(normal),
+ triangle_normal(normal)
{
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_v0(v0),
+ triangle_n0(n0),
+ triangle_v1(v1),
+ triangle_n1(n1),
+ triangle_v2(v2),
+ triangle_n2(n2),
+ triangle_normal(normal)
+{
+ triangle_detail = false;
+}
+
Triangle::~Triangle()
{}
diff --git a/src/model/triangle.h b/src/model/triangle.h
index 416a3e6..27abeed 100644
--- a/src/model/triangle.h
+++ b/src/model/triangle.h
@@ -17,9 +17,19 @@ namespace model
class Triangle
{
public:
- /// a new triangle with 3 vertices, a normal, color and a detail flag
+ /// 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 a new triangle with 3 vertices with normals and a face normal
+ * 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);
+
/// delete triangle
~Triangle();
@@ -41,23 +51,47 @@ public:
return triangle_v0;
}
+ /// triangle vertex 0 normal
+ inline math::Vector3f & n0()
+ {
+ return triangle_n0;
+ }
+
/// triangle vertex 1
inline math::Vector3f & v1()
{
return triangle_v1;
}
+
+ /// triangle vertex 1 normal
+ inline math::Vector3f & n1()
+ {
+ return triangle_n1;
+ }
/// triangle vertex 2
inline math::Vector3f & v2()
{
return triangle_v2;
}
+
+ /// triangle vertex 0 normal
+ inline math::Vector3f & n2()
+ {
+ return triangle_n2;
+ }
+
private:
math::Vector3f triangle_v0;
+ math::Vector3f triangle_n0;
+
math::Vector3f triangle_v1;
+ math::Vector3f triangle_n1;
+
math::Vector3f triangle_v2;
-
+ math::Vector3f triangle_n2;
+
math::Vector3f triangle_normal;
bool triangle_detail;
};